home *** CD-ROM | disk | FTP | other *** search
- TITLE FXDRVR: A Special WordStar Font Driver
- ;
- ;
- ; FXDRVR: A Special Font Driver for WordStar and the Epson FX-80
- ;
- ; Copyright (c) 1982, 1983, 1984 by Paul J. Gans. This version of
- ; FXDRVR.MAC is hereby placed into public domain. Permission
- ; is granted to SIG/M to distribute this file freely for non-
- ; commercial personal use only.
- ;
- ;
- ; Revision Record:
- ;
- ; Version 1.0 January 15, 1982 Original version.
- ; 2.0 January 19, 1982 Auto program load added.
- ; 2.1 September 17, 1982 Emphasized graphics added.
- ; 2.2 January 19, 1983 Updated to work with Epson
- ; Graphtrax Plus ROMs.
- ; 3.0 December 19, 1984 Name changed to FXDRVR, Down-
- ; load font used instead of
- ; graphics.
- ;
- ; The current version is 3.0.0 of 12/19/1984.
- ;
- PAGE 58
- ;
- ; This is a special font driver for WordStar. It allows the user to
- ; print special characters in a WordStar document on an Epson FX-80.
- ; This is done by making use of the FX-80's ability to accept a user-
- ; defined character set. Included with this font driver is a set of
- ; greek upper and lower case characters and some special mathematical
- ; symbols.
- ;
- ; Before this program can be used with WordStar, WordStar must be prop
- ; erly set up to match the assumptions made by this program. Configur
- ; ation instructions for WordStar are given in the file FXDRVR.DOC.
- ;
- ; This program is designed to be assembled with Microsoft's M80 assem
- ; bler and follows the conventions of that program. This assembler was
- ; chosen because most of the code below is designed to be executed at an
- ; address other than that into which it will be loaded by CP/M. A
- ; suitable command sequence to assemble and link this program is:
- ;
- ; >M80 =FXDRVR/L <== the /L produces a .PRN file,
- ; omit it if not desired.
- ;
- ; >L80 FXDRVR,FXDRVR/N/E
- ;
- ; After FXDRVR has been assembled and converted to a .COM file, the
- ; character set to be downloaded must be appended to it. The file con
- ; taining this character set must meet the assumptions of the program.
- ; The character set must contain 12 byte character definitions as
- ; specified in the Epson FX-80 manual. They may start at an arbitrary
- ; character position (as defined by the FFCHAR equate below) and may end
- ; at an arbitrary character position (as defined by the LFCHAR equate
- ; below). All characters between the first and last character inclusive
- ; MUST be present in the font. Any or all of the characters may be
- ; blank; many of the characters are blank in the set included here.
- ;
- ; The character set file is appended to the font driver at its very end.
- ; To make it easier to find the end of FXDRVR, a line of 16 asterisks
- ; has been placed at the end of the program. The first 16 bytes of the
- ; download font should overlay the asterisks.
- ;
- ;
- ; The action of the driver is simple. A set of control codes, presently
- ; the numbers 81H through 86H, cause the driver to instruct the Epson
- ; FX-80 to enter one or another of its printing modes. Control codes
- ; are:
- ;
- ; 81H downloaded font mode
- ; 82H italic mode
- ; 83H emphasized mode
- ; 84H condensed mode
- ; 85H elite mode
- ; 86H double strike mode
- ;
- ; These control codes are sent by WordStar when the appropriate special
- ; characters are typed into a document by the user. Just how these
- ; special characters are mapped into control codes is set by user cust-
- ; omization of the printer area of WordStar. A possible mapping is:
- ;
- ; ^A Enter elite mode
- ; ^N Leave elite mode
- ; ^W Toggle italic mode
- ; ^E Toggle emphasized mode
- ; ^R Toggle condensed mode
- ; ^Y Toggle MX-80 double strike mode
- ; ^Q Used downloaded font for next character
- ;
- ; It is suggested that condensed mode (the ^R toggle) not be used in new
- ; documents as future versions of this program may use the ^R toggle for
- ; other purposes.
- ;
- ; When the alternate font signal (^Q) is recognized in the output from
- ; WordStar, FXDRVR outputs the control codes sequence 0x1b 0x25 0x01
- ; 0x00. This puts the FX-80 into alternate character set mode (the
- ; downloaded set). FXDRVR then accepts exactly one more character from
- ; WordStar, transmits it to the FX-80, and then transmits the code
- ; sequence 0x1b, 0x25, 0x00, 0x00 to the FX-80. This last code sequence
- ; returns the FX-80 to the normal character set.
- ;
- ; The other mode codes function as toggles. Initially all modes are
- ; off. When a mode code is recognized in the input character stream,
- ; the corresponding mode is toggled. That is, if it was off, it is now
- ; turned on and vice versa. When a mode is changed, the corresponding
- ; string of bytes to perform that action is sent to the printer by the
- ; driver program.
- ;
- ; The driver appears to the user as a normal .COM file. It is invoked
- ; as:
- ;
- ; FXDRVR wsname [filename.ext]
- ;
- ; where wsname is the name of the WordStar file. and filename.ext is an
- ; optional file name. The special driver relocates itself in upper
- ; memory and patches itself into the normal BIOS call table. It will
- ; then look for and load WordStar under the name WS.COM, first searching
- ; the default disk and then, if not found, the A drive. Execution will
- ; then be turned over to WordStar, which will then work in a normal
- ; fashion, loading filename.ext as a D mode file for editing if it is
- ; specified.
- ;
- ; When WordStar finishes, it will return control to the driver which
- ; will reset all pointers and memory locations that it changed, thus
- ; restoring those locations to their original state. FXRVR ends with a
- ; return statement.
- ;
- ;
- ; Technical notes:
- ;
- ; There is nothing special about the font downloaded to the printer.
- ; The font can be edited, or other fonts created, with nothing more than
- ; the information provided by Epson in the FX-80 User's manual.
- ;
- ; This program has gone through a number of versions. Versions 1 and 2
- ; were written for the Epson MX-80 with Graphtrax. Changes were needed
- ; from time to time as the codes used to control various printer func
- ; tions have sometimes changed as Epson has changed the Graptrax ROMs.
- ;
- ; The current version has been greatly restructured to take advantage of
- ; the downloadable character set feature of the Epson FX-80. Previous
- ; versions used the graphics capability of the MX-80; this version uses
- ; a true character set.
- ;
- ;-----------------------------------------------------------------------------
- ;
- .Z80
- ;
- ; The definitions below should be changed to accomodate differing font
- ; sizes. FFCHAR is the decimal or hex equivalent of the first character
- ; to be downloaded, LFCHAR is the decimal or hex equivalent of the last
- ; character to be downloaded.
- ;
- FFCHAR EQU 000H ;First font character
- LFCHAR EQU 0FFH ;Last font character
- ;
- FSIZE EQU 12*(LFCHAR + 1 - FFCHAR) ;Font size
- DCOUNT EQU FSIZE + 5 ;Font size plus Epson codes
- ;
- FALSE EQU 0
- TRUE EQU NOT FALSE
- ;
- LF EQU 0AH ;Line feed
- CR EQU 0DH ;Carriage return
- ESCAPE EQU 1BH ;Escape
- SPACE EQU 20H ;Space
- ;
- INCHR EQU 01H ;CP/M character input
- OUTCHR EQU 02H ;CP/M character output
- PCHAR EQU 05H ;CP/M character print
- DSTRNG EQU 09H ;CP/M display string at console
- CHRW EQU 0BH ;CP/M character waiting
- OPEN EQU 0FH ;CP/M open file
- READ EQU 14H ;CP/M sequential read
- SETDMA EQU 1AH ;CP/M set DMA function
- ;
- LENTRY EQU 05H ;BIOS list function entry number
- ;
- WBOOT EQU 0000H ;Normal warm boot entry point
- OPSYS EQU 0005H ;CP/M call location
- TPATOP EQU 0006H ;Where TPA top address is stored
- FCB EQU 005CH ;Default file control block
- FCB2 EQU 006CH ;Secondary file control block
- BUFFER EQU 0080H ;Input command line buffer
- TBASE EQU 0100H ;Normal program load address
- ;
- CCBASE EQU 80H ;Control codes lie exclusively
- CCLAST EQU 87H ; between CCBASE and CCLAST
- ;
- LENGTH EQU FIN-HMC+1 ;Length of code to relocate
- ;
- ;
- ASEG
- ORG 100H
- ;
- ; First we display a logo.
- ;
- START: LD SP,STACK ;Plan ahead, use a stack!
- LD DE,SIGNON ;Now for a short message
- LD C,DSTRNG ; from our sponsor...
- CALL OPSYS
- JR DOWNL
- ;
- SIGNON: DB 'The Special Graphics Driver '
- DB CR,LF
- DB 'Version 3.0 (c) 1982, 1983, 1984 by '
- DB 'Paul J. Gans'
- DB CR,LF
- DB 'All Commercial Rights Reserved.'
- DB CR,LF,'$'
- ;
- ; The next thing to do is to download the user-definable character set.
- ; FXDRVR expects this set to be appended to the end of this program,
- ; starting at location FONT. There should be exactly 3077 bytes at that
- ; location, the first five of which are 0x1b, 0x26, 0x00, 0x00, 0xff,
- ; which tell the FX-80 that 3072 bytes, 256 character code at 12 bytes
- ; per character, are to be downloaded.
- ;
- DOWNL: LD BC,DCOUNT ;Set up a counter
- LD HL,FONT ;Source of bytes
- ;
- DOWN1: PUSH BC ;Save counters and address
- PUSH HL
- LD E,(HL) ;Get a byte
- LD C,PCHAR
- CALL OPSYS ;Send it to the printer
- POP HL ;Regain address
- POP BC ;And counter
- INC HL ;Next address
- DEC BC
- LD A,B ;Check for zero
- OR C
- JR NZ,DOWN1 ;Do it again
- ;
- ; The actual driver code itself must be relocated to just below the
- ; BDOS, the LIST entry in the BIOS jump table changed to point to
- ; FXDRVR, and the jump address in location 5 (TPATOP) must be lowered to
- ; protect the driver.
- ;
- START2: LD HL,(TPATOP) ;Last available memory + 1
- LD (FXDRVR+1),HL ;For CP/M jumps
- LD BC,LENGTH ;Length to be relocated
- XOR A ;Clear carry
- SBC HL,BC ;Where to put first byte
- ;
- PUSH HL ;Save first byte address
- PUSH HL ; twice for good luck
- LD BC,FXDRVR-HMC ;Offset to protected area
- ADD HL,BC ;First protected address
- EX (SP),HL ;Swap first and one protected address
- ;
- LD BC,HMC
- SBC HL,BC ;Compute offset
- LD (OFFSET),HL ;And save for later
- ;
- ; Fix the fixed addresses in FXDRVR.
- ;
- EX DE,HL ;Offset
- LD HL,RTABLE
- AGAIN: LD C,(HL) ;BC is actual value
- INC HL
- LD B,(HL)
- LD A,C ;If it is zero, we are done
- OR B
- JR Z,FIXUP
- LD A,(BC) ;Low byte of address
- ADD A,E ;Low byte of offset
- LD (BC),A ;Put it back
- INC BC ;Next
- LD A,(BC) ;High byte of address
- ADC A,D ;High byte of offset
- LD (BC),A ;Put it back
- INC HL
- JR AGAIN
- ;
- FIXUP: LD HL,(WBOOT+1) ;Get address of start of CCP
- LD BC,3*LENTRY-2 ;Jump table offset to address
- ADD HL,BC ;Actual jump table entry address
- LD C,(HL) ;Low byte of list address
- INC HL
- LD B,(HL) ;High byte of list address
- LD (PR1+1),BC ;Save for later
- DEC HL
- POP BC ;Relocated first protected address
- LD A,C ; plus 3 to accomodate
- ADD A,3 ; the relocated CP/M
- LD (HL),A
- INC HL
- LD A,B
- ADC A,0
- LD (HL),A ;Patch jump table entry
- LD (TPATOP),BC ;Reset top of available memory
- ;
- LD HL,(WBOOT+1) ;Get and save warm-boot address
- INC HL ;Skip op code
- LD C,(HL) ;Load low byte
- INC HL
- LD B,(HL) ;Load high byte
- LD (WBOOTS),BC ;Save it
- ;
- LD DE,(OFFSET) ;Get the offset
- LD BC,ATLAST ;Unrelocated where to go at the end
- LD A,C ;Add offset to the unrelocated
- ADD A,E ; address of ATLAST
- LD C,A ; because when we want to use it,
- LD A,B ; its gonna be up there and not
- ADC A,D ; down here!
- LD B,A
- LD (HL),B ;Store the relocated ATLAST address
- DEC HL ; in the BIOS jump table
- LD (HL),C
- ;
- MOVIT: LD BC,LENGTH ;Number of bytes to move
- POP DE ;Where to put the bytes
- LD HL,HMC ;Where to get first byte
- LDIR ;Move it
- ;
- HMC0: JP HMC ;Go save page 0 stuff and load program
- ;
- OFFSET: DW 0 ;Temporary for offset
- ;
- ; Relocation table.
- ;
- RTABLE: DW NOPROG+1
- DW NOPR1+1
- DW HMC0+1
- DW HMC+1
- DW ATLAST+1
- DW T00+1
- DW T01+1
- DW T02+1
- DW T03+1
- DW T04+1
- DW T05+1
- DW T06+1
- DW T07+1
- DW T08+1
- DW T09+1
- DW T10+1
- DW T11+1
- DW T12+1
- DW T13+1
- DW T14+1
- DW T15+1
- DW T16+1
- DW T17+1
- DW T18+1
- DW T19+1
- DW T20+1
- DW T21+1
- DW T22+1
- DW T23+1
- DW T24+1
- DW T25+1
- DW T26+1
- DW T27+1
- DW T28+1
- DW T29+1
- DW T30+1
- DW T31+1
- DW T32+1
- DW T33+1
- DW T34+1
- DW T35+1
- DW T36+1
- DW T37+1
- DW T38+1
- DW T39+1
- DW T40+1
- DW T41+1
- DW T42+1
- DW T43+1
- DW T44+2
- DW T45+2
- DW T46+1
- DW T47+1
- DW 0
- ;
- ;
- ; HIGH MEMORY CODE
- ;
- ; The code below is moved to high memory and executed there. The first
- ; part of it is not part of the driver proper, but contains code to save
- ; page 0, load the program, and reset page 0. The second part is the
- ; driver proper.
- ;
- ; Save the secondary FCB.
- ;
- HMC: LD SP,HMC ;'Tis a fine thing we do!
- LD BC,16 ;Length of FCB as set up
- T00: LD DE,FILE2 ;Destination address
- LD HL,FCB2
- LDIR ;Move it
- ;
- ; Set the file extension in the primary file control block to .COM, no
- ; matter what the user wants.
- ;
- LD HL,FCB+9 ;Point to the extension subfield
- LD A,'C' ;Do it
- LD (HL),A
- INC HL
- LD A,'O'
- LD (HL),A
- INC HL
- LD A,'M'
- LD (HL),A ;Done
- ;
- ; Save the input file buffer only if there is a second file name.
- ;
- LD HL,BUFFER
- LD A,(HL) ;Buffer length count
- CP 0
- JR Z,NOPROG ;Nothing, not even a program name
- ;
- LD B,A ;Something is there. First skip
- INC HL ; any leading spaces
- SRCH1: LD A,(HL) ; by looking for a non-space
- INC HL
- CP SPACE
- JR NZ,SRCH2 ;Found a non-space
- DJNZ SRCH1 ;Keep it up till out of buffer
- ;
- ; No program name exists at all. Complain to the user.
- ;
- NOPROG: LD DE,MSG1
- LD C,DSTRNG
- CALL OPSYS
- NOPR1: CALL REPR ;Reset printer
- JP WBOOT
- ;
- MSG1: DB 'No program name given.',CR,LF,'$'
- ;
- SRCH2: LD A,(HL) ;We are scanning the first file name
- CP SPACE ;Keep looking for the first space char
- JR Z,SRCH3 ;Found a space
- INC HL
- DJNZ SRCH2 ;Repeat till out of buffer
- T01: LD HL,BUFFR2 ;Show that there is nothing saved in
- LD (HL),B ; the command line buffer
- JR LOADPR ;Then go load the program without args
- ;
- SRCH3: INC B
- LD C,B ;Count of command line bytes to save
- LD B,0
- T02: LD DE,BUFFR2 ;Where to save command line
- EX DE,HL
- LD (HL),C ;Save byte count first
- INC HL
- EX DE,HL
- LDIR ;Then the rest of the string
- JR LOADPR ;Then go load the program
- ;
- ; There is a program name present. First check to see if the file
- ; exists on the logged in disk. If not, check the A disk. If found,
- ; load the program at TBASE. If not found, complain bitterly.
- ;
- LOADPR: LD DE,FCB ;First, open the file
- LD C,OPEN
- CALL OPSYS ;Returns FF on failure
- INC A ;Was it FF?
- JR NZ,LOAD1 ;Jump if file found
- ;
- LD HL,FCB
- LD A,01H ;Disk A flag
- LD (HL),A
- EX DE,HL ;Try again. We even may have already
- LD C,OPEN ; tried this disk, but no matter
- CALL OPSYS
- INC A
- JR NZ,LOAD1 ;Got it this time
- ;
- ; The primary program file does not exist. Complain.
- ;
- T03: LD DE,MSG2
- LD C,DSTRNG
- CALL OPSYS
- JP WBOOT
- ;
- MSG2: DB 'File not found.',CR,LF,'$'
- ;
- ; Load the primary file. Though the code below is not protected, no
- ; normal WordStar load ought to get this high in memory. If it does,
- ; bombs away!
- ;
- LOAD1: LD DE,TBASE ;Initial load address
- PUSH DE ;Save it
- LD C,SETDMA
- CALL OPSYS
- ;
- LOAD2: LD DE,FCB ;This is the primary loading loop.
- LD C,READ ; A sector is read into sequential
- CALL OPSYS ; memory until an endfile condition
- POP DE ; is found.
- OR A ;This checks for the endfile
- JR NZ,SETUP ;Non-zero is endfile
- LD HL,128 ;Update the DMA address
- ADD HL,DE
- PUSH HL ;And save it again
- EX DE,HL
- LD C,SETDMA
- CALL OPSYS
- JR LOAD2 ;Repeat till done
- ;
- ; It now remains to reset the FCB and BUFFER.
- ;
- SETUP: LD BC,16H ;Reset FCB from what was saved.
- LD DE,FCB
- T04: LD HL,FILE2
- LDIR
- LD HL,FCB2 ;Reset FCB2 to empty
- LD (HL),B ; by storing a leading zero
- LD B,11 ; and 11 spaces
- LD A,SPACE
- SETUP1: INC HL
- LD (HL),A
- DJNZ SETUP1
- T05: LD HL,BUFFR2 ;Reset the command line buffer if it
- LD A,(HL) ; isn't empty
- CP 0 ;Is it empty
- JP Z,TBASE ;Yes, go RUN
- INC A ;So we move the count as well
- LD C,A ;Set count
- LD B,0
- LD DE,BUFFER
- LDIR
- JP TBASE ;That's it!
- ;
- ; Storage for FILE2 and BUFFR2.
- ;
- FILE2: DS 16 ;Secondary file control block
- BUFFR2: DS 80H
- ;
- ;
- ; THE WordStar DRIVER
- ;
- ; The driver proper is below. The first location is a jump to the true
- ; start of CP/M. A call to location 5 (the normal CP/M entry) results
- ; in a jump to the first protected address in high memory. That has now
- ; been changed so as to protect the driver. Hence the jump below, fil-
- ; led in by the relocator.
- ;
- FXDRVR: JP 0000H ;Jump to CP/M
- ;
- LD HL,0 ;Save the stack pointer
- ADD HL,SP ;Got it!
- T06: LD SP,STAK ;Set it to a local area
- PUSH HL ; and save old SP on it
- T07: LD HL,RCVR ;Now we put the stack recovery routine
- PUSH HL ; onto the stack so we can RET to it
- ;
- T08: LD HL,MODES ;Array of mode flags
- LD A,(HL) ;Graphics mode flag
- CP 0 ;Are we in graphics mode?
- T09: JP NZ,DOMAP ;Jump if we are
- ;
- LD A,C ;Character to A
- CP CCBASE ;Is it a mode toggle character?
- T10: JP C,PRINT ;If not, print it directly
- CP CCLAST ;Is it a weird character?
- RET NC ;If so, ignore it
- ;
- CP 81H ;Graphics character?
- JR Z,GRAF ;Jump if so
- ;
- INC HL ;Giant case statement:
- CP 82H ; HL points to proper mode
- T11: JP Z,ITAL ; flag
- INC HL
- CP 83H
- T12: JP Z,EMPH
- INC HL
- CP 84H
- T13: JP Z,COND
- INC HL
- CP 85H
- T14: JP Z,ELIT
- INC HL
- CP 86H
- T15: JP Z,DBLE
- ;
- ; We cannot get to this point in normal usage. Thus:
- ;
- LD DE,MSG3
- LD C,DSTRNG
- CALL OPSYS
- HALT ;With prayers
- ;
- MSG3: DB 'HARD ERROR: Failure in case statement.'
- DB CR,LF
- DB 'System must be REBOOTED to continue'
- DB CR,LF,'$'
- ;
- ; The response to the various mode flags is coded below:
- ;
- GRAF: LD (HL),A ;Set graphics mode
- RET
- ;
- ITAL: LD A,(HL) ;Get ITALICS mode flag
- OR A ;(A): 00=off, FF=on
- CPL ;Does not change Z flag
- LD (HL),A ;Resave mode flag
- LD B,2 ;Send two bytes to EPSON
- T16: LD HL,ONITAL
- T17: JP Z,PRINTS ;Turn ITALICS on
- T18: LD HL,OFITAL
- T19: JP PRINTS ;Turn ITALICS off
- ;
- ONITAL: DB 1BH, 34H ;ON ITALICS string
- OFITAL: DB 1BH, 35H ;OFF ITALICS string
- ;
- EMPH: LD A,(HL) ;Get EMPHASIZED mode flag
- OR A ;(A): 00=off, FF=on
- CPL ;Does not change Z flag
- LD (HL),A ;Resave mode flag
- LD B,2 ;Send two bytes to EPSON
- T20: LD HL,ONEMPH
- T21: JP Z,PRINTS ;Turn EMPHASIZED on
- T22: LD HL,OFEMPH
- T23: JP PRINTS ;Turn EMPHASIZED off
- ;
- ONEMPH: DB 1BH, 45H ;ON EMPHASIZED string
- OFEMPH: DB 1BH, 46H ;OFF EMPHASIZED string
- ;
- COND: LD A,(HL) ;Get CONDENSED mode flag
- OR A ;Set flag register as above
- CPL ;Does not change Z flag
- LD (HL),A ;Resave mode flag
- LD B,1 ;Send one byte to EPSON
- T24: LD HL,ONCOND
- T25: JP Z,PRINTS ;Turn CONDENSED on
- T26: LD HL,OFCOND
- T27: JP PRINTS ;Turn CONDENSED off
- ;
- ONCOND: DB 0FH ;ON CONDENSED string
- OFCOND: DB 12H ;OFF CONDENSED string
- ;
- ELIT: LD A,(HL) ;Get EXPANDED mode flag
- OR A
- CPL
- LD (HL),A
- LD B,2 ;Send two bytes to EPSON
- T28: LD HL,ONELIT
- T29: JP Z,PRINTS
- T30: LD HL,OFELIT
- T31: JP PRINTS
- ;
- ONELIT: DB 1BH, 4DH ;ON ELITE string
- OFELIT: DB 1BH, 50H ;OFF ELITE string
- ;
- DBLE: LD A,(HL) ;Get DOUBLE STRIKE mode flag
- OR A
- CPL
- LD (HL),A
- LD B,2 ;Send two bytes to EPSON
- T32: LD HL,ONDBLE
- T33: JP Z,PRINTS
- T34: LD HL,OFDBLE
- T35: JP PRINTS
- ;
- ONDBLE: DB 1BH, 47H ;ON DOUBLE STRIKE string
- OFDBLE: DB 1BH, 48H ;OFF DOUBLE STRIKE string
- ;
- ; PRINT simply saves all registers and calls the CP/M BIOS print rou-
- ; tine. The proper address is stuffed into the call statement by the
- ; setup code.
- ;
- PRINT: PUSH AF ;Avoid trouble, save it all
- PUSH BC
- PUSH DE
- PUSH HL
- PR1: CALL 0 ;To be filled with the address
- POP HL ; of the CP/M print routine
- POP DE
- POP BC
- POP AF
- RET
- ;
- ; PRINTS will output the string of bytes whose start is pointed to by HL
- ; until B bytes are sent.
- ;
- PRINTS: LD C,(HL) ;Get a byte
- T36: CALL PRINT ;Print the character
- INC HL ;Point to next byte
- DJNZ PRINTS ;Keep on if more
- RET ;Else quit
- ;
- ; PRINTE will output the same bytes as PRINTS but in emphasized mode.
- ;
- PRINTE: LD DE,0 ;Clear DE
- PRE: LD D,(HL) ;Get new byte
- LD A,D ;Move it to A
- OR E ;Or in previous byte
- LD C,A ;Prepare to send it
- T37: CALL PRINT ;Then send it
- INC HL ;Point to next byte
- LD E,D ;Save old byte
- DJNZ PRE ;And repeat 12 times
- RET ;Then quit
- ;
- ; DOMAP (called that for historical reasons) puts the Epson into alter
- ; nate character set mode, outputs the character, and returns it to the
- ; ordinary (ROM) character set mode.
- ;
- DOMAP: XOR A ;Clear register
- T38: LD (MODES),A ;And reset graphics mode
- PUSH BC ;Save character to be printed
- LD B,4 ;Send 4 characters
- T39: LD HL,ONGR ;Start of sequence
- T40: CALL PRINTS ;Send sequence
- POP BC ;Regain character
- T41: CALL PRINT ;Print it
- LD B,4 ;Send 4 characters
- T42: LD HL,OFFGR ;Start of sequence
- T43: CALL PRINTS ;Print it
- RET
- ;
- ONGR: DB 1BH,25H,01H,00H ;Select alternate character set
- OFFGR: DB 1BH,25H,00H,00H ;Select normal character set
- ;
- RCVR: POP HL ;Before quitting, reset the stack
- LD SP,HL ; to what it was when WordStar
- RET ; set the return address
- ;
- ; At termination of WordStar various locations in the BIOS jump vector
- ; and in low memory have to be reset to their initial values. Note that
- ; initially, before the driver runs, locations 1 and 2 contain a jump to
- ; the BIOS jump table warm boot entry. When the driver runs, the ad-
- ; dress in the table is stored in WBOOTS below and the address of the
- ; routine below substituted for it. When WordStar warm boots, the rou-
- ; tine below will be entered. The routine will reset the BIOS table
- ; address to its original value, reset the LIST entry to its initial
- ; value, and return locations 5 and 6 in low memory to their initial
- ; values.
- ;
- ATLAST: LD HL,(FXDRVR+1) ;Original memory top
- LD (TPATOP),HL ; now restored
- T44: LD BC,(WBOOTS) ;Saved BIOS warm boot entry
- LD HL,(WBOOT+1) ;Address for BIOS entry
- INC HL ;Point to address part of jump
- LD (HL),C
- INC HL
- LD (HL),B ;BIOS warm boot entry restored
- ;
- DEC HL ;Address for BIOS entry
- DEC HL
- LD BC,3*LENTRY-2 ;Jump table offset to address
- ADD HL,BC ;Actual jump table entry address
- T45: LD BC,(PR1+1) ;Saved BIOS list entry
- LD (HL),C
- INC HL
- LD (HL),B ;BIOS list entry restored
- ;
- ; One last thing remains. The FX-80 should be reset to its power-up
- ; configuration. To that end a reset string is now sent to the printer.
- ;
- REPR: LD B,2 ;Two character string
- T46: LD HL,RESET ;Point to the string
- T47: CALL PRINTS ;Send it
- ;
- JP WBOOT ;THAT'S IT, FOLKS!
- ;
- RESET: DB 1BH, 64H ;FX-80 master reset string
- ;
- WBOOTS: DW 0 ;For original warm boot address
- DS 01EH ;For a local stack
- STAK:
- ;
- ; The MODE bytes are stored here.
- ;
- MODES: DB 0 ;Graphics mode flag
- DB 0 ;Italics mode flag
- MODEE: DB 0 ;Emphasized mode flag
- DB 0 ;Condensed mode flag
- DB 0 ;Expanded mode flag
- DB 0 ;Double strike mode flag
- ;
- ;
- DS 20
- STACK: DB 2 ;Always use a stack
- FIN:
- ;
- FONT: ;The download font follows
- DB 1BH, 26H, 00H ;Code to cause the Epson to accept font
- DB FFCHAR ;First font character
- DB LFCHAR ;Last font character
- ;
- ; The font to be downloaded is appended to this file. FXDRVR expects
- ; exactly 3072 bytes here and that is the number that will be
- ; transmitted to the FX-80.
- ;
- DB '********' ;To make finding the end-of-program
- DB '********' ; easier.
- ;
- END
-