home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols200 / vol225 / fxdrvr.mac < prev    next >
Encoding:
Text File  |  1986-02-12  |  22.7 KB  |  796 lines

  1.     TITLE    FXDRVR:  A Special WordStar Font Driver
  2. ;
  3. ;
  4. ;   FXDRVR:  A Special Font Driver for WordStar and the Epson FX-80
  5. ;
  6. ; Copyright (c) 1982, 1983, 1984 by Paul J. Gans.  This version of
  7. ;     FXDRVR.MAC is hereby placed into public domain.  Permission
  8. ;     is granted to SIG/M to distribute this file freely for non-
  9. ;     commercial personal use only.
  10. ;
  11. ;
  12. ; Revision Record:
  13. ;
  14. ;    Version 1.0   January 15, 1982    Original version.
  15. ;         2.0   January 19, 1982    Auto program load added.
  16. ;         2.1   September 17, 1982    Emphasized graphics added.
  17. ;            2.2   January 19, 1983     Updated to work with Epson
  18. ;                                         Graphtrax Plus ROMs.
  19. ;            3.0   December 19, 1984    Name changed to FXDRVR, Down-
  20. ;                      load font used instead of
  21. ;                      graphics.
  22. ;
  23. ; The current version is 3.0.0 of 12/19/1984.
  24. ;
  25.         PAGE    58
  26. ;
  27. ; This  is a special font driver for WordStar.   It allows the  user  to 
  28. ; print  special  characters in a WordStar document on an  Epson  FX-80.   
  29. ; This  is  done by making use of the FX-80's ability to accept a  user- 
  30. ; defined  character set.   Included with this font driver is a  set  of  
  31. ; greek  upper  and lower case characters and some special  mathematical  
  32. ; symbols.
  33. ;
  34. ; Before this program can be used with WordStar,  WordStar must be prop
  35. ; erly set up to match the assumptions made by this program.   Configur
  36. ; ation instructions for WordStar are given in the file FXDRVR.DOC.
  37. ;
  38. ; This  program is designed to be assembled with Microsoft's M80  assem
  39. ; bler and follows the conventions of that program.   This assembler was 
  40. ; chosen because most of the code below is designed to be executed at an 
  41. ; address  other  than that into which it will be loaded   by  CP/M.   A 
  42. ; suitable command sequence to assemble and link this program is:
  43. ;
  44. ;         >M80 =FXDRVR/L          <== the /L produces a .PRN file,
  45. ;                                      omit it if not desired.
  46. ;
  47. ;         >L80 FXDRVR,FXDRVR/N/E
  48. ;
  49. ; After  FXDRVR  has been assembled and converted to a  .COM  file,  the 
  50. ; character set to be downloaded must be appended to it.   The file con
  51. ; taining  this character set must meet the assumptions of the  program.  
  52. ; The  character  set  must  contain 12 byte  character  definitions  as 
  53. ; specified in the Epson FX-80 manual.   They may start at an  arbitrary 
  54. ; character position (as defined by the FFCHAR equate below) and may end 
  55. ; at  an  arbitrary character position (as defined by the LFCHAR  equate 
  56. ; below).  All characters between the first and last character inclusive 
  57. ; MUST  be  present in the font.   Any or all of the characters  may  be 
  58. ; blank; many of the characters are blank in the set included here.
  59. ;
  60. ; The character set file is appended to the font driver at its very end.  
  61. ; To  make it easier to find the end of FXDRVR,  a line of 16  asterisks 
  62. ; has been placed at the end of the program.   The first 16 bytes of the 
  63. ; download font should overlay the asterisks.
  64. ;
  65. ;
  66. ; The action of the driver is simple.  A set of control codes, presently 
  67. ; the  numbers 81H through 86H,  cause the driver to instruct the  Epson
  68. ; FX-80  to enter one or another of its printing modes.    Control codes 
  69. ; are:
  70. ;
  71. ;    81H    downloaded font mode
  72. ;    82H    italic mode
  73. ;    83H    emphasized mode
  74. ;    84H    condensed mode
  75. ;    85H    elite mode
  76. ;    86H    double strike mode
  77. ;
  78. ; These  control codes are sent by WordStar when the appropriate special 
  79. ; characters  are  typed into a document by the user.   Just  how  these 
  80. ; special characters are mapped into control codes is set by user  cust-
  81. ; omization  of the printer area of WordStar.   A possible mapping is: 
  82. ;
  83. ;    ^A    Enter elite mode
  84. ;    ^N    Leave elite mode
  85. ;    ^W    Toggle italic mode
  86. ;    ^E    Toggle emphasized mode
  87. ;    ^R    Toggle condensed mode
  88. ;    ^Y    Toggle MX-80 double strike mode
  89. ;    ^Q    Used downloaded font for next character
  90. ;
  91. ; It is suggested that condensed mode (the ^R toggle) not be used in new 
  92. ; documents as future versions of this program may use the ^R toggle for
  93. ; other purposes.
  94. ;
  95. ; When  the alternate font signal (^Q) is  recognized in the output from 
  96. ; WordStar,  FXDRVR  outputs the control codes sequence 0x1b  0x25  0x01 
  97. ; 0x00.  This puts the  FX-80 into  alternate  character set  mode  (the 
  98. ; downloaded set).  FXDRVR then accepts  exactly one more character from 
  99. ; WordStar,  transmits it to the  FX-80, and  then  transmits  the  code 
  100. ; sequence 0x1b, 0x25, 0x00, 0x00 to the FX-80.  This last code sequence 
  101. ; returns the FX-80 to the normal character set.
  102. ;
  103. ; The other  mode codes  function as  toggles.  Initially  all modes are 
  104. ; off.   When a mode code is recognized  in  the input character stream,  
  105. ; the corresponding  mode is toggled.  That is, if it was off, it is now 
  106. ; turned on and vice versa.   When a mode is changed,  the corresponding 
  107. ; string  of bytes to perform that action is sent to the printer by  the 
  108. ; driver program.
  109. ;
  110. ; The  driver appears to the user as a normal .COM file.   It is invoked 
  111. ; as:
  112. ;
  113. ;                        FXDRVR wsname [filename.ext]
  114. ;
  115. ; where wsname is the name of the WordStar file.  and filename.ext is an 
  116. ; optional  file  name.   The special  driver relocates itself in  upper 
  117. ; memory  and patches itself into  the normal BIOS call table.   It will 
  118. ; then look for and load WordStar under the name WS.COM, first searching 
  119. ; the default disk and then, if not found, the A drive.   Execution will 
  120. ; then  be turned over to WordStar,  which will  then work in  a  normal 
  121. ; fashion,  loading  filename.ext as a D mode file for editing if it  is 
  122. ; specified.
  123. ;
  124. ; When  WordStar  finishes,  it will return control to the driver  which 
  125. ; will reset all  pointers and  memory  locations that it  changed, thus 
  126. ; restoring those locations to their original state.   FXRVR ends with a 
  127. ; return statement.
  128. ;
  129. ;
  130. ; Technical notes:
  131. ;
  132. ; There  is  nothing special about the font downloaded to  the  printer.  
  133. ; The font can be edited, or other fonts created, with nothing more than 
  134. ; the information provided by Epson in the FX-80 User's manual.
  135. ;
  136. ; This program has gone through a number of versions.   Versions 1 and 2 
  137. ; were written for the Epson MX-80 with Graphtrax.   Changes were needed 
  138. ; from  time to time as the codes used to control various printer  func
  139. ; tions have sometimes changed as Epson has changed the Graptrax ROMs.
  140. ;
  141. ; The current version has been greatly restructured to take advantage of 
  142. ; the  downloadable character set feature of the Epson FX-80.   Previous 
  143. ; versions used the graphics capability of the MX-80;  this version uses 
  144. ; a true character set.
  145. ;
  146. ;-----------------------------------------------------------------------------
  147. ;
  148.         .Z80 
  149. ;
  150. ; The  definitions below should be changed to accomodate differing  font 
  151. ; sizes.  FFCHAR is the decimal or hex equivalent of the first character 
  152. ; to be downloaded,  LFCHAR is the decimal or hex equivalent of the last 
  153. ; character to be downloaded.
  154. ;
  155. FFCHAR    EQU    000H        ;First font character
  156. LFCHAR    EQU    0FFH        ;Last font character
  157. ;
  158. FSIZE    EQU    12*(LFCHAR + 1 - FFCHAR)    ;Font size
  159. DCOUNT    EQU    FSIZE + 5    ;Font size plus Epson codes
  160. ;
  161. FALSE    EQU    0
  162. TRUE    EQU    NOT FALSE
  163. ;
  164. LF    EQU    0AH        ;Line feed
  165. CR    EQU    0DH        ;Carriage return
  166. ESCAPE    EQU    1BH        ;Escape
  167. SPACE    EQU    20H        ;Space
  168. ;
  169. INCHR    EQU    01H        ;CP/M character input
  170. OUTCHR    EQU    02H        ;CP/M character output
  171. PCHAR    EQU    05H        ;CP/M character print
  172. DSTRNG    EQU    09H        ;CP/M display string at console
  173. CHRW    EQU    0BH        ;CP/M character waiting
  174. OPEN    EQU    0FH        ;CP/M open file
  175. READ    EQU    14H        ;CP/M sequential read
  176. SETDMA    EQU    1AH        ;CP/M set DMA function
  177. ;
  178. LENTRY    EQU    05H        ;BIOS list function entry number
  179. ;
  180. WBOOT    EQU    0000H        ;Normal warm boot entry point
  181. OPSYS    EQU    0005H        ;CP/M call location
  182. TPATOP    EQU    0006H        ;Where TPA top address is stored
  183. FCB    EQU    005CH        ;Default file control block
  184. FCB2    EQU    006CH        ;Secondary file control block
  185. BUFFER    EQU    0080H        ;Input command line buffer
  186. TBASE    EQU    0100H        ;Normal program load address
  187. ;
  188. CCBASE    EQU    80H        ;Control codes lie exclusively
  189. CCLAST    EQU    87H        ;  between CCBASE and CCLAST
  190. ;
  191. LENGTH    EQU    FIN-HMC+1    ;Length of code to relocate
  192. ;
  193. ;
  194.     ASEG
  195.     ORG    100H
  196. ;
  197. ; First we display a logo.
  198. ;
  199. START:    LD    SP,STACK    ;Plan ahead, use a stack!
  200.     LD    DE,SIGNON    ;Now for a short message
  201.     LD    C,DSTRNG    ;  from our sponsor...
  202.     CALL    OPSYS
  203.     JR    DOWNL
  204. ;
  205. SIGNON:    DB    'The Special Graphics Driver '
  206.     DB    CR,LF
  207.     DB    'Version 3.0  (c) 1982, 1983, 1984 by '
  208.     DB    'Paul J. Gans'
  209.         DB      CR,LF
  210.         DB      'All Commercial Rights Reserved.'
  211.     DB    CR,LF,'$'
  212. ;
  213. ; The next thing to do is to download the user-definable character  set.  
  214. ; FXDRVR  expects  this set to be appended to the end of  this  program, 
  215. ; starting at location FONT.  There should be exactly 3077 bytes at that 
  216. ; location,  the first five of which are 0x1b,  0x26,  0x00, 0x00, 0xff, 
  217. ; which  tell the FX-80 that 3072 bytes,  256 character code at 12 bytes 
  218. ; per character, are to be downloaded.
  219. ;
  220. DOWNL:    LD    BC,DCOUNT    ;Set up a counter
  221.     LD    HL,FONT            ;Source of bytes
  222. ;
  223. DOWN1:    PUSH    BC        ;Save counters and address
  224.     PUSH    HL
  225.     LD    E,(HL)        ;Get a byte
  226.     LD    C,PCHAR
  227.     CALL    OPSYS        ;Send it to the printer
  228.     POP    HL        ;Regain address
  229.     POP    BC        ;And counter
  230.     INC    HL        ;Next address
  231.     DEC    BC
  232.     LD    A,B        ;Check for zero
  233.     OR    C
  234.     JR    NZ,DOWN1    ;Do it again
  235. ;
  236. ; The  actual  driver  code itself must be relocated to just  below  the 
  237. ; BDOS,  the  LIST  entry  in the BIOS jump table changed  to  point  to 
  238. ; FXDRVR, and the jump address in location 5 (TPATOP) must be lowered to 
  239. ; protect the driver.
  240. ;
  241. START2:    LD    HL,(TPATOP)    ;Last available memory + 1
  242.     LD    (FXDRVR+1),HL    ;For CP/M jumps
  243.     LD    BC,LENGTH    ;Length to be relocated
  244.     XOR    A        ;Clear carry
  245.     SBC    HL,BC        ;Where to put first byte
  246. ;
  247.     PUSH    HL        ;Save first byte address
  248.     PUSH    HL        ;  twice for good luck
  249.     LD    BC,FXDRVR-HMC    ;Offset to protected area
  250.     ADD    HL,BC        ;First protected address
  251.     EX    (SP),HL        ;Swap first and one protected address
  252. ;
  253.     LD    BC,HMC
  254.     SBC    HL,BC        ;Compute offset
  255.     LD    (OFFSET),HL    ;And save for later
  256. ;
  257. ; Fix the fixed addresses in FXDRVR.
  258. ;
  259.     EX    DE,HL        ;Offset
  260.     LD    HL,RTABLE
  261. AGAIN:    LD    C,(HL)        ;BC is actual value
  262.     INC    HL
  263.     LD    B,(HL)
  264.     LD    A,C        ;If it is zero, we are done
  265.     OR    B
  266.     JR    Z,FIXUP
  267.     LD    A,(BC)        ;Low byte of address
  268.     ADD    A,E        ;Low byte of offset
  269.     LD    (BC),A        ;Put it back
  270.     INC    BC        ;Next
  271.     LD    A,(BC)        ;High byte of address
  272.     ADC    A,D        ;High byte of offset
  273.     LD    (BC),A        ;Put it back
  274.     INC    HL
  275.     JR    AGAIN
  276. ;
  277. FIXUP:    LD    HL,(WBOOT+1)    ;Get address of start of CCP
  278.     LD    BC,3*LENTRY-2    ;Jump table offset to address
  279.     ADD    HL,BC        ;Actual jump table entry address
  280.     LD    C,(HL)        ;Low byte of list address
  281.     INC    HL
  282.     LD    B,(HL)        ;High byte of list address
  283.     LD    (PR1+1),BC    ;Save for later
  284.     DEC    HL
  285.     POP    BC        ;Relocated first protected address
  286.     LD    A,C        ;  plus 3 to accomodate
  287.     ADD    A,3        ;  the relocated CP/M
  288.     LD    (HL),A
  289.     INC    HL
  290.     LD    A,B
  291.     ADC    A,0
  292.     LD    (HL),A        ;Patch jump table entry
  293.     LD    (TPATOP),BC    ;Reset top of available memory
  294. ;
  295.     LD    HL,(WBOOT+1)    ;Get and save warm-boot address
  296.     INC    HL        ;Skip op code
  297.     LD    C,(HL)        ;Load low byte
  298.     INC    HL
  299.     LD    B,(HL)        ;Load high byte
  300.     LD    (WBOOTS),BC    ;Save it
  301. ;
  302.     LD    DE,(OFFSET)    ;Get the offset
  303.     LD    BC,ATLAST    ;Unrelocated where to go at the end
  304.     LD    A,C        ;Add offset to the unrelocated
  305.     ADD    A,E        ;  address of ATLAST
  306.     LD    C,A        ;  because when we want to use it,
  307.     LD    A,B        ;  its gonna be up there and not
  308.     ADC    A,D        ;  down here!
  309.     LD    B,A
  310.     LD    (HL),B        ;Store the relocated ATLAST address
  311.     DEC    HL        ;  in the BIOS jump table
  312.     LD    (HL),C
  313. ;
  314. MOVIT:    LD    BC,LENGTH    ;Number of bytes to move
  315.     POP    DE        ;Where to put the bytes
  316.     LD    HL,HMC        ;Where to get first byte
  317.     LDIR            ;Move it
  318. ;
  319. HMC0:    JP    HMC        ;Go save page 0 stuff and load program
  320. ;
  321. OFFSET:    DW    0        ;Temporary for offset
  322. ;
  323. ; Relocation table.
  324. ;
  325. RTABLE:    DW    NOPROG+1
  326.     DW    NOPR1+1
  327.     DW    HMC0+1
  328.     DW    HMC+1
  329.     DW    ATLAST+1
  330.     DW    T00+1
  331.     DW    T01+1
  332.     DW    T02+1
  333.     DW    T03+1
  334.     DW    T04+1
  335.     DW    T05+1
  336.     DW    T06+1
  337.     DW    T07+1
  338.     DW    T08+1
  339.     DW    T09+1
  340.     DW    T10+1
  341.     DW    T11+1
  342.     DW    T12+1
  343.     DW    T13+1
  344.     DW    T14+1
  345.     DW    T15+1
  346.     DW    T16+1
  347.     DW    T17+1
  348.     DW    T18+1
  349.     DW    T19+1
  350.     DW    T20+1
  351.     DW    T21+1
  352.     DW    T22+1
  353.     DW    T23+1
  354.     DW    T24+1
  355.     DW    T25+1
  356.     DW    T26+1
  357.     DW    T27+1
  358.     DW    T28+1
  359.     DW    T29+1
  360.     DW    T30+1
  361.     DW    T31+1
  362.     DW    T32+1
  363.     DW    T33+1
  364.     DW    T34+1
  365.     DW    T35+1
  366.     DW    T36+1
  367.     DW    T37+1
  368.     DW    T38+1
  369.     DW    T39+1
  370.     DW    T40+1
  371.     DW    T41+1
  372.     DW    T42+1
  373.     DW    T43+1
  374.     DW    T44+2
  375.     DW    T45+2
  376.     DW    T46+1
  377.     DW    T47+1
  378.     DW    0
  379. ;
  380. ;
  381. ;                           HIGH MEMORY CODE
  382. ;
  383. ; The code below is moved to high memory and executed there.   The first 
  384. ; part of it is not part of the driver proper, but contains code to save 
  385. ; page 0,  load the program,  and reset page 0.   The second part is the 
  386. ; driver proper.
  387. ;
  388. ; Save the secondary FCB.
  389. ;
  390. HMC:    LD    SP,HMC        ;'Tis a fine thing we do!
  391.     LD    BC,16        ;Length of FCB as set up
  392. T00:    LD    DE,FILE2    ;Destination address
  393.     LD    HL,FCB2
  394.     LDIR            ;Move it
  395. ;
  396. ; Set the file extension in the primary file control block to  .COM,  no 
  397. ; matter what the user wants.
  398. ;
  399.     LD    HL,FCB+9    ;Point to the extension subfield
  400.     LD    A,'C'        ;Do it
  401.     LD    (HL),A
  402.     INC    HL
  403.     LD    A,'O'
  404.     LD    (HL),A
  405.     INC    HL
  406.     LD    A,'M'
  407.     LD    (HL),A        ;Done
  408. ;
  409. ; Save the input file buffer only if there is a second file name.
  410. ;
  411.     LD    HL,BUFFER
  412.     LD    A,(HL)        ;Buffer length count
  413.     CP      0
  414.     JR    Z,NOPROG    ;Nothing, not even a program name
  415. ;
  416.     LD    B,A        ;Something is there.  First skip
  417.     INC    HL        ;  any leading spaces
  418. SRCH1:    LD    A,(HL)        ;  by looking for a non-space
  419.     INC    HL
  420.     CP    SPACE
  421.     JR    NZ,SRCH2    ;Found a non-space
  422.     DJNZ    SRCH1        ;Keep it up till out of buffer
  423. ;
  424. ; No program name exists at all.  Complain to the user.
  425. ;
  426. NOPROG:    LD    DE,MSG1
  427.     LD    C,DSTRNG
  428.     CALL    OPSYS
  429. NOPR1:    CALL    REPR        ;Reset printer
  430.     JP    WBOOT
  431. ;
  432. MSG1:    DB    'No program name given.',CR,LF,'$'
  433. ;
  434. SRCH2:    LD    A,(HL)        ;We are scanning the first file name
  435.     CP    SPACE        ;Keep looking for the first space char
  436.     JR    Z,SRCH3        ;Found a space
  437.     INC    HL
  438.     DJNZ    SRCH2        ;Repeat till out of buffer
  439. T01:    LD    HL,BUFFR2    ;Show that there is nothing saved in
  440.     LD    (HL),B        ;  the command line buffer
  441.     JR    LOADPR        ;Then go load the program without args
  442. ;
  443. SRCH3:    INC    B
  444.     LD    C,B        ;Count of command line bytes to save
  445.     LD    B,0
  446. T02:    LD    DE,BUFFR2    ;Where to save command line
  447.     EX    DE,HL
  448.     LD    (HL),C        ;Save byte count first
  449.     INC    HL
  450.     EX    DE,HL
  451.     LDIR            ;Then the rest of the string
  452.     JR    LOADPR        ;Then go load the program
  453. ;
  454. ; There  is  a  program name present.   First check to see if  the  file 
  455. ; exists on the logged in disk.   If not,  check the A disk.   If found, 
  456. ; load the program at TBASE. If not found, complain bitterly.
  457. ;
  458. LOADPR:    LD    DE,FCB        ;First, open the file
  459.     LD    C,OPEN
  460.     CALL    OPSYS        ;Returns FF on failure
  461.     INC    A        ;Was it FF?
  462.     JR    NZ,LOAD1    ;Jump if file found
  463. ;
  464.     LD    HL,FCB
  465.     LD    A,01H        ;Disk A flag
  466.     LD    (HL),A
  467.     EX    DE,HL        ;Try again.  We even may have already
  468.     LD    C,OPEN        ;  tried this disk, but no matter
  469.     CALL    OPSYS
  470.     INC    A
  471.     JR    NZ,LOAD1    ;Got it this time
  472. ;
  473. ; The primary program file does not exist.  Complain.
  474. ;
  475. T03:    LD    DE,MSG2
  476.     LD    C,DSTRNG
  477.     CALL    OPSYS
  478.     JP    WBOOT
  479. ;
  480. MSG2:    DB    'File not found.',CR,LF,'$'
  481. ;
  482. ; Load  the primary file.   Though the code below is not  protected,  no 
  483. ; normal  WordStar load ought to get this high in memory.   If it  does, 
  484. ; bombs away!
  485. ;
  486. LOAD1:    LD    DE,TBASE    ;Initial load address
  487.     PUSH    DE        ;Save it
  488.     LD    C,SETDMA
  489.     CALL    OPSYS
  490. ;
  491. LOAD2:    LD    DE,FCB        ;This is the primary loading loop.
  492.     LD    C,READ        ;  A sector is read into sequential
  493.     CALL    OPSYS        ;  memory until an endfile condition
  494.     POP    DE        ;  is found.
  495.     OR    A        ;This checks for the endfile
  496.     JR    NZ,SETUP    ;Non-zero is endfile
  497.     LD    HL,128        ;Update the DMA address
  498.     ADD    HL,DE
  499.     PUSH    HL        ;And save it again
  500.     EX    DE,HL
  501.     LD    C,SETDMA
  502.     CALL    OPSYS
  503.     JR    LOAD2        ;Repeat till done
  504. ;
  505. ; It now remains to reset the FCB and BUFFER.
  506. ;
  507. SETUP:    LD    BC,16H        ;Reset FCB from what was saved.
  508.     LD    DE,FCB
  509. T04:    LD    HL,FILE2
  510.     LDIR
  511.     LD    HL,FCB2        ;Reset FCB2 to empty
  512.     LD    (HL),B        ;  by storing a leading zero
  513.     LD    B,11        ;  and 11 spaces
  514.     LD    A,SPACE
  515. SETUP1:    INC    HL
  516.     LD    (HL),A
  517.     DJNZ    SETUP1
  518. T05:    LD    HL,BUFFR2    ;Reset the command line buffer if it
  519.     LD    A,(HL)        ;  isn't empty
  520.     CP    0        ;Is it empty
  521.     JP    Z,TBASE        ;Yes, go RUN
  522.     INC    A        ;So we move the count as well
  523.     LD    C,A        ;Set count
  524.     LD    B,0
  525.     LD    DE,BUFFER
  526.     LDIR
  527.     JP    TBASE        ;That's it!
  528. ;
  529. ; Storage for FILE2 and BUFFR2.
  530. ;
  531. FILE2:    DS    16        ;Secondary file control block
  532. BUFFR2:    DS    80H
  533. ;
  534. ;
  535. ;                         THE WordStar DRIVER
  536. ;
  537. ; The driver proper is below.   The first location is a jump to the true 
  538. ; start of CP/M.   A call to location 5 (the normal CP/M entry)  results 
  539. ; in a jump to the first protected address in high memory.  That has now 
  540. ; been changed so as to protect the driver.   Hence the jump below, fil-
  541. ; led in by the relocator.
  542. ;
  543. FXDRVR:    JP    0000H        ;Jump to CP/M
  544. ;
  545.     LD    HL,0        ;Save the stack pointer
  546.     ADD    HL,SP        ;Got it!
  547. T06:    LD    SP,STAK        ;Set it to a local area
  548.     PUSH    HL        ;  and save old SP on it
  549. T07:    LD    HL,RCVR        ;Now we put the stack recovery routine
  550.     PUSH    HL        ;  onto the stack so we can RET to it
  551. ;
  552. T08:    LD    HL,MODES    ;Array of mode flags
  553.     LD    A,(HL)        ;Graphics mode flag
  554.     CP    0        ;Are we in graphics mode?
  555. T09:    JP    NZ,DOMAP    ;Jump if we are
  556. ;
  557.     LD    A,C        ;Character to A
  558.     CP    CCBASE        ;Is it a mode toggle character?
  559. T10:    JP    C,PRINT        ;If not, print it directly
  560.     CP    CCLAST        ;Is it a weird character?
  561.     RET    NC        ;If so, ignore it
  562. ;
  563.     CP    81H        ;Graphics character?
  564.     JR    Z,GRAF        ;Jump if so
  565. ;
  566.     INC    HL        ;Giant case statement:
  567.     CP    82H        ;  HL points to proper mode
  568. T11:    JP    Z,ITAL        ;  flag
  569.     INC    HL
  570.     CP    83H
  571. T12:    JP    Z,EMPH
  572.     INC    HL
  573.     CP    84H
  574. T13:    JP    Z,COND
  575.     INC    HL
  576.     CP    85H
  577. T14:    JP    Z,ELIT
  578.     INC    HL
  579.     CP    86H
  580. T15:    JP    Z,DBLE
  581. ;
  582. ; We cannot get to this point in normal usage.  Thus:
  583. ;
  584.     LD    DE,MSG3
  585.     LD    C,DSTRNG
  586.     CALL    OPSYS
  587.     HALT            ;With prayers
  588. ;
  589. MSG3:    DB    'HARD ERROR:  Failure in case statement.'
  590.     DB    CR,LF
  591.     DB    'System must be REBOOTED to continue'
  592.     DB    CR,LF,'$'
  593. ;
  594. ; The response to the various mode flags is coded below:
  595. ;
  596. GRAF:    LD    (HL),A        ;Set graphics mode
  597.     RET
  598. ;
  599. ITAL:    LD    A,(HL)        ;Get ITALICS mode flag
  600.     OR    A        ;(A): 00=off, FF=on
  601.     CPL            ;Does not change Z flag
  602.     LD    (HL),A        ;Resave mode flag
  603.     LD    B,2        ;Send two bytes to EPSON
  604. T16:    LD    HL,ONITAL
  605. T17:    JP    Z,PRINTS    ;Turn ITALICS on
  606. T18:    LD    HL,OFITAL
  607. T19:    JP    PRINTS        ;Turn ITALICS off
  608. ;
  609. ONITAL:    DB    1BH, 34H    ;ON ITALICS string
  610. OFITAL:    DB    1BH, 35H    ;OFF ITALICS string
  611. ;
  612. EMPH:    LD    A,(HL)        ;Get EMPHASIZED mode flag
  613.     OR    A        ;(A): 00=off, FF=on
  614.     CPL            ;Does not change Z flag
  615.     LD    (HL),A        ;Resave mode flag
  616.     LD    B,2        ;Send two bytes to EPSON
  617. T20:    LD    HL,ONEMPH
  618. T21:    JP    Z,PRINTS    ;Turn EMPHASIZED on
  619. T22:    LD    HL,OFEMPH
  620. T23:    JP    PRINTS        ;Turn EMPHASIZED off
  621. ;
  622. ONEMPH:    DB    1BH, 45H    ;ON EMPHASIZED string
  623. OFEMPH:    DB    1BH, 46H    ;OFF EMPHASIZED string
  624. ;
  625. COND:    LD    A,(HL)        ;Get CONDENSED mode flag
  626.     OR    A        ;Set flag register as above
  627.     CPL            ;Does not change Z flag
  628.     LD    (HL),A        ;Resave mode flag
  629.     LD    B,1        ;Send one byte to EPSON
  630. T24:    LD    HL,ONCOND
  631. T25:    JP    Z,PRINTS    ;Turn CONDENSED on
  632. T26:    LD    HL,OFCOND
  633. T27:    JP    PRINTS        ;Turn CONDENSED off
  634. ;
  635. ONCOND:    DB    0FH        ;ON CONDENSED string
  636. OFCOND:    DB    12H        ;OFF CONDENSED string
  637. ;
  638. ELIT:    LD    A,(HL)        ;Get EXPANDED mode flag
  639.     OR    A
  640.     CPL
  641.     LD    (HL),A
  642.     LD    B,2        ;Send two bytes to EPSON
  643. T28:    LD    HL,ONELIT
  644. T29:    JP    Z,PRINTS
  645. T30:    LD    HL,OFELIT
  646. T31:    JP    PRINTS
  647. ;
  648. ONELIT:    DB    1BH, 4DH    ;ON ELITE string
  649. OFELIT:    DB    1BH, 50H    ;OFF ELITE string
  650. ;
  651. DBLE:    LD    A,(HL)        ;Get DOUBLE STRIKE mode flag
  652.     OR    A
  653.     CPL
  654.     LD    (HL),A
  655.     LD    B,2        ;Send two bytes to EPSON
  656. T32:    LD    HL,ONDBLE
  657. T33:    JP    Z,PRINTS
  658. T34:    LD    HL,OFDBLE
  659. T35:    JP    PRINTS
  660. ;
  661. ONDBLE:    DB    1BH, 47H    ;ON DOUBLE STRIKE string
  662. OFDBLE:    DB    1BH, 48H    ;OFF DOUBLE STRIKE string
  663. ;
  664. ; PRINT  simply  saves all registers and calls the CP/M BIOS print  rou-
  665. ; tine.   The  proper address is stuffed into the call statement by  the 
  666. ; setup code.
  667. ;
  668. PRINT:    PUSH    AF        ;Avoid trouble, save it all
  669.     PUSH    BC
  670.     PUSH    DE
  671.     PUSH    HL
  672. PR1:    CALL    0        ;To be filled with the address
  673.     POP    HL        ;  of the CP/M print routine
  674.     POP    DE
  675.     POP    BC
  676.     POP    AF
  677.     RET
  678. ;
  679. ; PRINTS will output the string of bytes whose start is pointed to by HL 
  680. ; until B bytes are sent.
  681. ;
  682. PRINTS:    LD    C,(HL)        ;Get a byte
  683. T36:    CALL    PRINT        ;Print the character
  684.     INC    HL        ;Point to next byte
  685.     DJNZ    PRINTS        ;Keep on if more
  686.     RET            ;Else quit
  687. ;
  688. ; PRINTE will output the same bytes as PRINTS but in emphasized mode.
  689. ;
  690. PRINTE:    LD    DE,0        ;Clear DE
  691. PRE:    LD    D,(HL)        ;Get new byte
  692.     LD    A,D        ;Move it to A
  693.     OR    E        ;Or in previous byte
  694.     LD    C,A        ;Prepare to send it
  695. T37:    CALL    PRINT        ;Then send it
  696.     INC    HL        ;Point to next byte
  697.     LD    E,D        ;Save old byte
  698.     DJNZ    PRE        ;And repeat 12 times
  699.     RET            ;Then quit
  700. ;
  701. ; DOMAP (called that for historical reasons) puts the Epson into  alter
  702. ; nate character set mode,  outputs the character, and returns it to the 
  703. ; ordinary (ROM) character set mode.
  704. ;
  705. DOMAP:    XOR    A        ;Clear register
  706. T38:    LD    (MODES),A    ;And reset graphics mode
  707.     PUSH    BC        ;Save character to be printed
  708.     LD    B,4        ;Send 4 characters
  709. T39:    LD    HL,ONGR        ;Start of sequence
  710. T40:    CALL    PRINTS        ;Send sequence
  711.     POP    BC        ;Regain character
  712. T41:    CALL    PRINT        ;Print it
  713.     LD    B,4        ;Send 4 characters
  714. T42:    LD    HL,OFFGR    ;Start of sequence
  715. T43:    CALL    PRINTS        ;Print it
  716.     RET
  717. ;
  718. ONGR:    DB    1BH,25H,01H,00H    ;Select alternate character set
  719. OFFGR:    DB    1BH,25H,00H,00H    ;Select normal character set
  720. ;
  721. RCVR:    POP    HL        ;Before quitting, reset the stack
  722.     LD    SP,HL        ;  to what it was when WordStar
  723.     RET            ;  set the return address
  724. ;
  725. ; At  termination of WordStar various locations in the BIOS jump  vector 
  726. ; and in low memory have to be reset to their initial values.  Note that 
  727. ; initially, before the driver runs, locations 1 and 2 contain a jump to 
  728. ; the  BIOS jump table warm boot entry.   When the driver runs,  the ad-
  729. ; dress  in the table is stored in WBOOTS below and the address  of  the 
  730. ; routine below substituted for it.   When WordStar warm boots, the rou-
  731. ; tine  below  will be entered.   The routine will reset the BIOS  table 
  732. ; address  to its original value,  reset the LIST entry to  its  initial 
  733. ; value,  and  return  locations 5 and 6 in low memory to their  initial 
  734. ; values.
  735. ;
  736. ATLAST:    LD    HL,(FXDRVR+1)    ;Original memory top
  737.     LD    (TPATOP),HL    ;  now restored
  738. T44:    LD    BC,(WBOOTS)    ;Saved BIOS warm boot entry
  739.     LD    HL,(WBOOT+1)    ;Address for BIOS entry
  740.     INC    HL        ;Point to address part of jump
  741.     LD    (HL),C
  742.     INC    HL
  743.     LD    (HL),B        ;BIOS warm boot entry restored
  744. ;
  745.     DEC    HL        ;Address for BIOS entry
  746.     DEC    HL
  747.     LD    BC,3*LENTRY-2    ;Jump table offset to address
  748.     ADD    HL,BC        ;Actual jump table entry address
  749. T45:    LD    BC,(PR1+1)    ;Saved BIOS list entry
  750.     LD    (HL),C
  751.     INC    HL
  752.     LD    (HL),B        ;BIOS list entry restored
  753. ;
  754. ; One  last  thing remains.   The FX-80 should be reset to its  power-up 
  755. ; configuration.  To that end a reset string is now sent to the printer.
  756. ;
  757. REPR:    LD    B,2        ;Two character string
  758. T46:    LD    HL,RESET    ;Point to the string
  759. T47:    CALL    PRINTS        ;Send it
  760. ;
  761.     JP    WBOOT        ;THAT'S IT, FOLKS!
  762. ;
  763. RESET:  DB    1BH, 64H    ;FX-80 master reset string
  764. ;
  765. WBOOTS:    DW    0        ;For original warm boot address
  766.     DS    01EH        ;For a local stack
  767. STAK:
  768. ;
  769. ; The MODE bytes are stored here.
  770. ;
  771. MODES:    DB    0        ;Graphics mode flag
  772.     DB    0        ;Italics mode flag
  773. MODEE:    DB    0        ;Emphasized mode flag
  774.     DB    0        ;Condensed mode flag
  775.     DB    0        ;Expanded mode flag
  776.     DB    0        ;Double strike mode flag
  777. ;
  778. ;
  779.     DS    20
  780. STACK:    DB    2        ;Always use a stack
  781. FIN:
  782. ;
  783. FONT:                ;The download font follows
  784.         DB    1BH, 26H, 00H    ;Code to cause the Epson to accept font
  785.     DB    FFCHAR        ;First font character
  786.     DB    LFCHAR        ;Last font character
  787. ;
  788. ; The  font to be downloaded is appended to this file.   FXDRVR  expects 
  789. ; exactly  3072  bytes  here  and  that  is  the  number  that  will  be 
  790. ; transmitted to the FX-80.
  791. ;
  792.     DB    '********'    ;To make finding the end-of-program
  793.     DB    '********'    ;  easier.
  794. ;
  795.     END
  796.