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
/
ENTERPRS
/
CPM
/
UTILS
/
S
/
VDE267SC.LBR
/
VDX3.AZM
/
VDX3.ASM
Wrap
Assembly Source File
|
2000-06-30
|
45KB
|
2,455 lines
;*** VDE.ASM (c)1988 E.Meyer
;*** Module 3: disk, display code
;
;
;DISK I/O
;
IOon: LD DE,DspEsQ ;show Wait....
CALL GoTo
CALL MakAlt
LD HL,IOmsg
LD B,7
CALL BHLMsg
CALL UnAlt
IF VDM
CALL SCursr
ENDIF
RET
IOoff: LD A,(NoHdrF) ;headerless? redo top line
OR A
JP NZ,ShoLn1
LD DE,DspEsQ ;header: blank prompt
CALL GoTo
CALL MakAlt
LD B,7+1 ;(cursor)
CALL BBlank
JP UnAlt
;
;Enter BDOS, but latch onto warm start for
;recovery purposes. (CP/M 2 ONLY)
;
BDOS: CALL CPM3
JP NC,BDOSep ;Plus: just do it
PUSH DE
LD HL,(0001H)
INC HL ;trap warm boot vector in BIOS JP table
LD E,(HL)
INC HL
LD D,(HL)
LD (BIOSws+1),DE
LD DE,BIOSws
LD (HL),D
DEC HL
LD (HL),E
POP DE
CALL BDOSep ;DO IT
PUSH HL
LD DE,(BIOSws+1) ;Restore real warm boot
LD HL,(0001H)
INC HL
LD (HL),E
INC HL
LD (HL),D
POP HL
RET
BIOSws: LD DE,0 ;<--- Warm boot vector
LD HL,(0001H)
INC HL
LD (HL),E ;restore it
INC HL
LD (HL),D
LD SP,Stack ;reset stack
CALL RDlog ;and disks
CALL Error3 ;Give I/O message
JP Sk1Ed ;Continue editing
;
CPM3: LD A,0 ;<---- Version
CP 30H ;(Carry set if 2.2)
RET
;
RstDrv: OR A ;CP/M 2 drive reset (A=1 etc)
JR Z,RDlog
LD HL,FixDsk
RES 6,(HL) ;(have to adjust from ASCII)
CP (HL) ;one of 2 fixed drives? ignore
RET Z
INC HL
RES 6,(HL)
CP (HL)
RET Z
PUSH AF
LD C,GDRV
CALL BDOSep
POP BC
INC A
CP B ;is it logged drive?
JR Z,RDlog
LD HL,1 ;if NOT, can be selective
RDlp: DEC B
JR Z,RDok
ADD HL,HL
JR RDlp
RDok: EX DE,HL
LD C,RSTV ;reset single drive
JR RDxit
RDlog: LD C,RSTD ;sigh, whole system
RDxit: JP BDOSep
;
;
Parse: PUSH AF ;parse FCB w/Duu: and [A/W (NO WILDCARDS)
LD A,(DFMode)
LD (FMode),A
PUSH HL ;Entry: HL=string, A=length
CALL BlkFCB ;Exit: set FCB, FCBU, FMode
POP HL ;...now checks filetypes too
LD D,H
LD E,L
POP AF
OR A
JR Z,PNODRV
LD C,A
LD B,0 ;chars there
LD A,':'
CPIR ;find drivespec?
JR NZ,PNODRV
DEC HL
DEC HL ;yep...User number?
LD A,(HL)
CP '0'
JR C,PDRV
CP '9'+1
JR NC,PDRV
;
PUSR: SUB '0'
LD E,A ;Got user... figure units
DEC HL
LD A,(HL)
CP '0'
JR C,ZPAR1 ;thats all?
CP '9'+1
JR NC,ZPAR1
SUB '0'
LD D,A ;nope, tens too
ADD A
ADD A
ADD A ;*8
ADD D
ADD D
ADD E ;*(8+2)+units = user
LD E,A
DEC HL
CP 32
JR NC,ZPBAD ;illegal?
ZPAR1: LD A,E
LD (FCBU),A ;set user
LD C,USRN
PUSH HL
CALL BDOSep
POP HL
;
PDRV: BIT 7,L ;now, parse FCB (start with drive)
JR Z,ZPAR2A ;(Kludge: stay above 0080h)
LD A,(HL)
CP ' ' ;oops, was it there?
JR Z,ZPAR2A
ZPAR2: SUB 'A'
JR C,ZPBAD ;make sure it's legal
LD E,A
LD A,16
CP E
JR C,ZPBAD
LD A,E
INC A
LD (FCB),A
ZPAR2A: LD BC,4
LD A,':'
CPIR ;skip over user, to filename
JR PNAME
PNODRV: LD A,' ' ;no du: at all
EX DE,HL
DEC HL ;find filename
PNDL: INC HL
CP (HL)
JR Z,PNDL ;(first nonblank)
;
PNAME: LD B,8
LD DE,FCB+1 ;do filename at (HL)
ZPRL1: XOR A
ADD (HL)
INC HL
JR Z,ZPARX
CP '.'
JR Z,ZPRL1X
CP ' '
JR Z,ZPRL2F
JR C,ZPBADC
CP '['
JR Z,POPT
CALL ZPBADC
JR Z,ZPBAD
LD (DE),A
INC DE
DJNZ ZPRL1
JR ZPRL1F
ZPRL1X: LD A,' ' ;fill with " "
CALL Fill
JR PTYP
ZPBAD: CALL BlkFCB ;bad entry
SCF
RET
ZPRL1F: XOR A
ADD (HL)
JR Z,ZPARX
CP '.'
JR NZ,ZPRL2F ;no "."? leave type blank
INC HL
;
PTYP: LD B,3 ;file type at (HL)
ZPRL2: XOR A
ADD (HL)
INC HL
JR Z,ZPARX
CP ' '
JR Z,ZPRL2F
JR C,ZPBADC
CP '['
JR Z,POPT
CALL ZPBADC
JR Z,ZPBAD
LD (DE),A
INC DE
DJNZ ZPRL2
ZPRL2F: LD A,(HL) ;(eat spaces)
CP ' '
JR NZ,POPT
INC HL
JR ZPRL2F
;
POPT: LD A,(HL) ;process W/A option
CP '['
JR NZ,POPT1
INC HL
LD A,(HL) ;process W/A option
POPT1: OR A
JR Z,ZPARX
CALL VerOpt ;verify legality
JR NZ,ZPBAD
LD (FMode),A
JR ZPARX2 ;any specification overrides defaults
;
ZPARX: LD HL,FCB+9 ;check filetype mode defaults
LD DE,FDflt1
PUSH HL
CALL TypDfl
POP HL
LD DE,FDflt2
CALL TypDfl
ZPARX2: LD A,(FCB+1)
CP ' '
JR Z,ZPBAD
OR A ;DONE.
RET
;
ZPBADC: PUSH HL ;check bad chars
PUSH BC
LD HL,ZPBLST
LD BC,ZPBLEN
CPIR ;Z set if bad
POP BC
POP HL
RET
ZPBLST: DB ' .,;:?*=[' ;illegal chars
ZPBLEN EQU $-ZPBLST
;
TypDfl: LD B,3 ;Set mode from filetype if (HL),(DE) MATCH
TypDLp: LD A,(DE)
CP '?'
JR Z,TypD2
CP (HL)
RET NZ ;no match, quit
TypD2: INC DE
INC HL
DJNZ TypDLp
LD A,(DE) ;match, here's your mode
CALL VerOpt
RET NZ
LD (FMode),A
RET
;
VerOpt: CP 'A' ;verify mode option legal
RET Z
CP 'N'
RET Z
CP 'W'
RET
;
;
;Read in the file. (HL=prev byte, BC=max size)
;Return with HL=last byte, Z=out of room, C=input error.
;
MSIn: XOR A
LD (FCB+12),A ;Initialize FCB
LD (FCB+32),A
LD (MSIFlg),A
CPL
LD (SftFlg),A
PUSH HL
PUSH BC
LD DE,FCB
LD C,FOPN
CALL BDOS
INC A ;Not found?
JR NZ,MSIfnd
MSIerr: POP BC ;Error...
POP BC
OR 1 ;Clear Z
SCF ;Set C
RET
MSIfnd: LD DE,DMA
LD C,SDMA
CALL BDOS
;
MSIlp1: LD DE,FCB
LD C,RSEQ
CALL BDOS
CP 1 ;No more records?
JP Z,MSIefX
JR NC,MSIerr ;Other error?
LD IX,DMA
POP DE ;target count
LD B,128 ;1 record
POP HL ;target address
MSIlp2: LD A,(FMode)
CP 'W'
JR NZ,MSIlp3
LD A,(IX) ;Wordstar: handle soft hyphens
CP 1Fh
JR NZ,MSIl2x
LD A,'-'
LD (IX),A
MSIl2x: CP 1Eh ;remove dead soft hyphens
JR Z,MSIlf
CP 0A0H ;remove soft spaces
JR NZ,MSIl2a
LD A,(SftFlg)
OR A ;(unless at beginning of line)
JR Z,MSIlf
JR MSIlp3
MSIl2a: XOR A
LD (SftFlg),A
LD A,(IX) ;and keep hard/soft CRs straight
CP 8DH
JR NZ,MSIl2b
LD A,(HL) ;SCR must have space before...
CP ' '
JR Z,MSIlp3
SET 7,(HL)
JR NC,MSIlp3
RES 7,(HL) ;can't set hi bit on ctlcodes
LD A,' '
INC HL ;Bump output
LD (HL),A ;Insert byte
DEC DE ;Room left?
LD A,D
OR E
RET Z
JR MSIlp3
MSIl2b: CP CR
JR NZ,MSIlp3
MSIl2c: RES 7,(HL) ;...and HCR must not have space
LD A,(HL)
CP ' '
JR NZ,MSIlp3
DEC HL
INC DE
JR MSIl2c
MSIlp3: LD A,(IX) ;take the byte
AND 7Fh ;Mask parity
CP EOF ;EOF?
JR Z,MSIeof
CP LF ;toss line feeds
JR NZ,MSIl3a
LD (SftFlg),A ;but record them
JR MSIlf
MSIl3a: PUSH HL
LD HL,BlkChr
CP (HL) ;toss block chars
POP HL
JR Z,MSIlf
CP ' ' ;take non-spaces
JR NZ,MSIok
LD A,(HL)
CP 20H ;Last one CTL? take space
JR C,MSIsp
BIT 7,(HL) ;Already hidden space? take space
JR NZ,MSIsp
SET 7,(HL) ;Hide space
JR Z,MSIlf
;
MSIsp: LD A,' '
MSIok: INC HL ;Bump output
LD (HL),A ;Insert byte
DEC DE ;Room left?
LD A,D
OR E
RET Z
MSIlf: INC IX ;Bump input
DEC B ;Go through record
JP NZ,MSIlp2
PUSH HL
PUSH DE
JP MSIlp1 ;Get next block
;
MSIefX: POP DE ;(for last rec bug fix)
POP HL
MSIeof: OR 1 ;clear Z/C
LD (MSIFlg),A ;Show load OK
RET
;
;
;Write out BC characters at HL to file FCB (C=error)
;
MSOut: PUSH BC
PUSH HL
ADD HL,BC ;ending address
PUSH HL
CALL CPM3
LD A,(FCB)
CALL C,RstDrv ;reset drive
LD HL,FCB+1 ;strip attributes
LD B,11
MSOlp1: RES 7,(HL)
INC HL
DJNZ MSOlp1
LD A,(FilFlg)
OR A ;Save old file?
JR Z,MSOdel
LD HL,FCB ;Make a copy of FCB
LD DE,DMA
LD BC,16 ;FCB length
LDIR ;Copy it
LD BC,8+1
LD HL,FCB
LDIR ;again
LD BC,3
LD HL,Bak
LDIR
LD DE,DMA+16 ;delete BAKfil
LD C,FDEL
CALL BDOS
LD DE,DMA ;rename old file to BAK
LD C,FREN
CALL BDOS
;XOR A ;reset FilFlg
;LD (FilFlg),A
JR MSOmak
;
MSOdel: LD DE,FCB ;delete old file?
LD C,FDEL
CALL BDOS
;
MSOmak: XOR A ;Initialize FCB
LD (SftFlg),A
LD (FCB+12),A
LD (FCB+32),A
LD DE,FCB
LD C,FMAK
CALL BDOS
POP DE ;end
POP HL ;start
POP BC ;(bytes)
INC A
JP Z,MSOerr
LD A,B
OR C ;any bytes?
JP Z,MSOcls
LD C,0 ;Initialize GetNx
LD B,128 ;1 record
LD IX,DMA
MSOlp2: CALL GetNx
PUSH BC
PUSH HL
LD HL,BadTbl ;skip illegal chars
LD BC,BadLen
CPIR
POP HL
POP BC
JR Z,MSOsk1
MSOlp3: LD (IX),A ;put it out
LD A,(FMode)
CP 'W' ;Wordstar mode?
JR NZ,MSOWSx
LD A,(IX)
CP ' '
JR NZ,MSOWSa
LD A,(IX-1) ;add microjustification bits
CP 21h
JR C,MSOWS2
SET 7,(IX-1)
JR MSOWS2
MSOWSa: CP CR
JR Z,MSOWS1
CP LF
JR Z,MSOWSx
MSOWS0: XOR A
LD (SftFlg),A
JR MSOWSx
MSOWS1: LD A,(IX-1) ;soften CRs after spaces
AND 7FH
CP ' '
JR NZ,MSOWS0
;SET 7,(IX-1) ;now why would you want to do that?
MSOW1a: SET 7,(IX)
LD A,0FFH
LD (SftFlg),A
JR MSOWSx
MSOWS2: LD A,(SftFlg) ;and spaces after soft CRs
OR A
JR NZ,MSOW1a
MSOWSx: LD A,(IX)
INC IX ;bump pointer
DJNZ MSOsk1 ;Skip if buffer not full
PUSH BC
PUSH DE
PUSH HL
LD DE,FCB
LD C,WSEQ
CALL BDOS
POP HL
POP DE
POP BC
OR A
JR NZ,MSOerr ;check for output error
LD B,128
LD IX,DMA
LD A,(DMA+127)
LD (IX-1),A
MSOsk1: AND 7FH
CP CR ;Add LF after CR
LD A,LF
JR Z,MSOlp3
LD A,H
XOR D ;At end yet?
JP NZ,MSOlp2
LD A,L
XOR E
JP NZ,MSOlp2
OR C ;Still got hidden space?
JP NZ,MSOlp2
OR B ;need EOF?
JR Z,MSOsk2
MSOefL: LD (IX),EOF ;yes
INC IX
DJNZ MSOefL
MSOsk2: LD DE,FCB
LD C,WSEQ
CALL BDOS
OR A
JR NZ,MSOerr
MSOcls: LD DE,FCB ;all done, close up
LD C,FCLO
CALL BDOS
INC A
OR A ;bug fix 2.67
RET NZ
MSOerr: SCF
RET
;
;
;
; DISPLAY FUNCTIONS
;
;(Re)initialize screen to begin editing
;
DoHdr: LD A,(NoHdrF)
OR A
RET NZ
LD DE,0
CALL GoTo
LD HL,Header
CALL AltDsp
CALL ShoFnm ;Show file name
LD HL,OPoff
LD A,(FMode)
CP 'N'
JR NZ,DoHdr1 ;show "Pg " if document
LD A,(PgLen)
OR A
JR NZ,DoHdrT
LD HL,OPon ;show "OP" if ^OP in nondoc
DoHdr1: LD DE,DspOP
CALL TogSho
DoHdrT: CALL ITshow ;show toggles
CALL VTshow
CALL HYshow
CALL AIshow
CALL DSshow
JP MRshow
;
TogSho: LD A,(NoHdrF)
OR A
RET NZ
PUSH HL ;toggle show subroutine
CALL GoTo
CALL MakAlt
POP HL
LD B,3
CALL BHLMsg
JP UnAlt
;
;
UpLft: LD DE,0100H ;go to "top of text"
LD A,(RulFlg)
OR A
JR Z,UndrX
INC D
JR UndrX
UndrHd: LD DE,0100H ;go below header regardless
UndrX: JP GoTo
;
;
NoHdr: LD HL,NoHdrF ;toggles on/off
CALL ToggHL
OR A
JR Z,HdrOn
HdrOff: CALL AdjLns ;that's one more line
CALL IncVO
JP SetAl
HdrOn: CALL AdjLns
CALL DecVO
CALL DoHdr ;let's see it again
JP SetAl
;
;
;Show current file data in the heading
;
ShoFnm: CALL MakAlt
LD DE,DspFnm+8 ;blank out old stuff
CALL GoTo
LD B,12
CALL BBlank
LD DE,DspFnm
CALL GoTo
LD A,(FCB)
ADD 'A'-1 ;drive letter
CALL PutChA
LD A,(FCBU) ;user number 0-15
CP 10
JR C,ShoFn1
PUSH AF
LD A,'1'
CALL PutChA
POP AF
SUB 10
ShoFn1: ADD '0'
CALL PutChA
LD A,':'
CALL PutChA ;punctuate
LD HL,FCB+1
LD B,8 ;Name
ShFnLp: LD A,(HL)
CP ' ' ;Quit on blank
JR Z,ShFnLF
CALL PutChA
INC HL
DJNZ ShFnLp ;Loop for 8
ShFnLF: LD A,'.' ;punctuate
CALL PutChA
LD HL,FCB+9
LD B,3 ;Type
ShFnL2: LD A,(HL)
CALL PutChA
INC HL
DJNZ ShFnL2
LD B,2
CALL BBlank
LD A,'[' ;option
CALL PutChA
LD A,(FMode)
CALL PutChA
JP UnAlt
;
;
Ruler: LD HL,RulFlg ;toggle ruler on/off
CALL ToggHL
OR A
JP Z,RulOff
;
RulOn: CALL AdjLns ;readjust screen length
CALL DecVO
CALL Z,SetAl ;maybe on line 1?
JR RuShow
;
RulFix: LD A,(RulFlg) ;update ruler if on
OR A
RET Z
RuShow: LD IY,RulBuf ;build ruler here
LD A,(NSkip) ;starting column
INC A
LD C,A
LD A,(View) ;length
;DEC A ;less one for safety
LD B,A
RuLp: LD E,'-' ;default char is "-"
LD A,(VTFlg) ;which tab mode?
OR A
JR Z,RuLpH
PUSH BC ;"T" if varitab stop
LD A,C
LD HL,VTList
LD BC,VTNum
CPIR
POP BC
JR Z,RuVtab
JR RuNtab
RuLpH: LD HL,TabCnt ;"I" if hardtab stop
LD A,C
DEC A
AND (HL)
JR Z,RuHtab
RuNtab: LD A,(RtMarg) ;"]" if right margin
CP C
JR Z,RuRM
JR C,RuDot ;or dot if outside
LD A,(LfMarg)
CP C
JR Z,RuLM ;or "[" if left margin
DEC A
CP C
JR NC,RuDot
RuLpF: LD (IY),E ;okay, show it
INC IY
INC C
DJNZ RuLp
;LD (IY),CR ;all done
;INC IY ;--NOT needed
LD (IY),0
CALL UndrHd
LD HL,RulBuf
JP AltDsp
RuLM: LD E,'['
JR RuLpF
RuRM: LD E,']'
JR RuLpF
RuDot: LD E,'.'
JR RuLpF
RuVtab: LD E,'T'
JR RuLpF
RuHtab: LD E,'I'
JR RuLpF
;
RulOff: CALL AdjLns ;adjust screen size
CALL IncVO
LD E,A
CALL CrLft ;oops, may be near top
XOR A
ADD E
JP Z,ShoLn1
JP SetAl
;
;Show the menu
;
DoMnu: LD A,(Help) ;menus enabled?
OR A
JR NZ,HelpY
LD HL,HlpMsg ;no, it's just a one-line msg now
CALL MsgDsp
CALL EscLp
JP ShoLn1
HelpY: LD A,(TxtLns)
CP 7
JP C,Error7 ;menu takes 7 lines
LD HL,Menu
CALL MsgDsp
CALL IfSpLn
DoMnuI: CALL RptKey ;request submenu?
CALL XCase
CP ' '
JR Z,DoMnuX
LD HL,KMenu
CP 'K'-40h
JR Z,DoMnu2
CP ESC
JR Z,DoMnu2
LD HL,OMenu
CP 'O'-40h
JR Z,DoMnu2
LD HL,QMenu
CP 'Q'-40h
JR NZ,DoMnuI
DoMnu2: CALL MsgDsp
CALL ESCLp ;wait for ESC
DoMnuX: JP SetAl
;
;
;Display one byte on the screen for messages rather than text.
;Hi bit set = following space.
;
DsByt: CP CR ;Is it a CR
JR Z,Sk1DB ;Yes, skip
CP X ;compressed space?
JR NC,Sk3DB
DsBy1: LD E,A ;normal character
IF VDM
CALL HPos ;room?
CP 2
JP NC,PutCh
ELSE
LD HL,HPos ;room?
DEC (HL)
JP NZ,PutCh ;put it out
INC (HL) ;EOL
ENDIF
RET
Sk1DB:
IF VDM
CALL HPos
ELSE
LD A,(HPos) ;Fill out spaces for CR
ENDIF
LD E,A ;(needed for attributes, etc)
CALL SpEOL
IF VDM
LD HL,(SPos) ;reset to next line
LD DE,(Empty)
ADD HL,DE
LD (SPos),HL
RET
ELSE
LD A,(AuWrap) ;does autowrap occur?
OR A
JR NZ,Sk1aDB
LD E,CR ;NO, put out a CRLF
CALL PutCh
LD E,LF
CALL PutCh
Sk1aDB: LD A,(View)
INC A
LD (HPos),A ;new line
RET
ENDIF
Sk3DB: AND 7FH ;compressed space
CALL DsByt
LD A,' '
JR DsByt
;
IF VDM
HPos: PUSH HL ;Calculate room left on line
PUSH DE
PUSH BC
LD HL,(SPos)
CALL UXlate ;E=col 0...View-1
LD A,(View)
INC A
SUB E
POP BC
POP DE
POP HL ;return A=room
RET
ENDIF
;
;
;Display message pointed to by HL. 00h is end.
;80H,nn = skip count.
;
Dspla:
IF VDM
PUSH HL
LD HL,(SPos) ;initialize to column 0
CALL UXlate
LD E,0
CALL Xlate
LD (SPos),HL
POP HL
ELSE
LD A,(View) ;initialize
INC A
LD (HPos),A
ENDIF
DspLp: ;or continue, here
IF VDM
CALL HPos
ELSE
LD A,(HPos)
ENDIF
LD E,A
LD A,(HL) ;get byte
INC HL
OR A ;All done?
RET Z
CP X ;hidden spaces?
JR NZ,Dsp10
LD A,(HL) ;get space count
INC HL
LD B,A
Dsp01: LD A,' '
PUSH BC
PUSH HL
CALL DsBy1
POP HL
POP BC
DJNZ Dsp01
JR DspLp
Dsp10: PUSH HL
CALL DsByt ;Put it out
POP HL
JR DspLp ;Do next one
;
;Display message which immediatly follows the CALL
;
Dspl: POP HL
CALL Dspla
JP (HL)
DsplC: POP HL ;same, but continued
CALL DspLp
JP (HL)
;
;
;Make a text "window" at screen bottom
;
Window: LD A,(PhysLn) ;requires 16 lines or more
CP 16
JP C,Error7
LD HL,WinFlg ;toggles on/off
CALL ToggHL
OR A
JR Z,WinOff
;
WinOn: CALL AdjLns ;adjust counts
LD A,(PhysLn)
AND 1
CALL NZ,ClLast ;clear odd line?
CALL TopV ;put chosen text on top
LD A,0FFh
LD (BelowF),A ;go below
CALL ShoSc ;show text
LD A,(NoHdrF)
OR A
JR NZ,WinOn2
LD DE,0000h ;separator needed?
CALL GoTo
CALL SepLin
CALL ShoFnm ;with name
WinOn2: XOR A
LD (BelowF),A
JP SetAl
;
WinOff: CALL AdjLns
JP SetAl
;
;
AdjLns: LD A,(PhysLn) ;KEEP screen counts consistent
LD HL,WinFlg
BIT 0,(HL)
JR Z,AdjL1
SRL A
AdjL1: LD (Lines),A ;physical window size
LD HL,NoHdrF
BIT 0,(HL)
JR NZ,AdjL2
DEC A ;adjust for header if present
AdjL2: LD HL,RulFlg
ADD (HL) ;adjust for ruler if present
LD (TxtLns),A
RET
;
;
; SCREEN I/O ROUTINES
;
;Do screen control code strings (return Carry if none)
;
CtlStr: XOR A
ADD (HL) ;HL points to #,bytes (# may be 0)
SCF
RET Z
LD B,A
INC HL ;set up count
IF NOT VDM
BHLMsg:
ENDIF
CtlSLp: LD E,(HL)
INC HL
PUSH BC
PUSH HL
CALL CONOut ;do NOT filter
POP HL
POP BC
DJNZ CtlSLp
OR A
RET
IF VDM
BHLMsg: LD E,(HL)
INC HL
PUSH BC
PUSH HL
CALL PutCh ;onto RAM, not conout
POP HL
POP BC
DJNZ BHLMsg
RET
ENDIF
;
BlkFCB: LD B,11 ;blank out FCB name,typ
LD DE,FCB+1
BlkFil: LD A,' ' ;blank out B bytes at DE
LD (DE),A
INC DE
DJNZ BlkFil
RET
BBlank: PUSH BC ;blank out B spaces
LD E,' '
IF VDM
CALL PutCh ;ram...
ELSE
CALL CONOut
ENDIF
POP BC
DJNZ BBlank
RET
;
;Show messages and prompts
;
MsgDsp: PUSH HL ;most start at "top"
CALL UpLft
POP HL
AltDsp: PUSH HL ;display message in alt video
CALL MakAlt
POP HL
CALL Dspla
JR UnAlt
;
Prompt: PUSH HL ;Prompt: blank first line
CALL UpLft ;(with attribute)
CALL MakAlt
LD A,(View)
INC A
LD E,A
CALL SpEOL
CALL UnAlt
POP HL
JR MsgDsp ;then show prompt message
;
;Handle alternate video
;
MakAlt: LD A,(AltHdr) ;optional for messages and prompts
OR A
RET Z
AltY: ;mandatory for ctl-chars
IF NOT VDM
LD HL,AltOn ;ram always uses hi bit
LD A,(AltBit)
OR A
JP Z,CtlStr
ENDIF
LD A,X
LD (AltMsk),A
RET
UnAlt: LD A,(AltHdr)
OR A
RET Z
UnAltY:
IF NOT VDM
LD HL,AltOff
LD A,(AltBit)
OR A
JP Z,CtlStr
ENDIF
XOR A
LD (AltMsk),A
RET
;
;Character output
;
IF VDM
XPutCh: ;show character in E
PutCh: NOP ;<--- goes to RET for Quiet
LD A,E
CP BS ;handle "backspace" (used in GetStr)
JR Z,PutBS
LD A,(AltMsk)
OR E
LD E,A
PUSH HL
LD HL,(SPos)
CALL VidIN
LD (HL),E
CALL VidOUT
INC HL
LD (SPos),HL
POP HL
RET
PutBS: PUSH HL
LD HL,(SPos)
DEC HL
LD (SPos),HL
POP HL
RET
ELSE
XPutCh: LD A,(Horiz) ;show character in E
LD HL,View ;UNLESS in lower rt corner
CP (HL)
JR NZ,PutCh
LD A,(Vert)
LD HL,TxtLns
CP (HL)
RET Z
PutCh: PUSH HL ;show char in E
PUSH DE
PUSH BC
LD A,(Filter) ;filtered
INC A
CP E
JR NC,PutCh1
LD E,'?'
PutCh1: LD A,(AltMsk)
OR E
LD E,A
CALL CONOut
POP BC
POP DE
POP HL
RET
ENDIF
Echo: CP 20H ;echo typed char, IF nice
RET C ; (used for one-char input)
PutChA: PUSH DE ;show char in A
PUSH AF ; save it too (for Echo)
LD E,A
CALL PutCh
POP AF
POP DE
RET
;
CONOut:
IF NOT VDM
NOP ;<--- goes to RET for Quiet
ENDIF
LD C,UCON ;put byte to console (mostly ctls)
JP BDOSep
;
;Position cursor to row D column E
;
GoTo: LD A,(NoHdrF) ;lie for lack of header
AND D ;(decrement row if >0)
JR Z,GoTo01
DEC D
GoTo01: LD A,(BelowF) ;implement window below
OR A
JR Z,GoToIt
LD A,(Lines)
ADD A,D
LD D,A
IF VDM
GoToIt: CALL Xlate ;convert to VidRAM
LD (SPos),HL ;and set (and return) it
RET
Xlate: LD HL,(Width) ;translate (D,E) to vidRAM addr
LD BC,(Empty)
ADD HL,BC
LD B,H
LD C,L ;now BC=row length
LD HL,(VidRAM)
LD A,D
OR A
JR Z,XltLpF
XltLp: ADD HL,BC ;add rows
DEC D
JR NZ,XltLp
XltLpF: ADD HL,DE ;now cols
RET ;return it in HL
UXlate: LD BC,(VidRAM) ;untranlate vidRAM addr to (D,E)
OR A
SBC HL,BC
EX DE,HL
LD HL,(Width)
LD BC,(Empty)
ADD HL,BC
LD B,H
LD C,L
EX DE,HL
LD DE,0
UXltLp: SBC HL,BC ;count rows
JR C,UXltLF
INC D
JR UXltLp
UXltLF: ADD HL,BC
LD E,L ;remainder is cols
RET
ELSE
GoToIt: LD A,D
LD (CurRow),A
LD A,(PosMod)
CP 'N'
JR NZ,GoYPos
LD HL,PCu ;use Down,Right method (gaak)
CALL Go2Byt ;home first
LD A,D
OR A
JR Z,Go2RwF
Go2Row: PUSH DE ;move down to desired row
LD E,LF
CALL CONOut
POP DE
DEC D
JR NZ,Go2Row
Go2RwF: LD A,E
OR A
RET Z
Go2Col: LD HL,PCu+2
CALL Go2Byt ;now across to desired col
DEC E
JR NZ,Go2Col
RET
GoYPos: CP 'A' ;Okay, can be more sophisticated...
JR Z,GoANSI
LD HL,PCu ;use ESC = sequence
CALL Go2Byt ;leadin byte(s)
LD HL,PCu+2
PUSH DE ;now coordinates
PUSH HL
LD A,(PosMod) ;which order?
CP 'R'
JR Z,GoToX ;(backwards)
LD A,D
ADD (HL)
LD E,A
CALL CONOut
POP HL
POP DE
INC HL
LD A,E
ADD (HL)
LD E,A
CALL CONOut
JR GoToDl
GoToX: LD A,E
ADD (HL)
LD E,A
CALL CONOut
POP HL
POP DE
INC HL
LD A,D
ADD (HL)
LD E,A
CALL CONOut
GoToDl: LD A,(PosDly) ;optional delay for some terminals
OR A
RET Z
LD B,A
LD C,0
JP BDlyLp
GoANSI: LD HL,ANSIms+3 ;use ANSI sequence
LD A,D
INC A ;origin 1,1
CALL GoASub
LD HL,ANSIms+6
LD A,E
INC A
CALL GoASub
LD HL,ANSIms
CALL CtlStr
JR GoToDl
GoASub: LD (HL),'0' ;tens digit
GASl1: CP 10
JR C,GAS2
INC (HL)
SUB 10
JR GASl1
GAS2: INC HL
ADD '0' ;units
LD (HL),A
RET
Go2Byt: CALL Go1Byt ;show one or two bytes at HL
LD A,(HL)
OR A
RET Z
Go1Byt: PUSH DE
LD B,1 ;just do one byte
CALL CtlSLp
POP DE
RET
ANSIms: DB 8, ESC,'[00;00H' ;for use with CtlStr
ENDIF
;
;
IfSpLn: LD A,(AltHdr) ;draw sep line IF headers not alt
OR A
RET NZ
SepLin: CALL MakAlt ;draw separator line
LD A,(View)
LD D,A
LD E,'-'
SLDlp: PUSH DE
CALL PutCh
POP DE
DEC D
JR NZ,SLDlp
JP UnAlt
;
;
;SHOW SCREEN ROUTINES
;
; | +------------------------
; |HELLO! | ^
; |This is your |text file, which is seen Vert
; |on the screen| just like this._ v
; | | \
; |<---NSkip---> <-----Horiz-----> \
; |<-----------CurCol------------> \Cursor at (H,V)
;
;Recheck current position on screen
;
Orient: LD A,(Vert) ;Adjust Horiz and Vert
LD E,A
CALL CrLft ;Start of first screen line
JR NC,Ornt1
CALL TopV ;At top, set Vert to 1
JR Ornt2
Ornt1: LD A,(Vert) ;Decrement Vert if needed
SUB E ; to avoid whitespace at top
LD (Vert),A
Ornt2: CALL ColCnt ;Update column (in A,B,CurCol)
LD A,(Horiz) ;Compute cursor offset in line
LD C,A
LD A,B
SUB C ;CurCol-Horiz is minimum offset
JR NC,Ornt4a
XOR A ;set 0 if negative
Ornt4a: LD E,A
LD A,(NSkip) ;present offset < min?
CP E
JR C,Ornt4b ;if so, change
CP B ;bigger than CurCol-1?
JR C,Ornt4c ;if not, OK
LD A,B ;round down to small enough
DEC A
AND 0C0H ;multiple of 32
JR Ornt4c
Ornt4b: LD A,E ;round up to big enough
OR 1FH
JR Z,Ornt4c
INC A
Ornt4c: LD (NSkip),A ;set (new?) offset
SUB B
NEG
LD (Horiz),A
IF VDM
CALL PosCur ;Figure cursor address
ENDIF
LD HL,(CurLin) ;Figure line, page
LD (CurPgL),HL
LD A,(FMode)
CP 'N'
LD A,(PgLen)
JR NZ,Ornt5
XOR A ;don't SHOW pagination for nondocs
Ornt5: LD E,A
LD D,0
DEC HL
LD B,D
LD C,D
OR A ;not paginating?
JR Z,OrnLpF
INC BC
OrntLp: SBC HL,DE
JR C,OrnLpF
INC BC
JR OrntLp
OrnLpF: ADD HL,DE
INC HL
LD (CurPgL),HL
LD (CurPg),BC
RET
;
;Show (just) as much of the text as necessary
;
ShoTx: CALL KyStat ;check keybd
JR NZ,ShoTx1
CALL TestSc ;check postponed screen disp
JP NZ,ShoAll ;do it!
CALL ShoPos ;quiet? update header
CALL TestCu ;check postponed line disp
JR NZ,DoPost ;do it (or more, if requested)
ShoTx1: LD A,(ShoFlg) ;busy...
OR A ;nothing (0)
RET Z
DEC A
JP Z,ShoRCu ;just one line (1,2) - can be postponed
DEC A
JP Z,ShoCu
DEC A
JP Z,ShoDn ;bottom part (3)
JP ShoSc ;or whole screen
DoPost: LD A,(ShoFlg)
CP 3
JP C,ShoCu ;at LEAST this
JP Z,ShoDn
JP ShoSc
;
;Show position in file, no matter what
;
ShoPos: LD A,(NoHdrF)
OR A
RET NZ
CALL Force ;must see this
LD DE,DspPg ;Update header
CALL GoTo
CALL MakAlt ;C128 bug fix requires GoTo first
LD HL,(CurPg)
LD A,(FMode)
CP 'N'
CALL NZ,ShPSb1
LD DE,DspLin
LD HL,(CurPgL)
CALL ShPoSb
LD DE,DspCol
LD A,(CurCol)
LD L,A
LD H,0
CALL ShPoSb
CALL UnAlt
JP UForce
ShPoSb: PUSH HL ;show a number
CALL GoTo
POP HL
ShPSb1: LD DE,PNBuf
CALL BCDCon
LD HL,PNBuf
LD B,5
JP BHLMsg
;
;Show current line only (fast)
;
ShoCu: CALL ConChk ;(postpone if busy!)
JP NZ,HoldCu
ShoCu1:
IF VDM
JP DspCu
ShoRCu EQU ShoCu
ELSE
LD A,(Vert)
LD B,A
JP ShoLn
;
ShoRCu: CALL ConChk ;(postpone if busy!)
JP NZ,HoldCu
CALL FetchB
CP TAB ;can't do this with tab at left
JP Z,ShoCu
LD A,(Vert) ;special routine: only RIGHT of cursor
LD D,A ;...modeled on ShoLCu
LD A,(RulFlg)
AND 1
ADD D
LD D,A ;current row
LD A,(Horiz)
DEC A
LD E,A
JP Z,ShoCu ;can't do this at left of screen
DEC E
CALL GoTo ;position to start
LD E,1 ;find start of line
CALL CrLft
PUSH HL
LD HL,Horiz
LD A,(NSkip)
ADD (HL)
DEC A
LD D,A
DEC A
LD B,A ;skip till just before cursor
LD A,(View)
INC A
SUB (HL)
LD E,A
INC E
POP HL
CALL ShoLSb ;do part (char!) left of cursor
INC E ;(DON'T ask me why this INC is needed)
LD D,E
DEC D
LD A,(Vert)
LD HL,TxtLns
CP (HL) ;avoid last line, col
JR NZ,ShRCu3
DEC D
ShRCu3: LD HL,(AftCu)
JP ShoLSb
ENDIF
;
;Display from Cursor line-1 down
;
ShoDn: CALL ConChk ;(postpone if busy!)
JP NZ,HoldSc
IF VDM
JP ShoSc0 ;shucks, do whole screen
ELSE
LD A,(DSFlg) ;(or line-2, if DS)
LD HL,Vert
ADD (HL)
JR Z,ShoSc0
LD B,A
DJNZ ShScLp
JR ShoSc0
ENDIF
;
;Show everything on emerging from macros etc
;
ShoAll: CALL Orient
CALL DoHdr
CALL ShoPos
JR ShoSc0
;
;Display whole text screen (sigh)
;
ShoSc: CALL ConChk ;(Postpone if busy!)
JP NZ,HoldSc
ShoSc0: CALL RulFix
CALL SetNo ;kill any pending redisps
XOR A
LD (CuFlg),A
CPL
LD (HorFlg),A
IF NOT VDM
LD B,1 ;Simple method if not memory mapped
ShScLp: PUSH BC
CALL ShoLn
POP BC
INC B
LD A,(TxtLns)
INC A
SUB B
JR NZ,ShScLp
RET
ELSE
DspLn1: LD A,1 ;Display line 1 only
JR DspT0
DspTx: XOR A
DspT0: LD (DspFlg),A
LD A,(ShutUp) ;Special fast full-screen display
CP 0C9H
RET Z ;oops, quiet
XOR A
LD (DspFlg),A
CALL UpLft
LD A,(Vert)
LD E,A
CALL CrLft ;Find start of screen
LD A,(Vert) ;cursor line
DEC A
JR Z,DspT1 ;Skip if it was 1
LD E,A ;line count
LD A,(DspFlg)
DEC A
JR Z,Dsp1
CALL DsLns ;display them
JR DspT1
Dsp1: LD E,1 ;only 1 for DspLn1
JP DsLns
DspCu: LD A,(ShutUp) ;Display cursor line only
CP 0C9h
RET Z ;oops, quiet
LD A,0FFh
LD (DspFlg),A
LD A,(RulFlg)
AND 1
LD HL,Vert
ADD (HL)
LD D,A ;position cursor on screen
LD E,0
CALL GoTo
LD E,1
CALL CrLft ;start of line
DspT1: LD A,(Horiz)
DEC A
JR Z,DspT2 ;Was column 0?
LD B,A
LD A,(NSkip) ;screen offset
LD C,A
CALL DsChr ;show part of line before cursor
DspT2: LD A,(Width)
LD HL,Horiz
INC A
SUB (HL)
JR Z,DspT3 ;End of line?
LD B,A ;Get remaining characters
LD C,0 ;No skip
LD HL,(AftCu) ;Point at trailing text
LD E,1
CALL DsLin ;Display the data
LD A,(DspFlg)
DEC A
RET Z ;quit here for DspLn1
JR DspT4
DspT3: LD E,1 ;Skip to line following cursor
CALL CrRit
JR C,DspT4
LD HL,(EndTx)
DspT4: LD A,(DspFlg) ;quit here for DspCu
INC A
RET Z
LD A,(Vert)
LD E,A
LD A,(TxtLns)
SUB E ;TxtLns-Vert: still to do
RET Z
LD E,A
JR DsLnsX
;
DsLns: XOR A ;Sbr: display E lines at (HL)
LD (DcCR+1),A
LD A,(Width)
LD B,A
LD A,(NSkip)
LD C,A
;
DsLin: CALL DsChr ;Entry to finish cursor line
LD A,B
OR A ;count exhausted?
JR Z,DsLn2
PUSH DE
PUSH HL ;fill for CR
LD E,B
INC E ;count+1
CALL SpEOL
POP HL
POP DE
DsLn2: LD BC,(Empty) ;Set screen position for next line
LD IY,(SPos)
ADD IY,BC
LD (SPos),IY
DEC HL ;Find next line to do
LD BC,256
LD A,CR
CPIR
DEC E
RET Z ;All done?
DsLnsX: LD BC,(EndTx)
PUSH HL
SCF
SBC HL,BC ;Watch for end of text
POP HL
JR C,DsLns
;
DsLn3: PUSH DE ;text ended, fill with blanks
LD A,(Width)
INC A ;count+1
LD E,A
CALL SpEOL
LD HL,(SPos)
LD DE,(Empty) ;End of line; find next
ADD HL,DE
LD (SPos),HL
POP DE
DEC E
JR NZ,DsLn3 ;Keep going
RET
;
DsChr: XOR A ;Sbr: display B chars of text (C=skip count)
ADD C ;Need to skip?
JR Z,DsCLp2
PUSH BC
LD B,C ;yes, do it
LD C,0
DsCLp1: CALL GetNx
JR NZ,DsCh1 ;Hit a CR, quit
POP BC
RET
DsCh1: CP TAB
CALL Z,DsCh3 ;Adjust for Tabs
DJNZ DsCLp1
LD A,C ;restore everything
POP BC
LD C,A
;
DsCLp2: CALL GetNx ;data byte
JR Z,DcCR ;oops, CR
LD (DcCR+1),A
CP TAB
CALL Z,DsCh4 ;Adjust for Tabs
CP 20h
JR NC,DsCh2
ADD 0C0h ;ctls show as hili letters
DsCh2: CALL DcPoke
DJNZ DsCLp2 ;Do next byte
RET
DcCR: LD A,0 ;<--patch last byte here
CP ' '
LD A,CR
LD (DcCR+1),A
RET Z
LD A,(HCRFlg) ;can suppress this...
OR A
RET Z
LD A,'<' ;show CR if hard
DEC B
DcPoke: CALL VidIN
LD IY,(SPos)
LD (IY),A
INC IY
LD (SPos),IY
JP VidOUT
;
DsCh3: LD A,(NSkip) ;Tab skip adjust
SUB B
JR DsCh5
DsCh4: PUSH BC ;Tab display adjust
PUSH DE
PUSH HL
LD HL,(SPos)
CALL UXlate ;E=col
LD A,(NSkip)
ADD E
POP HL
POP DE
POP BC
DsCh5: PUSH HL
LD HL,TabCnt
AND (HL)
XOR (HL)
POP HL
LD C,A ;Set blank count
LD A,' ' ;Get first one
RET
ENDIF
;
;Show line 1 (to wipe out msgs)
;
IF VDM
ShoLn1 EQU DspLn1
ELSE
ShoLn1: LD B,1 ;fall thru...
;
;Show line number B (=1...TxtLns)
;
ShoLn: PUSH BC
CALL KyStat ;(helps buffering for slow keyboards)
POP BC
LD A,(RulFlg)
AND 1
ADD B
LD D,A ;position cursor on screen
LD E,0
PUSH BC
CALL GoTo
POP BC
LD A,(Vert) ;is line before or after cursor?
SUB B
JR Z,ShoLCu ;ouch, it's cursor line
JR C,ShoLAf
ShoLBf: LD E,A ;okay, before
INC E
CALL CrLft
LD A,(View)
INC A
LD E,A
LD A,(NSkip)
LD B,A
LD D,255
JR ShoLSb
ShoLAf: NEG ;okay, after
PUSH BC ;save line#
LD E,A
CALL CrRit
POP BC
PUSH AF
LD A,(View)
LD D,A
INC A
LD E,A
LD A,(TxtLns)
CP B ;last line? avoid last column
JR NZ,ShLAf0
DEC D
ShLAf0: POP AF
JR C,ShLAf1
JR Z,ShLAf2
ShLAf1: JP ClEOL ;no line!
ShLAf2: LD A,(NSkip)
LD B,A
ADD D
LD D,A
JR ShoLSb
ShoLCu: LD E,1 ;hmm, right on cursor
PUSH BC ;save line#
CALL CrLft
LD A,(NSkip)
LD B,A
LD A,(CurCol) ;do part to left
DEC A
LD D,A
LD A,(View)
INC A
LD E,A
CALL ShoLSb
LD D,E
DEC D
POP AF ;line#
LD HL,TxtLns
CP (HL) ;avoid last line, col
JR NZ,ShLCu1
DEC D
ShLCu1: LD HL,(AftCu)
;
ShoLSb: LD A,D ;Show up to column D of text starting at HL
OR A ;E=room+1, B=Cols to skip (if any)
RET Z
XOR A
EXX
LD B,A ;B',C' keep track of previous chars
LD C,A
LD E,A ;E' is count skipped
EXX
LD C,A ;initialize GetNx
ADD B
JR Z,ShLSL2
ShLSL1: CALL GetNx ;eat skipped columns
JP Z,ClEOL ;end of line?
CP Tab
JR Z,ShLS1T
EXX
INC E ;E'
EXX
DEC D
DJNZ ShLSL1
CALL ShSvCh
JR ShLSL2
ShLS1T: EXX ;count for tabs
LD A,E
LD HL,TabCnt
AND (HL)
XOR (HL) ;extra spaces
INC A ;plus usual one
PUSH AF
ADD E
LD E,A
POP AF
EXX
PUSH AF
SUB D
NEG
LD D,A
POP AF
SUB B
NEG
LD B,A
JR NZ,ShLSL1
LD A,Tab
CALL ShSvCh
ShLSL2: CALL GetNx ;show the rest
CALL ShSvCh
PUSH HL
PUSH BC
PUSH DE
JR Z,ShLSCr ;take care of CR,TAB
CP Tab
JR Z,ShLSTb
CP 20H
JR NC,ShLSCh
ADD 40H ;other ctls are hili letters
PUSH AF
CALL AltY ;(mandatory)
POP AF
CALL PutChA
CALL UnAltY
JR ShLRet
ShLSCr: EXX
LD A,C ;last char
EXX
CP ' '
JR Z,ShLCrF ;SCR doesn't show
LD A,(HCRFlg)
OR A
JR Z,ShLCrF ;HCRs also MAY not...
LD E,'<'
CALL PutCh
POP DE
DEC D
DEC E
PUSH DE
LD A,E ;don't ClEOL if now in last col
CP 2
ShLCrF: CALL NC,ClEOL
POP DE ;end of line
POP BC
POP HL
RET
ShLSTb: LD A,(View) ;hit a tab...
INC A
SUB E ;column
LD HL,TabCnt
AND (HL)
XOR (HL) ;figure extra spaces
LD B,A
JR Z,ShLTLF
ShLTbL: LD A,' ' ;do them
CALL PutChA
POP DE
DEC D
DEC E
PUSH DE
DEC E
JR Z,ShLRet
DJNZ ShLTbL ;then one last
ShLTLF: LD A,' '
ShLSCh: CALL PutChA ;just show ordinary chars
ShLRet: POP DE
POP BC
POP HL
DEC E
DEC D
RET Z
LD A,E
DEC A
RET Z
JR ShLSL2
ShSvCh: EXX ;keep track of prev chars
LD C,B
LD B,A
EXX
RET
ENDIF
;
;
ClEOL: ;clear to EOL (quickly if possible)
IF NOT VDM
LD HL,ClL
CALL CtlStr
RET NC
ENDIF
SpEOL: DEC E ;this always SPACES (for attributes)
RET Z
ClELp:
IF VDM
LD C,E ;this is for SPEED
LD B,0
LD HL,(SPos)
LD A,(ShutUp)
OR A
JR Z,ClEL1
ADD HL,BC ;oops, quiet
JR ClEL2
ClEL1: LD D,H
LD E,L
INC DE
CALL VidIN
LD A,(AltMsk)
OR ' '
LD (HL),A
LDIR
CALL VidOUT
ClEL2: LD (SPos),HL
RET
ELSE
LD A,(CurRow)
INC A
LD HL,PhysLn
CP (HL)
JR NZ,ClEL3
DEC E ;avoid last char on last line
RET Z
ClEL3: LD A,' '
CALL PutChA
DEC E
JR NZ,ClEL3
RET
ENDIF
;
ClLast: LD A,(PhysLn) ;clear last line on screen
DEC A
LD D,A
LD E,0
CALL GoToIt
LD A,(View)
LD E,A ;do NOT INC this, it's last line
JR ClEOL
;
;
;Set level of display required
;
SetAl: LD A,0FFH ;routines to set it
JR Set1 ;(must preserve ALL REGS and FLAGS)
SetDn: LD A,3
JR Set1
SetCu: LD A,2
JR Set1
SetRCu: LD A,1
JR Set1
SetNo: LD A,0 ;this one WILL shut it up...
JR Set2
Set1: PUSH AF ;...otherwise, do not DEcrease previous requests
EX (SP),HL
LD A,(ShoFlg)
CP H
EX (SP),HL
JR NC,Set3
POP AF
Set2: LD (ShoFlg),A
RET
Set3: POP AF
RET
;
;Hardware vertical scrolls for speed
;
IF VDM
ScrlU EQU SetAl ;not implemented
ScrlD EQU SetAl
ELSE
ScrlU: CALL TestCu ;be sure all ok first
CALL NZ,ShoCu1
LD HL,DelL
CALL ScrlUD
JR SetCu
ScrlD: CALL TestCu
CALL NZ,ShoCu1
LD HL,InsL
CALL ScrlUD
JR SetCu
ScrlUD: PUSH HL ;[common sbr, used in one-liners too]
LD A,(NoHdrF) ;canNOT do this if header suppressed
LD HL,OddDel ; and ins/del specific to ln 1.
AND (HL)
LD HL,WinFlg ; or if Windowing (in any event)
OR (HL)
POP HL
JR NZ,SetAl
PUSH HL
CALL UpLft
POP HL
CALL CtlStr ;do it
JR C,SetAl ;(maybe couldn't)
LD A,(OddDel)
OR A
CALL NZ,RulFix
RET
ENDIF
;
; Set flag for redisplay due to arrow keys
;
EdgeL: LD A,(Vert)
DEC A
RET NZ
LD A,(CurCol)
DEC A
RET NZ
JP ScrlD ;scroll if at top left
EdgeR: CALL Fetch
CP CR
JR Z,ER01
LD A,(Horiz) ;not CR: if off right edge, scroll
LD HL,View
CP (HL)
JR Z,HorScl
RET
ER01: LD A,(Vert) ;CR: if at bot right, scroll
LD HL,TxtLns
CP (HL)
JP Z,ScrlU
JR EdgeD
EdgeU: LD A,(Vert)
DEC A
JP Z,ScrlD ;first line: scroll
RET
EdgeD: LD A,(Vert)
LD HL,TxtLns
CP (HL)
JP Z,ScrlU ;last line: scroll
RET
;
;Watch for horizontal scroll
;
IfScl: LD A,(NSkip) ;request scroll if already scrolled
OR A
RET Z
HorScl: CALL SetCu ;request scroll
LD A,0
LD (HorFlg),A
RET
;
;Postpone display for speed
;
HoldCu: LD A,0FFH ;save if busy
LD (CuFlg),A
RET
HoldSc: LD A,0FFH
LD (ScFlg),A
RET
TestSc: LD HL,ScFlg ;test & reset postponement
JR TestX
TestCu: LD HL,CuFlg
TestX: XOR A ;(ret with Z if none)
ADD (HL)
LD (HL),0
RET
;
; Position cursor for input
;
IF VDM
CursrX: CALL PosCur ;turn off cursor if on
LD HL,CursOn
LD A,(HL)
OR A
RET Z
LD (HL),0
JR CCursr
ENDIF
;
Cursr: CALL PosCur ;turn on cursor
IF VDM
LD HL,CursOn ;(if off)
LD A,(HL)
OR A
RET NZ
LD (HL),0FFH
ENDIF
CALL Fetch
CP CR
IF VDM
JR NZ,CCursr ;show cursor
ELSE
RET NZ
ENDIF
LD A,(HCRFlg) ;oops, on a CR
OR A ;HCRs showing?
IF VDM
JR Z,CCursr
ELSE
RET Z
ENDIF
CALL FetchB ;got to fix HCR flag
LD E,' ' ;kludge to " " or "<"
CP E
JR Z,Csr01
CALL NdCnt
JR C,Csr01
LD E,'<'
Csr01:
IF VDM
CALL PutCh
JR CCursr
ELSE
CALL XPutCh
LD E,BS
JP PutCh
ENDIF
PosCur: LD A,(Horiz)
LD E,A
DEC E
LD A,(RulFlg)
AND 1
LD HL,Vert
ADD (HL)
LD D,A
IF VDM
CALL GoTo ;sets SPos too
LD (CPos),HL
RET
ELSE
JP GoTo
ENDIF
;
IF VDM
SCursr: LD HL,(SPos) ;actually make a cursor visible
JR HLCurs
CCursr: LD HL,(CPos)
HLCurs: LD A,(ShutUp)
OR A
RET NZ ;oops, quiet
CALL VidIN
BIT 7,(HL)
RES 7,(HL)
JR NZ,Sk1Cu
SET 7,(HL)
Sk1Cu: JP VidOUT
ENDIF
;
;
;
; MESSAGES
;
ErrTab: DW 0,MSG1,MSG2,MSG3,MSG4,MSG7,MSG7,MSG7,MSG8,MSG9
;
MSG1: DB 'Ou','t'+X,'o','f'+X,'Memory',0
MSG2: DB 'Invali','d'+X,'Key',0
MSG3: DB 'I/','O'+X ;(fall through to 7)
MSG7: DB 'Error',0
MSG4: DB 'No','t'+X,'Found',0
MSG8: DB 'Synta','x'+X,'Error',0 ;(note 5,6 not used)
MSG9: DB 'Canno','t'+X,'Reformat',0 ;(note error 10 has no MSG)
;
NameQ: DB 'Name',':'+X,0
ReadQ: DB 'Read',':'+X,0
WritQ: DB 'Write',':'+X,0
EraQ: DB 'Erase',':'+X,0
LoadQ: DB 'Load',':'+X,0
FindQ: DB 'Find',':'+X,0
ChgQ: DB 'Chang','e'+X,'to',':'+X,0
DirQ: DB 'Drive',':'+X,0
PrtQ: DB 'Options',':'+X,0
PgLnQ: DB 'Length',':'+X,0
ColQ: DB 'Column',':'+X,0
PageQ: DB 'Page',':'+X,0
LineQ: DB 'Line',':'+X,0
MacroQ: DB 'Macro',':'+X,0
RptcQ: DB 'Repea','t'+X,'coun','t'+X,'([Q],0-9/*)',':'+X,0
KeyQ: DB 'Ke','y'+X,'numbe','r'+X,'([N/Q],0-9)',':'+X,0
QuitQ: DB 'Abando','n'+X,'changes','?'+X,'(Y/N)',':'+X,0
UnchgQ: DB 'Unchanged',';'+X,'save','?'+X,'(Y/N)',':'+X,0
;
; Changed: Q File size: NNNNN Memory used: NNNNN Free: NNNNN
InfMsg: DB CR
DB ' '+X,'Changed',':'+X
ModQQQ: DB 'Q',X,7,'Fil','e'+X,'size',':'+X
SizNNN: DB 'NNNNN',X,5,'Memor','y'+X,'used',':'+X
UsdNNN: DB 'NNNNN',X,5,'Free',':'+X
FreNNN: DB 'NNNNN',CR,0
;
; [Menus disabled; see VDE.DOC or .QRF]
; [See VDE.DOC and .QRF for help]
;
HlpMsg: DB X,21,'[Menu','s'+X,'disabled',';'+X,'se','e'+X
DB 'VDE.DO','C'+X,'o','r'+X,'.QRF]',CR,0
;
;P00:FILENAME.TYP [X Pg nn Ln nn Cl nn INS vt hy AI DS MR ESC...etc
;
Header: DB X,31,'L','n'+X,X,5,'Cl',CR,0
DspFnm EQU 1 ;offsets for display
DspOP EQU DspFnm+22
DspPg EQU DspOP+3
DspLin EQU DspPg+8
DspCol EQU DspLin+8
DspIns EQU DspCol+5
DspTab EQU DspIns+5
DspHyp EQU DspTab+3
DspInd EQU DspHyp+3
DspSpc EQU DspInd+3
DspMrg EQU DspSpc+3
DspEsc EQU DspMrg+4
DspEsQ EQU DspEsc+3
TogOff: DB ' '
CQTog: DB ' ^Q'
COTog: DB ' ^O'
CPTog: DB ' ^P'
CKTog: DB ' ^K'
ESCTog: DB 'ESC'
YNMsg: DB 'Chg? (Y/N,*)'
IOmsg DB 'Wait...'
RdyQ: DB 'Rdy'
CQTTog: DB '^QT'
OPon: DB 'OP '
OPoff: DB 'Pg '
INSon: DB 'INS'
VTon: DB 'vt '
HYon: DB 'hy '
AIon: DB 'AI '
DSon: DB 'DS '
MRon: DB 'MR '
;
Bak: DB 'BAK'
;
;
;
;
Data: ;zeroed out at initialization...
;any other values that matter must be set by Start:.
;
;FLAGS
;
FilFlg: DS 1 ;make BAK file?
MSIFlg: DS 1 ;file loaded?
Modify: DS 1 ;file modified?
WinFlg: DS 1 ;windowing?
BelowF: DS 1 ;in window?
MacFlg: DS 1 ;macro going?
ChgFlg: DS 1 ;change followed last find?
FBackw: DS 1 ;find backward?
AIFlg: DS 1 ;auto indent?
DSFlg: DS 1 ;doublespace?
VTFlg: DS 1 ;varitab?
KeyFlg: DS 1 ;allow redisp?
HorFlg: DS 1 ;horiz scroll? (must be next to ShoFlg)
ShoFlg: DS 1 ;redisp code
CuFlg: DS 1 ;postponed line redisp?
ScFlg: DS 1 ;postponed screen redisp?
JmpFlg: DS 1 ;jump in progress?
YNFlg: DS 1 ;"*" specified?
SftFlg: DS 1 ;handle space softening
HCRFlg: DS 1 ;showing hard CRs?
IgnFlg: DS 1 ;ignoring dot commands?
;
;STORAGE
;
FMode: DS 1
EdErr: DS 1
CurDsk: DS 1
CurUsr: DS 1
FCBU: DS 1
FindSv: DS 2
MKsav: DS 1
Copies: DS 1
POByt: DS 1
StPrt: DS 2
EndPr: DS 2
PageN: DS 1
PBeg: DS 1
PNum: DS 1
POff: DS 1
PrTMrg: DS 1
PrLMrg: DS 1
HdrPtr: DS 2
HdrLen: DS 1
PgLen: DS 1
LfMarg: DS 1 ;L,R order
RtMarg: DS 1
LMSav: DS 1 ;ditto
RMSav: DS 1
PhysLn: DS 1
DirLns: DS 1
DirCls: DS 1
CmdPtr: DS 2
RptCnt: DS 1
LFChr: DS 1
SavQ: DS 1
SavQ2: DS 1
SavIns: DS 1
AltMsk: DS 1
CurRow: DS 1
DspFlg: DS 1
IsBVal: DS 1
PrevCh: DS 1
PrvCh2: DS 1
IF VDM
Width: DS 2
Empty: DS 2
ENDIF
;
;SCREEN DATA AREA
;
TxtLns: DS 1 ;text screen size
Horiz: DS 1 ;virtual screen position
Vert: DS 1
NSkip: DS 1 ;virtual screen offset
IF VDM
SPos: DS 2 ;screen position
CPos: DS 2 ;cursor position
CursOn: DS 1 ;is cursor "on"?
ELSE
HPos: DS 1 ;room left on line
ENDIF
;
CurCol: DS 1 ;column
CurLin: DS 2 ;line
CurPg: DS 2 ;page
CurPgL: DS 2 ;line on page
;
BegTx: DS 2 ;text boundaries
BefCu: DS 2
AftCu: DS 2
EndTx: DS 2
LastCu: DS 2
;
;BUFFERS
;
ConBufL EQU 30
ConBuf: DS ConBufL+1 ;console buffer
;
FCBBuf: DS 32 ;for SavNam, Dir
RulBuf: DS 128 ;for RulFix
;
StrSiz EQU 128 ;size of Macro strings
LinLen EQU 65 ;max length of VDE input line
FndStr: DS LinLen+1 ;string buffers
ChgStr: DS LinLen+1
MacStr: DS StrSiz+1
;
DataLn EQU $-Data ;end of DATA segment
;
DS 48
Stack: DS 4
;
VDEend: ;text starts here if menus disabled
;
;^E csr up ^F word rt ^W line up ^G delete ^U undelete ^P prt code
;^X down ^A word lf ^Z line dn DEL del left ^B reform ^PZ place mark
;^S left ^R page up ^V insert ^T del word ^^ case toggle
;^D right ^C page dn ^N insrt CR ^Y del line ^L(^\) rpt find
; (PRESS ^K/ESC, ^O, ^Q FOR SUBMENUS)
;
Menu: DB '^','E'+X,'cs','r'+X,'up',' '+X,'^','F'+X,'wor','d'+X,'rt',X,3
DB '^','W'+X,'lin','e'+X,'up',X,3,'^','G'+X,'delete',X,4
DB '^','U'+X,'undelete',X,3,'^','P'+X,'pr','t'+X,'code',CR
DB '^','X'+X,'down',X,4,'^','A'+X,'wor','d'+X,'lf',X,3
DB '^','Z'+X,'lin','e'+X,'dn',' '+X,'DE','L'+X,'de','l'+X,'left',' '+X
DB '^','B'+X,'reform',X,5,'^P','Z'+X,'plac','e'+X,'mark',CR
DB '^','S'+X,'left',X,4,'^','R'+X,'pag','e'+X,'up',X,3
DB '^','V'+X,'insert',X,4,'^','T'+X,'de','l'+X,'word',' '+X
DB '^','^'+X,'cas','e'+X,'toggle',CR
DB '^','D'+X,'right',X,3,'^','C'+X,'pag','e'+X,'dn',X,3
DB '^','N'+X,'insr','t'+X,'CR',' '+X,'^','Y'+X,'de','l'+X,'line',' '+X
DB '^L(^\',')'+X,'rp','t'+X,'find',CR
DB X,24,'(PRES','S'+X,'^K/ESC',','+X,'^O',','+X,'^','Q'+X
DB 'FO','R'+X,'SUBMENUS)',CR,0
;
;^KB Begin block ^KW block Write ^KL Load new ^KN Name EscM Macro def
;^KK end block ^KY delete block ^KS Save ^KI Info Esc# store key
;^KU Unmark blk ^KR Read file ^KD save+load ^KP Print Esc0..9 use ky
;^KC Copy block ^KF File list ^KX save+eXit Esc-TAB tab back
;^KV moVe block ^KE Erase file ^KQ Quit Esc-Arrows shift screen
;
KMenu: DB '^K','B'+X,'Begi','n'+X,'block',' '+X,'^K','W'+X,'bloc','k'+X,'Write'
DB X,3,'^K','L'+X,'Loa','d'+X,'new',X,5,'^K','N'+X,'Name',X,4
DB 'Esc','M'+X,'Macr','o'+X,'def',CR
DB '^K','K'+X,'en','d'+X,'block',X,4,'^K','Y'+X,'delet','e'+X,'block'
DB ' '+X,'^K','S'+X,'Save',X,9,'^K','I'+X,'Info',X,4
DB 'Esc','#'+X,'stor','e'+X,'key',CR
DB '^K','U'+X,'Unmar','k'+X,'blk',X,3,'^K','R'+X,'Rea','d'+X,'file'
DB X,5,'^K','D'+X,'save+load',X,4,'^K','P'+X,'Print',X,3
DB 'Esc0..','9'+X,'us','e'+X,'ky',CR
DB '^K','C'+X,'Cop','y'+X,'block',X,3,'^K','F'+X,'Fil','e'+X,'list'
DB X,5,'^K','X'+X,'save+eXit',X,4,'Esc-TA','B'+X,'ta','b'+X,'back',CR
DB '^K','V'+X,'moV','e'+X,'block',X,3,'^K','E'+X,'Eras','e'+X,'file'
DB X,4,'^K','Q'+X,'Quit',X,9,'Esc-Arrow','s'+X,'shif','t'+X,'screen',CR
DB 0
;
; ^QB goto Block ^Q<u> scr top ^QY del to EOL ^QF Find,
; ^QP to Place mk ^Q<d> scr bot ^QDel " to BOL ^QA replAce
; ^QR goto TOF ^Q<l> ln start ^QT del to char (/I,B/, _)
; ^QC goto EOF ^Q<r> ln end ^QU UNdel line ^QI goto pg/ln
;
QMenu: DB X,6,'^Q','B'+X,'got','o'+X,'Block',X,4,'^Q<u','>'+X,'sc','r'+X,'top'
DB X,5,'^Q','Y'+X,'de','l'+X,'t','o'+X,'EOL',X,4,'^Q','F'+X,'Find,',CR
DB X,6,'^Q','P'+X,'t','o'+X,'Plac','e'+X,'mk',X,3,'^Q<d','>'+X,'sc'
DB 'r'+X,'bot',X,5,'^QDe','l'+X,'"'+X,'t','o'+X,'BOL',X,4,'^Q','A'+X
DB 'replAce',CR
DB X,6,'^Q','R'+X,'got','o'+X,'TOF',X,6,'^Q<l','>'+X,'l','n'+X,'start'
DB X,4,'^Q','T'+X,'de','l'+X,'t','o'+X,'char',X,5,'(/I,B/',','+X,'_)',CR
DB X,6,'^Q','C'+X,'got','o'+X,'EOF',X,6,'^Q<r','>'+X,'l','n'+X,'end'
DB X,6,'^Q','U'+X,'UNde','l'+X,'line',X,4,'^Q','I'+X,'got','o'+X
DB 'pg/ln',CR
DB ' ',CR,0
;
; ^OL,R margin set ^OA autoindent ^OP Page length ^O<u> make top ln
; ^OX margin rel ^OI,N tab set,clr ^OS dbl Spacing ^OW Window
; ^OC Center ^OV Vari tabs ^OH Hyphenation ^OQ Quiet (no hdr)
; ^OF Flush rt ^OT ruler ^OD Display CRs ^OZ Zap screen
;
OMenu: DB ' '+X,'^OL,','R'+X,'margi','n'+X,'set',X,4,'^O','A'+X,'autoindent'
DB X,3,'^O','P'+X,'Pag','e'+X,'length',X,3
DB '^O<u','>'+X,'mak','e'+X,'to','p'+X,'ln',CR
DB X,4,'^O','X'+X,'margi','n'+X,'rel',' '+X,'^OI,','N'+X,'ta','b'+X
DB 'set,clr',' '+X,'^O','S'+X,'db','l'+X,'Spacing',X,5
DB '^O','W'+X,'Window',CR
DB X,4,'^O','C'+X,'Center',X,8,'^O','V'+X,'Var','i'+X,'tabs',X,4
DB '^O','H'+X,'Hyphenation',X,5,'^O','Q'+X,'Quie','t'+X,'(n','o'+X
DB 'hdr)',CR
DB X,4,'^O','F'+X,'Flus','h'+X,'rt',X,6,'^O','T'+X,'ruler',X,8
DB '^O','D'+X,'Displa','y'+X,'CRs',X,5,'^O','Z'+X,'Za','p'+X
DB 'screen',CR
DB ' ',CR,0
;
DS 4
MnuEnd: ;menus end here, text can begin
;
;END of Module 3