home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
programs
/
wstar
/
simple.ark
/
SIMPLE.MAC
< prev
next >
Wrap
Text File
|
1987-07-06
|
31KB
|
1,887 lines
TITLE SIMPLE printer driver for WS4, CP/M
;
; Submit DRIVER.SUB to build a SIMPLE.DRV file that can be included in the
; WSPRINT.OVR file using WSCHANGE.
;
IF1
.PRINTX -SIMPLE, 06 Jul 87-
ELSE
.PRINTX -Pass 2-
ENDIF
ASEG
ORG 8680H ; Fixed load point for WS4 #21
;
; Equates
;
TPA EQU 100H ; Where TPA starts for WordStar
;
; Special Characters
;
CR EQU 0DH ; Carriage return
LF EQU 0AH ; Line feed
EOF EQU 1AH ; End of file mark
BS EQU 08H ; Backspace
DEL EQU 7FH ; Delete
ESC EQU 1BH ; Escape
BESC EQU 1CH ; Back escape
TAB EQU 09H ; Tab
FFEED EQU 0CH ; Form feed
SOFTHY EQU 1EH ; Soft hyphen
HARDHY EQU 1FH ; Hard hyphen
;
SOFTCR EQU 10000000B+CR ; Soft carriage return
SOFTAB EQU 10000000B+TAB ; Soft tab (for ^P)
SOFTLF EQU 10000000B+LF ; Soft line feed
SOFTFF EQU 10000000B+FFEED ; Soft form feed
SOFTBL EQU 10000000B+' ' ; Soft blank
;
; Variable Data Sizes
;
TABMAX EQU 15 ; Maximum tabs
DECMAX EQU 6 ; Maximum decimal tabs
RLRSIZ EQU TABMAX+DECMAX+5 ; Ruler size 08may84
;
; Standard WordStar List Output Routines
;
SIBASE EQU 280h
LSTOUT EQU SIBASE+6 ; Prints char in A.
;
LSOSTA EQU SIBASE+9 ; Returns output status to A (0 if busy).
;
LSTRNG EQU SIBASE+12h ; Send string to list device (count byte
; first, just like console strings).
;
; Printer Driver Entry Points
;
; Note that WordStar expects this table to appear exactly
; in this order.
;
PGORG: DB 0 ; Driver model
DW PGLEN ; Code length
DW PDLEN ; Code + unitialize data length
DW $LEN ; String length
DW $SYMTAB ; Symbol table address
DB 'SIMPLE',0 ; Driver name
DW 0 ; Default output file name address
JMP PRINITZ ; Initialize printer
JMP PRINT ; Print a line
JMP PRESUME ; Resume printing
JMP PRABORT ; Abort printing
JMP PRUNITZ ; Uninitialize when done printing
PAGE
;
; Initialize
;
; On entry: HL -> table of printer information
; DE -> user strings
; A is TRUE if form feeds are okay
;
; Note that even though this simple driver does not use all of
; the information, the entire table is defined below.
;
; Do not modify values in the table. WordStar updates the table
; values while printing.
;
PRINITZ:
SHLD PRTABLE ; Store table address
XCHG
SHLD PRUSER
;
STA PRFFOK ; Form feed flag
;
XRA A ; Assume we're at top of first page
STA PRLINE ; No lines on page
STA PRCOLM ; At leftmost column
STA PRFFL ; No form feed lines
STA PRHALF ; No half line feed yet
STA PRONOFF ; No print controls on
STA PRSSIZ ; No string to print
STA PR2ND ; No second character
STA PREXTX ; Not an extended character
STA PRSTRT
;
LXI H,XTOGL ; Zero init attr states
MVI C,XTOGZ
PRINZ1: MOV M,A
INX H
DCR C
JNZ PRINZ1
;
DCR A
STA PRLQCH ; Force PRLQ call
STA PRTYPX ; No last type for line
MVI A,1
STA PRNEXZ ; Skip 1 byte / char
;
CALL GETSIZ
PRINI1: XRA A
RET
;
; Print Value Table Offsets
;
PAGTOP EQU 0 ; Top page margin
PAGBOT EQU PAGTOP+1 ; Bottom page margin
PAGSIZ EQU PAGBOT+1 ; Page size
PAGNMT EQU PAGSIZ+1 ; Page number at top
PAGON EQU PAGNMT+2 ; Page number on/off flag
PAGNMP EQU PAGON+1 ; Column where page number prints
HDMAR EQU PAGNMP+1 ; Heading margin
FTMAR EQU HDMAR+1 ; Footing margin
TBMASK EQU FTMAR+1 ; Tab mask
PAGMAR EQU TBMASK+1 ; Left page margin
PRNNLQ EQU PAGMAR+1 ; Near letter quality on/off
PRNBID EQU PRNNLQ+1 ; Print bidirectional on/off
PRNMIC EQU PRNBID+1 ; Microjustified print on/off
PRNUNL EQU PRNMIC+1 ; Underline blanks on/off
PRNHMI EQU PRNUNL+1 ; Standard character width (in HMI units)
PRNVMI EQU PRNHMI+1 ; Standard line height (in VMI units)
CHRWID EQU PRNVMI+1 ; Character width (in HMI units)
ALTWID EQU CHRWID+1 ; Alternate pitch width (in HMI units)
SSROLL EQU ALTWID+1 ; Subscript/superscript roll (in VMI units)
LINEHT EQU SSROLL+1 ; Line height (in VMI units)
LFMAR EQU LINEHT+1 ; Left margin
RTMAR EQU LFMAR+1 ; Right margin
PPMAR EQU RTMAR+1 ; Number of tabs
TABS EQU PPMAR+1 ; Number of tabs
DECS EQU TABS+1+TABMAX ; Number of decimal tabs
POCW EQU DECS+1+DECMAX ; Page offset char width
HENCW EQU POCW+1 ; Header normal char width
HEACW EQU HENCW+1 ; Header alternate char width
FONCW EQU HEACW+1 ; Footer normal char width
FOACW EQU FONCW+1 ; Footer alternate char width
HELH EQU FOACW+1 ; Header line height
FOLH EQU HELH+1 ; Footer line height
PROP EQU FOLH+1 ; Proportional spacing
PAGNUM EQU PROP+1 ; Page number
PAGVMI EQU PAGNUM+2 ; VMI units of text on a page (minus margins)
VMICNT EQU PAGVMI+2 ; Current VMI count
TOPVMI EQU VMICNT+2 ; VMI units in top margin
BOTVMI EQU TOPVMI+2 ; VMI units in bottom margin
LNHITE EQU BOTVMI+2 ; LINEHT with MS byte zero
ALTPCH EQU LNHITE+2 ; Alternate pitch on/off
HEPROP EQU ALTPCH+1 ; Header proportional flag
HENLQ EQU HEPROP+1 ; Header NLQ
FOPROP EQU HENLQ+1 ; Footer proportional flag
FONLQ EQU FOPROP+1 ; Footer NLQ
SHTBIN EQU FONLQ+1 ; Sheet feeder bin
;
PAGE
;
; Print a Line
;
; On entry: HL points to start of a line of characters
; DE contains the number of characters in the line
; A contains the line type code & suppress printing
; flag (MSB of A is 1 to suppress)
;
; Type codes: 0 = line from body of text
; 1 = header line
; 2 = footer line
;
; On exit: A contains a return code
;
; Return code: 0 = done printing line
; 1 = not done printing, printer is busy
; 2 = pause required, operator should resume printing
;
PRINT:
SHLD PRCHAR ; Store pointer to current char
;
XCHG ; Store count
SHLD PRCOUNT
;
STA PRTYPE ; Store type code
ANI 7Fh
CPI 3 ; Dot command?
JZ PRINI1
;
PUSH PSW
LHLD PRTABLE ; Get page offset, space in before the
LXI D,PAGMAR ; next printing character
DAD D
MOV A,M
STA PROFST
;
MVI A,1
STA PRLEAD ; Leading blank flag
XRA A
STA PUNDBL ; Not underlining between words
;
POP PSW
LXI H,PRTYPX
MOV B,M
MOV M,A
CMP B
JZ PRIN9
;
ORA A ; Normal text line?
JZ PRIN8
;
LXI H,XTOGL+1 ; Clear header/footer attributes
MVI C,XTOGZ/2
XRA A
PRIN1: MOV M,A
INX H
INX H
DCR C
JNZ PRIN1
;
MVI A,1
PRIN8: MOV L,A ; Store print control offset
MVI H,0
SHLD PRTYPA
CALL PRLQAD ; No change in NLQ print?
LDA PRLQPR
CMP M
JZ PRIN9
;
MVI A,0FFh ; Change NLQ state
STA PRLQCH
PRIN9: LXI H,PRSTRT ; Not 1st printing line?
LDA PRTYPE
ORA M
JM PRESUME
;
MVI M,0FFH
;;; CALL PRBIN
JMP PRESUME
PAGE
;
; Resume Printing
;
; On exit: A contains a return code
;
; Return code: 0 = done printing line
; 1 = not done printing, printer is busy
; 2 = pause required, operator should resume printing
;
; Note that control must be returned to WordStar if the printer is
; busy so that the user may abort printing from the console.
; Therefore, you must not advance the character pointer or decrement
; the count until after the character has been printed (in case the
; printer is busy).
;
PRESUME:
LDA PRSSIZ ; Not printing string?
ORA A
JZ PRES4
;
MOV C,A
CALL LSOSTA ; Ready to print string size
LHLD PRSPTR
JNZ PRES3
;
PRES2: MOV A,C
CALL XSIZE ; Save size
MVI A,1
JMP PRRET
PRES3: MVI A,1
CALL LSOSTA
JZ PRES2
;
MOV A,M
CALL LSTOUT
INX H
DCR C
JNZ PRES3
;
XRA A
STA PRSSIZ
PRES4: LDA PR2ND ; No 2nd composite byte?
ORA A
JZ PRES6
;
CALL PRLO ; Not busy?
JNZ PRRET
;
PRES5: LXI H,PRCOLM ; Bump posn, no more 2nd char
INR M
XRA A
STA PR2ND
JMP PRESUME
;
PRES6: LXI H,PRFFL ; No form feed lines left?
MOV A,M
ORA A
JZ PRES7
;
DCR M
;
LXI H,$CRLF ; Print CRLF's to next page
JMP PRES17
;
PRES7: LDA PRLQCH ; No NLQ change?
ORA A
JZ PRES8
;
CALL PRLQ ; Change state
JMP PRESUME
;
PRES8: LHLD PRCOUNT ; Not done printing?
MOV A,H
ORA L
JNZ PRES9
;
CALL GETSIZ ; Get page size
JMP PRINI1
;
PRES9: LHLD PRCHAR
MOV A,M
CPI SOFTFF ; Not a soft form feed?
JNZ PRES11
;
LDA PRLINE ; Already at top of page?
ORA A
JZ PRSKIP
;
JMP PRFF ; Form feed
;
PRES11: MOV A,M ; 7 bit ASCII
ANI 7FH
;
LXI H,PRSPEC1 ; Scan special char table
MOV B,A
PRES12: MOV A,M ; End of table?
INX H
CPI 0FFH
JZ PRES13
;
CMP B
JZ PRES13
;
INX H
INX H
JMP PRES12
;
PRES13: MOV E,M ; Execute special character routine
INX H
MOV D,M
XCHG
MOV A,B
PCHL
;
PRES14: LDA PROFST ; No page offset left?
ORA A
JZ PRES15
;
CALL PREXOFF ; Not extended character
JNZ PRESUME
;
MVI A,' ' ; Print spaces to offset left side of page
CALL PRLO
JNZ PRRET
;
LXI H,PROFST
DCR M
JMP PRESUME
;
PRES15: LXI H,PRSPEC2 ; Check 2nd special char table
JMP PRES12
;
; Print character
;
PRES16: CPI DEL ; Ignore non printing char?
JZ PRSKIP
;
CPI ' '
JC PRSKIP
;
JNZ PRES19 ; Not a blank?
;
CALL PREMAIN ; Only blanks remaining, turn something off?
JNZ PRRET
;
LHLD PRTYPA ; Not underlining?
LXI D,XUNDER
DAD D
MOV A,M
MOV C,A
ANI 1
JZ PRES21
;
LHLD PRTABLE ; Continuous underlining?
LXI D,PRNUNL
DAD D
MOV A,M
ORA A
JNZ PRES21
;
LDA PUNDBL ; Underlining already off?
ANI 1
JNZ PRES21
;
MOV A,C
ORA A
JP PRES21
;
MVI A,1 ; Not underlining blanks
STA PUNDBL
;
LHLD PRTYPA ; Turn underlining off
LXI D,XUNDER
DAD D
MOV A,M
ANI 7FH
MOV M,A
;
LXI H,$PSOFF
PRES17: CALL XSTRNG
JMP PRESUME
;
PRES19: LDA PRLEAD ; Not the 1st non-blank
ANI 1
JZ PRES20
;
CALL PRON ; Not everything on?
JNZ PRESUME
;
PRES20: XRA A ; No longer leading blank
STA PRLEAD
;
LDA PUNDBL ; Not suppressing blank underline?
ANI 1
JZ PRES21
;
LHLD PRTYPA ; Already on?
LXI D,XUNDER
DAD D
MOV M,A
ORA A
JM PRES21
;
ORI 80h ; Turn underlining on
MOV M,A
XRA A ; Underlining a non-blank now
STA PUNDBL
;
LXI H,$PSON
JMP PRES17
;
PRES21: CALL PREXOFF ; Not extended char
JNZ PRESUME
;
PRE21A: MOV L,B ; Just print char (unless busy)
MVI H,0
LXI D,$COMPOS
DAD H
DAD D
MOV A,M
;
INX H ; 2nd composite char
MOV B,M
LXI H,PR2ND
MOV M,B
;
LXI H,PRCOLM
INR M
;
CALL PRLO ; Print
JNZ PRRET
;
MOV A,B ; Composite char?
ORA A
JNZ PRBS
;
PRSKIP: CALL PRNEXT ; Try another char
JNZ PRSKIP
JMP PRESUME
;
PRNEXT: PUSH H
PRNEX0: LHLD PRCHAR
INX H
SHLD PRCHAR
;
LHLD PRCOUNT ; Decrement count
DCX H
SHLD PRCOUNT
MOV A,H
ORA L
JZ PRNEX1
;
LXI H,PRNEXZ ; More than 1 byte?
DCR M
JNZ PRNEX0
;
PRNEX1: MVI A,1
STA PRNEXZ
POP H
RET
;
; Dispatch Tables for Special Characters
;
PRSPEC1:
DB CR
DW PRCRLF
DB SOFTCR
DW PRCRLF
DB LF
DW PRLF
DB SOFTLF
DW PRLF
DB FFEED
DW PRFF
DB 'C'-'@'
DW PRPAUS
DB -1
DW PRES14
;
; Special chars processed after page offset
;
PRSPEC2:
DB TAB
DW PRTAB
DB SOFTAB
DW PRTAB
DB SOFTBL
DW PRBLNK
DB 'O'-'@'
DW PRBIND
DB 'F'-'@'
DW PRPHBL
DB 'G'-'@'
DW PRPHRB
DB BS
DW PRBS
DB 'N'-'@'
DW PRNORM
DB 'A'-'@'
DW PRALT
DB 'B'-'@'
DW PRBOLD
DB 'D'-'@'
DW PRDBL
DB 'S'-'@'
DW PRUNDR
DB 'T'-'@'
DW PRSUPR
DB 'V'-'@'
DW PRSUB
DB 'X'-'@'
DW PRSTRK
DB 'Y'-'@'
DW PRITAL
DB HARDHY
DW PRDASH
DB SOFTHY
DW PRSKIP
DB 'Q'-'@'
DW PCUSQ
DB 'W'-'@'
DW PCUSW
DB 'E'-'@'
DW PCUSE
DB 'R'-'@'
DW PCUSR
DB ESC
DW PREXTN
DB -1
DW PRES16
;
PRCRLF: CALL PROFF ; Turning things off?
JNZ PRESUME
;
LHLD PRCOUNT ; No chars after CR?
MOV A,H
ORA L
JZ PRCR
;
LHLD PRCHAR ; LF after CR?
INX H
MOV A,M
CPI LF
JZ PRCRL1
CPI SOFTLF
JNZ PRCR
;
PRCRL1: CALL PRNEXT ; Skip CR
PRCRL2: XRA A
STA PRCOLM
LXI H,$CRLF
PRCRL3: LDA PRLINE
INR A
STA PRLINE
JMP PSTRNG
;
; Carriage return, no line feed
;
PRCR: CALL PROFF ; Turn things off?
JNZ PRESUME
;
LXI H,$CR
XRA A
STA PRCOLM
JMP PSTRNG
;
; Line feed
;
PRLF: CALL PROFF ; Turn things off?
JNZ PRESUME
;
LXI H,$HLF ; No half line feed string?
MOV A,M
ORA A
JZ PRCRL2
;
LDA PRHALF ; 2nd half line feed?
XRI 1
STA PRHALF
ORA A
JZ PRCRL3
;
JMP PRES17
;
; Binding space
;
PRBIND: LXI H,$CTRLO
JMP P1STRNG
;
; Phantom blank
;
PRPHBL: LXI H,$CTRLF
JMP P1STRNG
;
; Phantom rubout
;
PRPHRB: LXI H,$CTRLG
JMP P1STRNG
;
; Normal pitch
;
PRNORM: LXI H,$NORM
JMP PSTRNG
;
; Alternate pitch
;
PRALT: LXI H,$ALT
JMP PSTRNG
;
; Bold on/off
;
PRBOLD: LXI D,XBOLD
LXI B,$PBON
; Fall into PRTOGL
;
; Toggle something on/off
;
PRTOGL:
LHLD PRTYPA
DAD D
MOV A,M
XRI 1
MOV M,A
;
LDA PRLEAD ; Only leading blanks so far?
ANI 1
JNZ PRTOG3
;
MOV A,M ; Now on?
ANI 1
JNZ PRTOG1
;
MOV A,M ; Already off?
ORA A
JP PRTOG3
;
ANI 7FH ; Mark off
MOV M,A
LXI H,$SHORT ; Offset to OFF string
JMP PRTOG2
;
PRTOG1: MVI A,1 ; On now
STA PRONOFF
;
MOV A,M ; Already on?
ORA A
JM PRTOG3
;
ORI 80h
MOV M,A
LXI H,0 ; Normal string offset
PRTOG2: DAD B
JMP PSTRNG ; Send control sequence
;
PRTOG3: JMP PRSKIP ; Ignore until blanks are done
;
; Doublestrike on/off
;
PRDBL: LXI D,XDBL
LXI B,$PDON
JMP PRTOGL
;
; Underline on/off
;
PRUNDR: LXI D,XUNDER
LXI B,$PSON
XRA A
STA PUNDBL
JMP PRTOGL
;
; Superscript on/off
;
PRSUPR: LXI D,XSUPER
LXI B,$PTON
JMP PRTOGL
;
; Subscript on/off
;
PRSUB: LXI D,XSUB
LXI B,$PVON
JMP PRTOGL
;
; Strike-out on/off
;
PRSTRK: LXI D,XSTRIKE
LXI B,$PXON
JMP PRTOGL
;
; Italics on/off
;
PRITAL: LXI D,XITALIC
LXI B,$PYON
JMP PRTOGL
;
; Extended character
;
PREXTN: LHLD PRCHAR ; ESC xx BESC?
INX H
INX H
MOV M,A
CPI BESC
JNZ PRSKIP
;
MVI A,1 ; Need to send string 1st?
CALL PREXST
JNZ PRESUME
;
MVI A,3 ; Extended character
STA PRNEXZ
LHLD PRCHAR
INX H
MOV A,M
JMP PRE21A
;
; Tab character (09H)
;
PRTAB: ; Tab
CALL PREXOFF ; Not extended?
JNZ PRESUME
LDA PROFST
;
MVI A,' ' ; Try to print a blank
CALL PRLO
JNZ PRRET ; Busy
;
LDA PRCOLM ; Increment column
INR A
STA PRCOLM
;
LHLD PRTABLE ; Use tab mask to see if at next stop
LXI D,TBMASK
DAD D
ANA M
JNZ PRTAB
JMP PRSKIP
;
PRFF: ; Form feed
CALL PROFF ; Turn things off
JNZ PRRET ; Busy
;
LDA PRFFOK ; Can't use form feeds?
ORA A
JZ PRFF1
;
LXI H,@USRFF
CALL USTRAD
MOV A,M
ORA A
JNZ PRFF0
;
LXI H,$FF
PRFF0: CALL XSTRNG
JMP PRFF2
;
PRFF1: LXI H,PRLINE ; Determine remaining lines on page
LDA PRPGSZ
SUB M
JC PRFF2
;
STA PRFFL
PRFF2: XRA A ; Top of page
STA PRLINE
STA PRCOLM
JMP PRSKIP
;
; Backspace
;
PRBS: LXI H,PRCOLM ; At left stop?
MOV A,M
ORA A
JZ PRSKIP
;
DCR M ; Back up
LXI H,$BS ; Backspace string
JMP PSTRNG
;
; Pause in mid-text
;
PRPAUS: CALL PRNEXT
LDA PRTYPE ; Inhibit printing?
ORA A
JM PRESUME
;
MVI A,2 ; Return code 2
ORA A
RET
;
PRBLNK: ; Convert to a blank
MVI B,' '
JMP PRES4
;
PRDASH:
MVI B,'-' ; Hard Hyphen
JMP PRES4
;
PCUSQ: LXI H,@USRQ
JMP USTRNG
;
PCUSW: LXI H,@USRW
JMP USTRNG
;
PCUSE: LXI H,@USRE
JMP USTRNG
;
PCUSR: LXI H,@USRR
JMP USTRNG
;
; Send NLQ print status
;
PRLQ: XRA A
STA PRLQCH
CALL PRLQAD
MOV A,M
STA PRLQPR
;
LXI H,$LQON
ANI 1
JNZ XSTRNG
;
LXI H,$LQOFF
JMP XSTRNG
;
PRLQAD:
LHLD PRTABLE
LXI D,PRNNLQ
DAD D
RET
;
; Check extended character status
;
PREXOFF:
XRA A ; Not an extended character
;
PREXST:
LXI H,PREXTX ; No change?
CMP M
RZ
;
MOV M,A ; New state
ORA A
;
LXI H,$BIDON
ORA A
JNZ PREXS1
;
LXI H,$BIDOFF
PREXS1: CALL XSTRNG
LDA PRSSIZ ; Any string?
ORA A
RET
;
; Table of on/off strings
;
PRPRCTL:
DW XBOLD,$PBON
DW XDBL,$PDON
DW XUNDER,$PSON
DW XSUPER,$PTON
DW XSUB,$PVON
DW XSTRIKE,$PXON
DW XITALIC,$PYON
DW 0
;
; Turn print controls on or off
;
; on exit: Z if all done, NZ if string pending
; B = $
;
PRON:
MVI C,0 ; Offset to ON string
MVI A,1 ; On
JMP PRO0
;
PROFF:
CALL PREXOFF ; Extended chars off
RNZ
;
MVI C,$SHORT ; Offset to OFF string
XRA A ; Off
;
PRO0: LXI H,PRONOFF
CMP M
JZ PRO6
;
LXI H,PRPRCTL
PRO1: MOV E,M ; Get attr address
INX H
MOV D,M
INX H
MOV A,D ; End of table?
ORA E
JZ PRO5
;
PUSH H ; Get current attr state
LHLD PRTYPA
DAD D
MOV A,M
ANI 1
JZ PRO2A ; Off?
;
MOV A,C ; 0 if turning on
ORA A
JZ PRO3
;
MOV A,M ; Already off?
ORA A
JP PRO2A
;
ANI 7Fh
JMP PRO4
PRO2A: POP H
INX H
INX H
JMP PRO1
;
; Turning on
;
PRO3: MOV A,M ; Already on?
ORA A
JM PRO2A
;
ORI 80H ; Mark on
;
PRO4: MOV M,A ; New state
POP H ; Get pointer to string
MOV E,M
INX H
MOV D,M
INX H
XCHG
PUSH B
MVI B,0
DAD B ; Add on/off offset
POP B
CALL XSTRNG ; AL = 1 from XSTRNG
RET
;
PRO5: LXI H,PRONOFF ; Change on/off state
MOV A,M
XRI 1
MOV M,A
PRO6: XRA A ; Z
RET
;
; Abort Printing
;
PRABORT:
MVI A,CR ; Print a final CRLF
CALL PRLOWT
MVI A,LF
CALL PRLOWT
JMP PRRET
PAGE
;
; Uninitialize Printing
;
PRUNITZ:
LXI H,PRUNI1 ; One last form feed
LXI D,1
XRA A
CALL PRINT
PRUNI0: ORA A
RZ
CALL PRESUME
JMP PRUNI0
;
PRUNI1: DB SOFTFF ; Form feed only if not already top of page
PAGE
;
; Check if only blanks remain on line
;
; on exit: NZ if string to be printed
;
PREMAIN:
LDA PRLEAD ; Leading blank?
ANI 1
JNZ PREMA3
;
LHLD PRCOUNT
XCHG
LHLD PRCHAR
JMP PREMA2
;
PREMA1: INX H
MOV A,M
ANI 7FH
CPI SOFTHY ; Control char?
JC PREMA2
;
CPI ' '
JZ PREMA2
;
CPI SOFTBL
JZ PREMA2
;
CPI SOFTCR
JZ PREMA2
;
CPI SOFTLF
JNZ PREMA3
;
PREMA2: DCX D ; More?
MOV A,D
ORA E
JNZ PREMA1
;
JMP PROFF ; Turn everything off
;
PREMA3: XRA A ; Z no string
RET
;
; Get page size
;
GETSIZ: PUSH H
PUSH D
LHLD PRTABLE
LXI D,PAGSIZ
DAD D
MOV A,M
STA PRPGSZ
POP D
POP H
RET
;
; Set up to print string at BX
;
XSTRNG:
PUSH H
LDA PRTYPE ; Printing suppressed?
ORA A
JM XSTRN3
;
XSTRN1: MOV A,M ; No redirection?
INX H
CPI -1
JNZ XSTRN2
;
PUSH D
MOV E,M
INX H
MOV D,M
XCHG
POP D
JMP XSTRN1
;
XSTRN2: CALL XSIZE
XSTRN3: POP H
XRA A
INR A ; NZ, AL = 1
RET
;
; Store pointer to string to be printed
;
; on entry: HL -> string
; A = length;
XSIZE:
SHLD PRSPTR
STA PRSSIZ
RET
;
; Print string at BX
;
P1STRNG:
LDA PRCOLM
INR A
STA PRCOLM
PSTRNG: CALL XSTRNG
JMP PRSKIP
;
USTRNG: CALL USTRAD
JMP PSTRNG
;
USTRAD: PUSH D
XCHG
LHLD PRUSER
DAD D
POP D
RET
;
; Print a Character
;
; On entry: A contains character to be printed
;
; On exit: A is zero if printed, 1 if busy
;
PRLO:
PUSH B
MOV B,A ; Save char to B
;
LDA PRTYPE ; Printing being suppressed?
ORA A
JM PRL2
;
MVI C,10 ; Go through busy loop up to 10 times
;
PRL0: CALL LSOSTA ; Printer ready for a char?
JNZ PRL1
;
DCR C ; One more time
JNZ PRL0
;
POP B ; Return a 1 since busy
XRA A
INR A ; (Set Z flag too)
RET
;
PRL1: MOV A,B ; Print char
CALL LSTOUT
;
PRL2: POP B ; Return a zero
XRA A
RET
;
; Print a Character if Possible
;
; On entry: A contains char to be printed
;
; On exit: Char printed if possible
;
PRLOWT:
LXI H,1000 ; Wait a while for printer to be not busy
MOV B,A
PRLOW0: MOV A,B ; Try printing it
CALL PRLO
RZ
;
DCX H ; Another try?
MOV A,H
ORA L
JNZ PRLOW0
RET
PRRET: RET
PGLEN EQU $-PGORG
PAGE
;
; Driver Variables
;
DATORG:
;
PRCHAR: DS 2 ; Pointer to current char
PRCOUNT:DS 2 ; Char count
PRTYPE: DS 1 ; Type of line
PRTYPX: DS 1 ; Prev line type
PRTYPA: DS 2 ; Offset to print control toggles
;
PRSPTR: DS 2 ; Pointer to string to print
PRSSIZ: DS 1 ; Length
;
PRLINE: DS 1 ; Current line number
PRCOLM: DS 1 ; Current print column
PROFST: DS 1 ; Page offset counter
PRLEAD: DS 1 ; Leading blank flag
PRPGSZ: DS 1 ; Page size
;
PRTABLE:DS 2 ; Pointer to WordStar table
PRUSER: DS 2 ; Pointer to user area strings
;
PRLQPR: DS 1 ; Last NLQ print state
PRLQCH: DS 1 ; Change NLQ state
;
PREXTX: DS 1 ; Extended character state
;
PRFFOK: DS 1 ; Form feed okay flag
PRFFL: DS 1 ; CRLF counter
PRHALF: DS 1 ; Half line feed counter
PRNEXZ: DS 1 ; Character size
PR2ND: DS 1 ; Second composed character
;
PRONOFF: DS 1 ; Print controls on/off flag
;
PUNDBL: DS 1 ; Underlining blanks flag
;
PRSTRT: DS 1 ; Printing started flag
;
; Print Control Toggles
;
; Byte for current state, regular text
;
XTOGL:
XBOLD: DS 2
XDBL: DS 2
XUNDER: DS 2
XSUPER: DS 2
XSUB: DS 2
XSTRIKE: DS 2
XITALIC: DS 2
XTOGZ EQU ($-XTOGL)
DATLEN EQU $-DATORG ; Length of uninitialized data
PDLEN EQU $-PGORG ; Driver length
PAGE
$ORG:
;
; String allocation macro
;
STRNG MACRO STROFF
STPAD SET STROFF-$
IF STPAD AND 0F000H
.PRINTX /**** STRING LENGTH ERROR ****/
ENDIF
IF STPAD GT 0
DS STPAD
ENDIF
ENDM
;
BTSUPR EQU 1 ; Superscript
BTSUB EQU 2 ; Subscript
BTCOLR EQU 4 ; Italics/red
BTALT EQU 8 ; Alternate width
BTUNDR EQU 10H ; Underlining
BTSTRK EQU 20H ; Strikeout
BTEXT EQU 40H ; Extended character set
BTNLQ EQU 80H ; Near letter quality
BTPROP EQU 100H ; Proportional
BTBOLD EQU 200H ; Boldface
BTDBL EQU 400H ; Doublestrike
BTENH EQU 800H ; Enhanced (alternate mode boldface)
BTCOND EQU 1000H ; Condensed (needs special pass)
BTCOMP EQU 2000H ; Printer composed character
BSS EQU BTSUPR+BTSUB
;
; Offsets to custom strings in user area
;
@USRQ EQU 0
@USRW EQU 25
@USRE EQU 50
@USRR EQU 75
@STRK EQU 100
@USRFF EQU 101
;
; Offsets into strings and flags
;
$SHORT EQU 10 ; Short string length
$LONG EQU 25 ; Long string length
;
$INIT EQU $ORG+7
$UNINT EQU $INIT+$LONG
$ABORT EQU $UNINT+$LONG
$CRLF EQU $ABORT+$LONG
$CR EQU $CRLF+$SHORT
$FF EQU $CR+$SHORT
$HLF EQU $FF+$SHORT
$BS EQU $HLF+$SHORT
$NORM EQU $BS+$SHORT
$ALT EQU $NORM+$SHORT
$CTRLF EQU $ALT+$SHORT
$CTRLG EQU $CTRLF+$SHORT
$CTRLO EQU $CTRLG+$SHORT
$PBON EQU $CTRLO+$SHORT
$PBOFF EQU $PBON+$SHORT
$PDON EQU $PBOFF+$SHORT
$PDOFF EQU $PDON+$SHORT
$PSON EQU $PDOFF+$SHORT
$PSOFF EQU $PSON+$SHORT
$PTON EQU $PSOFF+$SHORT
$PTOFF EQU $PTON+$SHORT
$PVON EQU $PTOFF+$SHORT
$PVOFF EQU $PVON+$SHORT
$PXON EQU $PVOFF+$SHORT
$PXOFF EQU $PXON+$SHORT
$PYON EQU $PXOFF+$SHORT
$PYOFF EQU $PYON+$SHORT
$BIDON EQU $PYOFF+$SHORT
$BIDOFF EQU $BIDON+$SHORT
$LQON EQU $BIDOFF+$SHORT
$LQOFF EQU $LQON+$SHORT
$BOLD EQU $LQOFF+$SHORT
$DOUBLE EQU $BOLD+1
$COMPOS EQU $DOUBLE+1
$SYMTAB EQU $COMPOS+512
;
; Name of driver
;
DB 'SIMPLE'
DB 0
;
; Control strings
;
STRNG $INIT
DB 1,CR
STRNG $UNINT
DB 1,CR
STRNG $ABORT
DB 2,CR,FFEED
STRNG $CRLF
DB 2,CR,LF
STRNG $CR
DB 1,CR
STRNG $FF
DB 1,FFEED
STRNG $HLF
DB 0
STRNG $BS
DB 1,08h
STRNG $NORM
DB 0
STRNG $ALT
DB 0
STRNG $CTRLF
DB 1,' '
STRNG $CTRLG
DB 1,' '
STRNG $CTRLO
DB 1,' '
STRNG $PBON
DB 0
STRNG $PBOFF
DB 0
STRNG $PDON
DB 0
STRNG $PDOFF
DB 0
STRNG $PSON
DB 0
STRNG $PSOFF
DB 0
STRNG $PTON
DB 0
STRNG $PTOFF
DB 0
STRNG $PVON
DB 0
STRNG $PVOFF
DB 0
STRNG $PXON
DB 0
STRNG $PXOFF
DB 0
STRNG $PYON
DB 0
STRNG $PYOFF
DB 0
STRNG $BIDON
DB 0
STRNG $BIDOFF
DB 0
STRNG $LQON
DB 0
STRNG $LQOFF
DB 0
STRNG $BOLD
DB 3
STRNG $DOUBLE
DB 2
STRNG $COMPOS
;
; Table of composite characters
; entry indexed by WordStar character value
; first byte = printing character or null
; second byte = overstruck character or null
;
; This table is set up for a simple ASCII printer, emulating
; an IBM character set 2.
;
UNK EQU '?'
COMPOS: DB UNK,0 ; 0
DB UNK,0 ; 1
DB UNK,0 ; 2
DB UNK,0 ; 3, heart
DB UNK,0 ; 4, diamond
DB UNK,0 ; 5, club
DB UNK,0 ; 6, spade
DB UNK,0 ; 7
DB UNK,0 ; 8
DB UNK,0 ; 9
DB UNK,0 ; A
DB UNK,0 ; B
DB UNK,0 ; C
DB UNK,0 ; D
DB UNK,0 ; E
DB UNK,0 ; 0F
;
DB UNK,0 ; 10
DB UNK,0 ; 11
DB UNK,0 ; 12
DB UNK,0 ; 13
DB 'PI' ; 14, paragraph symbol
DB 'So' ; 15, section mark
DB UNK,0 ; 16
DB UNK,0 ; 17
DB UNK,0 ; 18
DB UNK,0 ; 19
DB '->' ; 1A, right arrow
DB UNK,0 ; 1B
DB UNK,0 ; 1C
DB UNK,0 ; 1D
DB UNK,0 ; 1E
DB UNK,0 ; 1F
;
DB ' ',0 ; 20 blank
DB '!',0 ; 21
DB '"',0 ; 22
DB '#',0 ; 23
DB '$',0 ; 24
DB '%',0 ; 25
DB '&',0 ; 26
DB "'",0 ; 27
DB '(',0 ; 28
DB ')',0 ; 29
DB '*',0 ; 2A
DB '+',0 ; 2B
DB ',',0 ; 2C
DB '-',0 ; 2D
DB '.',0 ; 2E
DB '/',0 ; 2F
;
DB '0',0 ; 30
DB '1',0 ; 31
DB '2',0 ; 32
DB '3',0 ; 33
DB '4',0 ; 34
DB '5',0 ; 35
DB '6',0 ; 36
DB '7',0 ; 37
DB '8',0 ; 38
DB '9',0 ; 39
DB ':',0 ; 3A
DB ';',0 ; 3B
DB '<',0 ; 3C
DB '=',0 ; 3D
DB '>',0 ; 3E
DB '?',0 ; 3F
;
DB '@',0 ; 40
DB 'A',0 ; 41
DB 'B',0 ; 42
DB 'C',0 ; 43
DB 'D',0 ; 44
DB 'E',0 ; 45
DB 'F',0 ; 46
DB 'G',0 ; 47
DB 'H',0 ; 48
DB 'I',0 ; 49
DB 'J',0 ; 4A
DB 'K',0 ; 4B
DB 'L',0 ; 4C
DB 'M',0 ; 4D
DB 'N',0 ; 4E
DB 'O',0 ; 4F
;
DB 'P',0 ; 50
DB 'Q',0 ; 51
DB 'R',0 ; 52
DB 'S',0 ; 53
DB 'T',0 ; 54
DB 'U',0 ; 55
DB 'V',0 ; 56
DB 'W',0 ; 57
DB 'X',0 ; 58
DB 'Y',0 ; 59
DB 'Z',0 ; 5A
DB '[',0 ; 5B
DB '\',0 ; 5C
DB ']',0 ; 5D
DB '^',0 ; 5E
DB '_',0 ; 5F
;
DB '`',0 ; 60
DB 'a',0 ; 61
DB 'b',0 ; 62
DB 'c',0 ; 63
DB 'd',0 ; 64
DB 'e',0 ; 65
DB 'f',0 ; 66
DB 'g',0 ; 67
DB 'h',0 ; 68
DB 'i',0 ; 69
DB 'j',0 ; 6A
DB 'k',0 ; 6B
DB 'l',0 ; 6C
DB 'm',0 ; 6D
DB 'n',0 ; 6E
DB 'o',0 ; 6F
;
DB 'p',0 ; 70
DB 'q',0 ; 71
DB 'r',0 ; 72
DB 's',0 ; 73
DB 't',0 ; 74
DB 'u',0 ; 75
DB 'v',0 ; 76
DB 'w',0 ; 77
DB 'x',0 ; 78
DB 'y',0 ; 79
DB 'z',0 ; 7A
DB '{',0 ; 7B
DB '|',0 ; 7C
DB '}',0 ; 7D
DB '~',0 ; 7E
DB UNK,0 ; 7F
;
DB 'C,' ; 80 c,
DB 'u~' ; 81 u umlaut
DB "e'" ; 82 e'
DB 'a^' ; 83 a^
DB 'a~' ; 84 a umlaut
DB 'a`' ; 85 a`
DB 'a[' ; 86 a ring
DB 'c,' ; 87 c,
DB 'e^' ; 88 e^
DB 'e~' ; 89 e umlaut
DB 'e`' ; 8A e`
DB 'i~' ; 8B i umlaut
DB 'i^' ; 8C i^
DB 'i`' ; 8D i`
DB 'A~' ; 8E A umlaut
DB 'A[' ; 8F A ring
;
DB "E'" ; 90 E'
DB 'ae' ; 91 ae
DB 'AE' ; 92 AE
DB 'o^' ; 93 o^
DB 'o~' ; 94 o umlaut
DB 'o`' ; 95 o`
DB 'u^' ; 96 u^
DB 'u`' ; 97 u`
DB 'y~' ; 98 y umlaut
DB 'O~' ; 99 O umlaut
DB 'U~' ; 9A U umlaut
DB 'c|' ; 9B cent symbol
DB 'L-' ; 9C British pound
DB 'Y-' ; 9D Japanese yen
DB 'Pt' ; 9E Spanish peseta
DB 'S-' ; 9F curly f
;
DB "a'" ; A0 a'
DB "i'" ; A1 i'
DB "o'" ; A2 o'
DB "u'" ; A3 u'
DB 'n~' ; A4 n~
DB 'N~' ; A5 N~
DB 'a_' ; A6 a_
DB 'o_' ; A7 o_
DB '?',0 ; A8 upside down ?
DB '/',0 ; A9 upper left corner
DB '\',0 ; AA upper right corner
DB '12' ; AB 1/2
DB '14' ; AC 1/4
DB '!',0 ; AD upside down !
DB '<<' ; AE <<
DB '>>' ; AF >>
;
DB 'HI' ; B0 1/4 density block
DB 'HX' ; B1 1/3 density block
DB 'H*' ; B2 1/2 density block
DB '|',0 ; B3 single vertical
DB '|',0 ; B4 right vertical -| 1V 1H
DB '|',0 ; B5 right vertical =| 1V 2H
DB '|',0 ; B6 right vertical -|| 2V 1H
DB '\',0 ; B7 upper right 2V 1H
DB '\',0 ; B8 upper right 1V 2H
DB '|',0 ; B9 right vertical =|| 2V 2H
DB '|',0 ; BA double vertical
DB '\',0 ; BB upper right 2V 2H
DB '/',0 ; BC bottom right 2V 2H
DB '/',0 ; BD bottom right 2V 1H
DB '/',0 ; BE bottom right 1V 2H
DB '\',0 ; BF uppper right 1V 1H
;
DB '\',0 ; C0 bottom left 1V 1H
DB '-',0 ; C1 bottom 1V 1H
DB '-',0 ; C2 top 1V 1H
DB '|',0 ; C3 left 1V 1H
DB '-',0 ; C4 horizontal 1H
DB '-|' ; C5 cross 1V 1H
DB '|',0 ; C6 left 1V 2H
DB '|',0 ; C7 left 2V 1H
DB '\',0 ; C8 bottom left 2V 2H
DB '/',0 ; C9 top left 2V 2H
DB '-',0 ; CA bottom 2V 2H
DB '-',0 ; CB top 2V 2H
DB '|',0 ; CC left 2V 2H
DB '-',0 ; CD horizontal 2H
DB '-|' ; CE cross 2V 2H
DB '-',0 ; CF bottom 1V 2H
;
DB '-',0 ; D0 bottom 2V 1H
DB '-',0 ; D1 top 1V 2H
DB '-',0 ; D2 top 2V 1H
DB '\',0 ; D3 bottom left 2V 1H
DB '\',0 ; D4 bottom left 1V 2H
DB '/',0 ; D5 top left 1V 2H
DB '/',0 ; D6 top left 2V 1H
DB '-|' ; D7 cross 2V 1H
DB '-|' ; D8 cross 1V 2H
DB '/',0 ; D9 bottom right 1V 1H
DB '/',0 ; DA top left 1V 1H
DB 'H*' ; DB solid block
DB 'mw' ; DC solid bottom half
DB '|',0 ; DD solid left half
DB '|',0 ; DE solid right half
DB '~^' ; DF solid top half
;
DB 'a',0 ; E0 alpha
DB 'B,' ; E1 beta
DB 'g',0 ; E2 gamma
DB 'n-' ; E3 pi
DB 'E',0 ; E4 epsilon
DB 'r',0 ; E5 rho
DB 'u.' ; E6 mu
DB 't',0 ; E7 tau
DB 'oI' ; E8 oI
DB 'O-' ; E9 O-
DB 'n_' ; EA ohm
DB 's',0 ; EB sigma
DB 'o|' ; EC o|
DB 'O/' ; ED O/
DB 'E',0 ; EE round E
DB 'n',0 ; EF inverted U
;
DB '=_' ; F0 =_
DB '+_' ; F1 +_
DB '>_' ; F2 >_
DB '<_' ; F3 <_
DB 'f',0 ; F4 upper integral
DB 'j',0 ; F5 lower integral
DB '-:' ; F6 divide by
DB '~-' ; F7 ~_
DB 'o',0 ; F8 degree
DB '.',0 ; F9 high .
DB '-',0 ; FA short -
DB 'v-' ; FB v- divide by
DB 'n',0 ; FC superscript n
DB '2',0 ; FD superscript 2
DB "'`" ; FE small centered block
DB UNK,0 ; FF not used
STRNG $SYMTAB
;
; Symbol table
;
; WORD symbol count
; REPEAT 6 BYTES symbol name
; WORD symbol address
; WORD symbol storage size
;
DW SYMCNT
;
DB 'DATA ' ; All strings and tables
DW $ORG
DW $LEN
;
DB '$START' ; Initialize string
DW $INIT
DW $LONG
;
DB '$DONE ' ; Uninitialize string
DW $UNINT
DW $LONG
DB '$QUIT ' ; Abort string
DW $ABORT
DW $LONG
DB 'CRLF '
DW $CRLF
DW $SHORT
DB 'CRET '
DW $CR
DW $SHORT
DB '$FFEED'
DW $FF
DW $SHORT
DB 'HALFLF'
DW $HLF
DW $SHORT
DB 'BACKSP'
DW $BS
DW $SHORT
DB 'NORMWD'
DW $NORM
DW $SHORT
DB 'ALTRWD'
DW $ALT
DW $SHORT
DB 'PHSP '
DW $CTRLF
DW $SHORT
DB 'PHRUB '
DW $CTRLG
DW $SHORT
DB 'BINDSP'
DW $CTRLO
DW $SHORT
DB 'BLDON '
DW $PBON
DW $SHORT
DB 'BLDOFF'
DW $PBOFF
DW $SHORT
DB 'DBLON '
DW $PDON
DW $SHORT
DB 'DBLOFF'
DW $PDOFF
DW $SHORT
DB 'UNDON '
DW $PSON
DW $SHORT
DB 'UNDOFF'
DW $PSOFF
DW $SHORT
DB 'SPRON '
DW $PTON
DW $SHORT
DB 'SPROFF'
DW $PTOFF
DW $SHORT
DB 'SUBON '
DW $PVON
DW $SHORT
DB 'SUBOFF'
DW $PVOFF
DW $SHORT
DB 'STKON '
DW $PXON
DW $SHORT
DB 'STKOFF'
DW $PXOFF
DW $SHORT
DB 'ITLON '
DW $PYON
DW $SHORT
DB 'ITLOFF'
DW $PYOFF
DW $SHORT
DB 'EXTON '
DW $BIDON
DW $SHORT
DB 'EXTOFF'
DW $BIDOFF
DW $SHORT
DB 'NLQON '
DW $LQON
DW $SHORT
DB 'NLQOFF'
DW $LQOFF
DW $SHORT
DB 'COMPOS'
DW $COMPOS
DW 512
;
DB 'CODE ' ; Model 1 code
DW PGORG
DW PGLEN
SYMCNT EQU ($-$SYMTAB)/10
$LEN EQU $-$ORG
END