home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / p / px8info.lbr / PFKEY.DZC / PFKEY.DOC
Encoding:
Text File  |  1993-10-25  |  15.4 KB  |  324 lines

  1. .PL 54
  2. .MT 2
  3. .MB 2
  4. .HE          INTERRUPT DRIVEN ROUTINES VIA THE CTRL PF KEYS
  5. .FO                             PAGE #
  6. .HM 1
  7. .FM 1
  8.      While  most  of  the  time spent on the  Epson  Geneva  PX-8 
  9. Portable Computer would be spent running stock programs such as a 
  10. Spreadsheet or an Editor,  there are times that a User might wish 
  11. to  jump  out of a given program,  run a  special  function,  and 
  12. return  to the main program.   It is possible to perform  such  a 
  13. jump  on the PX provided that the interrupt routine being  jumped 
  14. to  is  written  correctly.   This  paper is  written  for  those 
  15. programmers who wish to expand the abilities of the Geneva.   The 
  16. paper  is a guide of what to do and what not to do  when  writing 
  17. such software.
  18.  
  19.      There  are  some  limits that the reader should  know  about 
  20. before  working on any interrupt  driven  software.   First,  the 
  21. software  MUST BE in machine code.   If you are unable to develop 
  22. such software in machine code,  don't bother to read the rest  of 
  23. this  paper because there is no way to enable the PX-8 to  accept 
  24. an interrupt routine in anything other than machine code.
  25.  
  26.      Another problem is the fact that no interrupt routine in RAM 
  27. will  work if any of it is located below $8000.   The reason  for 
  28. this limit is the fact that during interrupts, the RAM from $0000 
  29. to  $7FFF  is switched out and the Operating System (OS)  ROM  is 
  30. switched  into its place.   Thus any calls to any routine located 
  31. below  $8000 would result in an unexpected jump into the OS  ROM.  
  32. It  is  possible to locate an interrupt routine  below  the  CCP; 
  33. however such a move is not wise.  The reason it's not wise is the 
  34. fact that the routine is sitting within the TPA Area and could be 
  35. erased by a somewhat large or memory hungry program.   Some users 
  36. may wish to perform the trick of moving the routine above the CCP 
  37. and changing the BDOS jump vector.   While this trick is safer to 
  38. use,  a word of warning is required.  If the size of the internal 
  39. RAM  Disk  is changed or if the User BIOS size is  changed,  said 
  40. routine  will  be  garbaged.   The  safest  place  to  locate  an 
  41. interrupt routine is within the User BIOS Area.
  42.  
  43.      One final limit encountered when writing an interrupt driven 
  44. routine.   Standard BDOS and BIOS routines do not work  correctly 
  45. and  should  NOT be called.   However there is a way around  this 
  46. limit and is covered within this paper.
  47.  
  48.      During any interrupt operation,  the lower RAM ($0000-$7FFF) 
  49. is  switched out and the OS ROM is switched  in.   Therefore,  an 
  50. interrupt  routine  may  perform  direct calls  to  the  OS  ROM.  
  51. However unless you have source code, the correct address of where 
  52. to  jump  to would be unknown,  but there is a  solution  in  the 
  53. version 2.2B ROM (the new version OS ROM), vector table #3.
  54.  
  55.      First  a  few  words about the  different  tables:   When  a 
  56. program on the PX-8 executes a BIOS function such as Warm Boot, a 
  57. jump to location 0 occurs.  If the internal RAM Disk and the User 
  58. BIOS  area are both set to 0 bytes,  location 0 jumps to location 
  59. $EB03.   This  location is the WBOOT vector found in table #1  of 
  60. the  BIOS  jump  vectors.   Location $EB03  jumps  to  table  #2, 
  61. location  $EC03.   Table #2 starts at $EC00,  ends at $EC80,  and 
  62. every  line on this table is the same:  CALL $EC81.   While  this 
  63. might surprise some readers,  the function of this table is quite 
  64. logical.   Remember  that  a CALL instruction pushes  the  return 
  65. address  of  the next instruction to the stack,  thus  the  stack 
  66. holds the address of the the CALLing Vector+3.   All the  program 
  67. needs  to  do  is  to POP the HL register  and  perform  a  quick 
  68. subtraction  to  determine  the CALLing vector.   The  result  is 
  69. stored for later reference.  Thus, 43 bank switching routines are 
  70. not  required  because  all calls can use the  same  bank  select 
  71. routine.  When  the  OS ROM is called,  the  BIOS  routines  will 
  72. recover the CALLing vector and jump to the proper BIOS routine.
  73.  
  74.      In  the "old" version of the OS,  CP/M 2.2,  the proper jump 
  75. location  was found by a vector table located  within  ROM.   The 
  76. "new"  version  of the OS ROM has its jump vector  table  located 
  77. within upper RAM.  This vector table is known as table #3.  Below 
  78. is the locations of each vector and its function:
  79.  
  80.                       STANDARD BIOS CALLS:
  81.                       ====================
  82.  
  83.   FD90  JMP  2C89   ; COLD BOOT
  84.   FD93  JMP  2CCB   ; WARM BOOT
  85.   FD96  JMP  363D   ; CONST
  86.   FD99  JMP  3663   ; CONIN
  87.   FD9C  JMP  369D   ; CONOUT
  88.   FD9F  JMP  36B1   ; LIST
  89.   FDA2  JMP  36D2   ; PUNCH
  90.   FDA5  JMP  36C3   ; READER
  91.   FDA8  JMP  2F18   ; HOME
  92.   FDAB  JMP  2F24   ; SELDSK
  93.   FDAE  JMP  2FDD   ; SETTRK
  94.   FDB1  JMP  2FE3   ; SETSEC
  95.   FDB4  JMP  2FE8   ; SETDMA
  96.   FDB7  JMP  2FF9   ; READ
  97.   FDBA  JMP  2FEF   ; WRITE
  98.   FDBD  JMP  4178   ; LISTST
  99.   FDC0  JMP  2FEC   ; SECTRAN
  100.  
  101.                       EXTENDED BIOS CALLS:
  102.                       ====================
  103.  
  104.   FDC3  JMP  422C   ; PSET
  105.   FDC6  JMP  36E1   ; SCRNDUMP
  106.   FDC9  JMP  3907   ; BEEP
  107.   FDCC  JMP  3D42   ; RSOPEN
  108.   FDCF  JMP  3D5C   ; RSCLOSE
  109.   FDD2  JMP  3D60   ; RSINST
  110.   FDD5  JMP  414F   ; RSOUTST
  111.   FDD8  JMP  3D63   ; RSIN
  112.   FDDB  JMP  415E   ; RSOUT
  113.   FDDE  JMP  4299   ; TIMDAT
  114.  
  115.   FDE1  RET         ; MEMORY (DOES NOT PERFORM A FUNCTION WITHIN
  116.   FDE2  NOP         ;    THE PX-8, IT JUST RETURNS.)
  117.   FDE3  NOP  
  118.   FDE4  JMP  3D71   ; RSIOX
  119.   FDE7  RET         ; LIGHTPEN (THIS DOESN'T PERFORM A FUNCTION
  120.   FDE8  NOP         ;    WITHIN THE PX-8, IT JUST RETURNS.)
  121.   FDE9  NOP  
  122.   FDEA  JMP  43FE   ; MASKI
  123.   FDED  JMP  ECF9   ; LOADX
  124.   FDF0  JMP  ECFF   ; STORX
  125.   FDF3  JMP  ECF3   ; LDIRX
  126.   FDF6  JMP  ED0B   ; JUMPX
  127.   FDF9  JMP  ED05   ; CALLX
  128.   FDFC  JMP  41FD   ; GETPFK
  129.   FDFF  JMP  41FE   ; PUTPFK
  130.   FE02  JMP  4416   ; ADCVRT
  131.   FE05  JMP  4438   ; SLAVE
  132.   FE08  JMP  5F6B   ; RDVRAM
  133.   FE0B  JMP  6D3C   ; MCTTX
  134.   FE0E  JMP  2DF9   ; POWEROFF
  135.   FE11  DI          ; USER BIOS (THIS MUST BE DEFINED BY THE USER
  136.   FE12  RST  05     ;    DEFAULT CONTAINS GARBAGE LIKE THIS.)
  137.   FE13  RST  05
  138.  
  139.      A few words of warning to those who might wish to call these 
  140. vectors direct from a program in TPA:   IT WON'T WORK!   Remember 
  141. that these vectors are a direct call to the OS ROM.   Thus unless 
  142. the  OS  ROM  is paged into lower memory,  the  vectors  are  not 
  143. meaningful.   However,  if the OS ROM is active, any routine that 
  144. needs to call BIOS routines, MUST do so through these vectors.
  145.  
  146.      There  are several types of interrupts that can occur on the 
  147. PX-8, see below:
  148.  
  149.           7508:     ALARM, KB INTERRUPT
  150.           8251:     RS232 RECEIVE INTERRUPT
  151.             CD:     RS232 CD INTERRUPT
  152.            ICF:     BAR CODE READER INTERRUPT
  153.            OVF:     FREE RUNNING COUNTER OVERFLOW INTERRUPT
  154.            EXT:     EXTERNAL DEVICE INTERRUPT
  155.  
  156.      All of the above interrupts, if desired, can point to a user 
  157. defined routine in User BIOS.   The routine in User BIOS can call 
  158. any  of the above BIOS Vectors in table #3;  however there are  a 
  159. few things the programmer should watch out for when writing  User 
  160. BIOS Code.
  161.  
  162.      To  understand  what to watch out for,  please refer to  the 
  163. source  code  listing for PFDIR11,  starting at  location  $EA80.  
  164. This program is designed to provide a directory listing of  drive 
  165. A:  whenever CTRL-PF1 is pressed.  When this CTRL-Key is pressed, 
  166. an  interrupt  is  generated that causes control to jump  to  the 
  167. address found at location $F1C0-$F1C1.   The default address  for 
  168. this  location is a return instruction.   The return just  causes 
  169. the  CTRL-Key to do nothing.   However when PFDIR11 is  run,  the 
  170. address  at  this  vector is changed to point to $EA80  and  this 
  171. address is the start of my PFDIR routine.
  172.  
  173.      The  first section of code,  $EA80-EA85,  looks at the  MODE 
  174. FLAG ($F0B8).   The bits within this flag tell what MODE the PX-8 
  175. is in, for example:
  176.  
  177.           $F0B8: MODE FLAG, a 1 = active, a 0 = not on
  178.  
  179.               BIT      FUNCTION
  180.               -----------------------
  181.                7    POWER ON/OFF
  182.                6    SYSTEM INITIALIZE
  183.                5    PASSWORD ACCEPT
  184.                4    MENU DISPLAY
  185.                3    CP/M MODE
  186.                2    SYSTEM SCREEN
  187.                1    ALARM, INTERRUPT
  188.                0    ALARM, 0 START
  189.  
  190.      The bits that are tested are:  5,4,2,1,  and 0,  but first a 
  191. look at the bits that are not tested,  bits 7,6, and 3.  There is 
  192. no  need  to test bit 7 because PFDIR can only be  run  when  the 
  193. power is on.  Bit 6 could be tested, but is unnecessary because a 
  194. system  initialize  would disable the CTRL-PF Key  Functions.   I 
  195. have  no  idea how or even if bit 3 is  ever  used,  because  I'm 
  196. unable  to  come up with a condition where its set.   As for  the 
  197. bits that are tested, in all cases if the program were allowed to 
  198. run,  either there would be a system crash,  or upon return  from 
  199. the directory, the original screen would be trashed.
  200.  
  201.      Another  test  performed early in the program  ($EA86-$EA8A) 
  202. looks  at  what mode the LCD is in  (mode  0,1,2,  or  3).   This 
  203. program  will work in mode 0 only.   While the program could work 
  204. in mode 1,  the display of the directory would be a mess.  Screen 
  205. modes  2 and 3 would result in the directory erasing all or  part 
  206. of the current work on the screen.
  207.  
  208.      One  interesting thing discovered while writing  PFDIR,  was 
  209. the  fact  that once PFDIR was running,  there's no reason why  a 
  210. user couldn't press CTRL-PF1 again.  If done, the PX-8 will stack 
  211. both interrupts,  thereby running the second PF Key press  before 
  212. it  could  finish running the first PF Key press.   In  fact  the 
  213. stack  could hold several CTRL-PF Key presses.   While this might 
  214. be  a  big joke to some users,  "Lets see how many times  we  can 
  215. press  CTRL-PF1  before  the stack  overflows!",  the  result  of 
  216. pressing the CTRL-PF key a second time would be to destroy what's 
  217. on the original work screen.   The code at $EA8B-$EA94 keeps this 
  218. from occurring.   A single byte,  RFLAG (Run FLAG),  is tested to 
  219. see if the program is already running.
  220.  
  221.      Early  versions  of PFDIR caused problems when more  than  1 
  222. drive  was  being used.   The result would be that  whenever  any 
  223. drive other than A:  was in use,  if PFDIR was run,  a BDOS ERROR 
  224. would  occur when PFDIR was finished.   The reason for this error 
  225. was the fact that the disk work space area was altered by  PFDIR.  
  226. The solution to this problem was simple,  just save the disk work 
  227. space  area  on  entry to PFDIR and then restore this  area  upon 
  228. exit.   See sections $EA95-$EA9F and $EB62-$EB6C to see how  this 
  229. was done.
  230.  
  231.      PFDIR  should  not  alter or destroy any characters  on  the 
  232. current  LCD Display,  thus,  I assumed that the current  virtual 
  233. screen  was the area in use and the other virtual screen was  not 
  234. being used.  The subroutine SWAPVS (Swap Virtual Screens) located 
  235. at $EB76-$EB84 is a simple routine that selects the other screen.  
  236. If the current screen is 1,  this routine selects screen 2, or if 
  237. the  current  screen is 2,  it selects 1.   By  using  the  other 
  238. virtual  screen,  your  current work screen is saved  from  being 
  239. altered and will be reselected when the program returns.
  240.  
  241.      A  number of ROM Routines are called by PFDIR.   The  direct 
  242. calls  into  ROM were done because the routine required  did  not 
  243. exist in the BIOS tables.  Such calls are:
  244.  
  245.      BINASC:   Convert a binary number in the HL register into
  246.                printable ASCII, store at IX register location.
  247.  
  248.      SCRNPR:   Print the string pointed to by the HL register
  249.                to the LCD.  This routine does not look at the
  250.                IO byte ($3) or make use of CTRL-P. $FF = the
  251.                end of the string.
  252.  
  253.      LCDOUT:   The same as SCRNPR, except this one just prints
  254.                only a single character found in the C register
  255.                to the LCD.
  256.  
  257.      CONINP:   This is just like the BIOS routine CONTIN except
  258.                that this routine does NOT look at the IO Byte,
  259.                so that the Keyboard is always the input device.
  260.  
  261.      The  rest of the program is a simple Directory type  program 
  262. and because it runs much like a standard program in TPA,  it will 
  263. not be covered point for point.   In fact the only sections worth 
  264. noting are section $EB62-$EB6C, $EB6D-$EB74, and $EB75.
  265.  
  266.      $EB62-$EB6C restores the disk work area back to its original 
  267. form.   Section  $EB6D-$EB74 selects the original virtual  screen 
  268. and resets the RFLAG (Run FLAG) so that a later press of CTRL-PF1 
  269. will  allow the program to run again.   Last of all,  $EB75 is  a 
  270. return instruction, which is the end of our routine.  Notice that 
  271. this  instruction is a simple return (RET) and not a return  from 
  272. interrupt  (RETI  or RETN).   The OS code in the upper RAM  takes 
  273. care  of  enabling  the lower RAM memory  and  returning  to  the 
  274. current program.
  275.  
  276.      A  program  such as PFDIR is designed to avoid  crashing  or 
  277. affecting the current program in any way.  In some rare cases you 
  278. may  wish  to have the control PF Keys alter or change  something 
  279. within the program.  If that is the case, upper RAM ($8000-$FFFF) 
  280. is always on line and can be altered at any time;  however  lower 
  281. RAM  ($0000-$7FFF)  is  bank selected out  during  an  interrupt.  
  282. Thus,  the  BIOS routines in table #3,  LOADX,  STORX,  or  LDIRX 
  283. should be used to address the lower section of RAM memory.
  284.  
  285.      The  section  at  $EBA2-$EBA8 is run whenever  the  CTRL-PF1 
  286. function should be disabled and the default condition (no action, 
  287. just return),  is to be restored.   The code that does this  just 
  288. loads the default value $3970 into the control PF1 vector.
  289.  
  290.      The  last section of interest is $EBF0-$EBFF.   This section 
  291. is really not part of the program, but is still useful.  The code 
  292. here  is a header for the User BIOS Area.   The header is  useful 
  293. for  telling  what  routine is loaded into the  User  BIOS  Area.  
  294. Epson  standards  require that the header MUST  BE  in  locations 
  295. $EBF0-$EBFF.   The  following is a break down of each byte in the 
  296. User BIOS Header:
  297.  
  298. $EBF0-$EBF1:   This contains the following ASCII Upper Case
  299.                letters, "UB" (User Bios).  The letters "US" are
  300.                reserved for "User bios Scheduler data". These are
  301.                the ONLY 2 letter markers used to identify the
  302.                start of a legal header.
  303.  
  304. $EBF2-$EBF9:   8 ASCII letters are used like a file name to 
  305.                identify what routine is active in the User BIOS
  306.                Area.
  307.  
  308. $EBFA:         This is the number of 256 byte pages that the User
  309.                BIOS Routine takes.
  310.  
  311. $EBFB:         If this byte is $00, the routine may NOT be 
  312.                disabled.  Any other number allows for a release
  313.                routine to be run.
  314.  
  315. $EBFC-$EBFD:   If the address $EBFB does not equal $00, then this
  316.                is the address of the release routine that
  317.                disables the hooks of the User BIOS Routine.
  318.  
  319. $EBFE:         This byte is not used, but is set to $00.
  320.  
  321. $EBFF:         This is the checksum of the first 15 bytes, the
  322.                checksum is computed in this way:
  323.                CS = 0 - BYTE1 - BYTE2 - BYTE3 - ... - BYTE15
  324.