changeset 2391:f251299cd337

SCF removed since it has been backported to level 1
author boisy
date Sun, 24 Jan 2010 03:59:38 +0000
parents 1ac410eb636e
children ce8e20d715e4
files level2/modules/scf.asm
diffstat 1 files changed, 0 insertions(+), 1646 deletions(-) [+]
line wrap: on
line diff
--- a/level2/modules/scf.asm	Sun Jan 24 03:58:59 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1646 +0,0 @@
-********************************************************************
-* SCF - NitrOS-9 Level 2 Sequential Character File Manager
-*
-* $Id$
-*
-* This contains an added SetStat call to allow placing prearranged data
-* into the keyboard buffer of ANY SCF related device.
-*
-* Usage:
-*
-* Entry: X = Pointer to the string
-*        Y = Length of the string
-*        A = Path number
-*        B = SS.Fill ($A0) (syscall SETSTAT function call number)
-* NOTE: If high bit of Y is set, no carriage return will be appended to
-*       the read buffer (used in Shellplus V2.2 history)
-*
-* This also includes Kevin Darlings SCF Editor patches.
-*
-* Edt/Rev  YYYY/MM/DD  Modified by
-* Comment
-* ------------------------------------------------------------------
-*          1993/04/20  ???
-* V1.09:
-* - Speeded up L05CC (write char to device) routine by a few cycles
-* - Slightly optimized Insert char.
-* - Move branch table so Read & ReadLn are 1 cycle faster each; fixed
-*   SS.Fill so size is truncated @ 256 bytes.
-* - Added NO CR option to SS.Fill (for use with modified Shellplus V2.2
-*   command history).
-*
-*          1993/04/21  ???
-* Slight speedup to some of ReadLn parsing, TFM's in Open/Close.
-* - More optimization to read/write driver calls
-* - Got rid of branch table @ L05E3 for speed
-*
-*          1993/05/21  ???
-* V1.10:
-* Added Boisy Pitre's patch for non-sharable devices.
-* - Saved 4 cycles in routine @ L042B
-* - Modified Boisy's routine to not pshs/puls B (saves 2 cycles).
-* - Changed buffer prefill of CR's to save 1 byte.
-*
-*          1993/07/27  ???
-* V1.11:
-* Changed a BRA to a LBRA to a straight LBRA in L0322.
-* - Optimized path option character routine @ L032C
-*
-*          1993/08/03  ???
-* Modified vector table @ L033F to save 1 cycle on PD.PSC
-* - Sped up uppercase conversion checks for ReadLn & WritLn
-* - Changed 2 BRA's to L02F9 to do an LBRA straight to L05F8 (ReadLn loop)
-* - Moved L0565 routine so Reprint line, Insert & Delete char (on ReadLn)
-*   are 1 cycle faster / char printed
-* - Changed 2 references to L0420 to go straight to L0565
-* - Sped up ReadLn loop by 2 or 3 cycles per char read
-*
-*          1993/09/21  ???
-* V1.12:
-* Sped up L0435 by 1 or 2 cycles (depending on branch)
-* - Changed LDD ,S to TFR X,D (saves 1 cycle) @ L04F1 (Write & WritLn)
-* - Modified L04F1 to use W without TFR (+1 byte, -3 cycles) (Write)
-*
-*          1993/11/09  ???
-* Took LDX #0/LDU PD.BUF,y from L03B5 & merged in @ L028A, L02EF & L0381.
-* Also changed BEQ @ L03A5 to skip re-loading X with 0.
-*
-*          1993/11/10  ???
-* Moved L04B2 routine to allow a couple of BSR's instead of LBSR's In READ.
-* - Moved driver call right into READ loop (should save 25 cycles/char read)
-* - Moved driver call right into L0565 (should save 12 cycles/char written on echo,
-*   line editing, etc.)
-*
-*          1993/11/26  ???
-* Moved L02FE (ReadLn parsing) to end where ReadLn routine is moved L03E2
-* so Read loop would be optimized for it (read char from driver) instead of
-* L042B (write filled buffer to caller).
-* Changed LDA #C$NULL to CLRA.
-*
-*          1993/12/01  ???
-* Modified device write call (L056F) to preserve Y as well, to cut down on
-* PSHS/PULS.
-* - Changed L03E2 & L03DA to exit immediately if PD.DEV or PD.DV2 (depending
-* on which routine) is empty (eliminated redundant LEAX ,X).
-*
-*          1994/05/31  ???
-* Attempted mode to L03F1 to eliminate LDW #D$READ, changed:
-*      LDX V$DRIV,x
-*      ADDW M$Exec,x
-*      JSR w,x
-* to:
-*      LDW V$DRIV,x
-*      ADDW M$Exec,w
-*      JSR D$READ,w
-* Did same to L05C9 & L056F (should speed up each by 1 cycle)
-*
-*          1994/06/07  ???
-* Attempted to modify all M$Exec calls to use new V$DRIVEX (REQUIRES NEW IOMAN)
-* - L01FA (Get/SetStat), L03F1 (Read), L05C9 (Write), L056F (Write)
-* - Changed L046A to use LDB V.BUSY,x...CMPB ,s...TFR B,A
-*
-*          1994/06/08  ???
-* Changed TST <PD.EKO,y in read loop (L02BC) to LDB PD.EKO,y
-* - Changed LEAX 1,X to LDB #1/ABX @ L02C4
-* - Changed LEAX >L033F,pc @ L032C to use < (8 bit) version
-* - Modified L02E5 to use D instead of X, allowing TSTA, and faster exit on 0 byte
-*   just BRAnching to L0453
-*
-*          1994/06/09  ???
-* Changed LEAX 1,X to LDB #1/ABX @ L053D, L05F8, L0312, L0351, L03B8
-* - Changed to L0573: All TST's changed to LDB's
-* - Changed Open/Create init to use LEAX,PC instead of BSR/PULS X
-* - Changed TST PD.CNT,y to LDA PD.CNT,y @ close
-* - Eliminated L010D, changed references to it to go to L0129
-* - Eliminated useless LEAX ,X @ L0182, and changed BEQ @ L0182 to go to L012A
-*   instead of L0129 (speeds CLOSE by 5 or 10 cycles)
-* - Moved L06B9 into L012B, eliminate BSR/RTS, plus
-* - Changed TST V.TYPE,x to LDB V.TYPE,x
-* - Moved L0624 to just before L05F8 to eliminate BRA L05F8 (ReadLn)
-* - Changed TST PD.EKO,y @ L0413 to LDB PD.EKO,y
-* - Moved L0413-L0423 routines to later in code to allow short branches
-* - As result of above, changed 6 LBxx to Bxx
-* - Changed TST PD.MIN,y @ L04BB to LDA PD.MIN,y
-* - Changed TST PD.RAW,y/TST PD.UPC,y @ L0523 to LDB's
-* - Changed TST PD.ALF,y @ L052A to LDB
-* - L053D: Moved TST PD.RAW,y to before LDA -1,u to speed up WRITE, changed it to LDB
-*
-*          1994/06/10  ???
-* Changed TST PD.ALF,y to LDB @ L052A
-* - Changed CLR V.WAKE,u to CLRA/STA V.WAKE,u @ L03F1 (Read)
-* - Changed CLR V.BUSY,u to CLRA/STA V.BUSY,u @ L045D
-* - Changed CLR PD.MIN,y to CLRA/STA PD.MIN,y, moved before LDA P$ID,x @ L04A7
-* - Changed CLR PD.RAW,y @ L04BB to STA PD.RAW, since A already 0 to get there
-* - Changed CLR V.PAUS,u to CLRA/STA V.PAUS,u @ L05A2
-* - Changed TST PD.RAW,y to LDA PD.RAW,y @ L05A2
-* - Changed TST PD.ALF,y to LDA PD.ALF,y @ L05A2
-* - Changed CLR V.WAKE,u to CLRB/STB V.WAKE,u @ L05C9
-* - Changed CLR V.WAKE,u to CLRB/STB V.WAKE,u @ L056F
-* - Changed TST PD.UPC,y to LDB PD.UPC,y @ L0322
-* - Changed TST PD.DLO,y/TST PD.EKO,y to LDB's @ L03A5
-*
-*          1994/06/16  ???
-* Changed TST PD.UPC,y to LDB PD.UPC,y @ L0322
-* - Changed TST PD.BSO,y to LDB PD.BSO,y @ L03BF
-* - Changed TST PD.EKO,y to LDB PD.EKO,y @ L03BF
-*
-*          2002/10/11  Boisy G. Pitre
-* Merged NitrOS-9 and TuneUp versions for single-source maintenance.  Note that
-* the 6809 version of TuneUp never seemed to call GrfDrv directly to do fast screen
-* writes (see note around g.done label).
-*
-*  16r2    2002/05/16  Boisy G. Pitre
-* Removed pshs/puls of b from sharable code segment for non-NitrOS-9 because it was
-* not needed.
-*
-*  16r3    2002/08/16  Boisy G. Pitre
-* Now uses V$DRIVEX.
-*
-*  16r4    2004/07/12  Boisy G. Pitre
-* 6809 version now calls the FAST TEXT entry point of GrfDrv.
-*
-*  17      2010/01/15  Boisy G. Pitre
-* Fix for bug described in Artifact 2932883 on SF
-* Also added Level 1 conditionals for eventual backporting
-
-*
-*  17      2010/01/15  Boisy G. Pitre
-* Handling of device exclusivity using the SHARE. bit has been rearchitected.
-* The '93 patch looked at the mode bytes in the descriptor and driver and
-* determined that if both were set, then only one path would be allowed to
-* be opened on the device at a time.
-* I now believe this is wrong.
-* The mode bytes in the device driver and descriptor are capability bytes.
-* They advertise what the device is capable of doing (READ, WRITE, etc) so
-* the mode bytes alone do not convey action, but merely what is possible.
-* When the user calls I$Open on a device, he passes the desired mode byte
-* in RegA and IOMan checks to make sure that all bits in that register are
-* set in the mode bytes of the driver and descriptor.  So once we get into
-* the Open call of this file manager, we know that all set bits in RegA are
-* also set in the mode bytes of the driver and descriptor.
-*
-* For SHARE., what we SHOULD be doing is checking the number of open paths
-* on the device.  If the SHARE. bit is set in RegA, then we check if a path
-* is already open and if so, return the E$DevBsy error.
-* Likewise, if SHARE. is not set in RegA, we check the path at the head of
-* the open path list, and if ITS mode byte has the SHARE. bit set, we exit
-* with E$DevBsy too.  The idea is that if the SHARE. bit is set on the newly
-* opened path or an existing path, then there can "be only one."
-*
-*  17r1    2010/01/23  Boisy G. Pitre
-* SCF now returns on carry set after calling SS.Open.  Prior to this
-* change, SS.ComSt would be called right after SS.Open even if SS.Open
-* failed. This caused misery with the scdwn driver wildcard feature.
-
-         nam   SCF
-         ttl   NitrOS-9 Level 2 Sequential Character File Manager
-
-         IFP1
-         use   defsfile
-         use   scfdefs
-         ENDC
-
-tylg     set   FlMgr+Objct
-atrv     set   ReEnt+rev
-rev      set   1
-edition  equ   17
-
-         mod   eom,SCFName,tylg,atrv,SCFEnt,0
-
-SCFName  fcs   /SCF/
-         fcb   edition
-
-
-* Default input buffer setting for SCF devices when Opened/Created
-*               123456789!123456789!1234567890
-*msg      fcc   'by B.Nobel,C.Boyle,W.Gale-1993'
-msg      fcc   'www.nitros9.org'
-msgsize  equ   *-msg        Size of default input buffer message
-         fcb   C$CR         2nd CR for buffer pad fill
-blksize  equ   256-msgsize  Size of blank space after it
-
-* Return bad pathname error
-opbpnam  puls  y
-bpnam    comb               Set carry for error
-         ldb   #E$BPNam     Get error code
-oerr     rts                Return to caller
-
-* I$Create/I$Open entry point
-* Entry: Y= Path dsc. ptr
-open     ldx   PD.DEV,y     Get device table pointer
-         stx   PD.TBL,y     Save it
-         ldu   PD.RGS,y     Get callers register stack pointer
-         pshs  y            Save path descriptor pointer
-         ldx   R$X,u        Get pointer to device pathname
-         os9   F$PrsNam     Parse it
-         bcs   opbpnam      Error, exit
-         tsta               End of pathname?
-         bmi   open1        Yes, go on
-         leax  ,y           Point to actual device name
-         os9   F$PrsNam     Parse it again
-         bcc   opbpnam      Return to caller with bad path name if more
-open1    sty   R$X,u        Save updated name pointer to caller
-         puls  y            Restore path descriptor pointer
-         ldd   #256         Get size of input buffer in bytes
-         os9   F$SRqMem     Allocate it
-         bcs   oerr         Can't allocate it return with error
-         stu   PD.BUF,y     Save buffer address to path descriptor
-         leax  <msg,pc      Get ptr to init string
-
-         IFNE  H6309
-
-         ldw   #msgsize     get size of default message
-         tfm   x+,u+        Copy it into buffer (leaves X pointing to 2nd CR)
-         ldw   #blksize     Size of rest of buffer
-         tfm   x,u+         Fill rest of buffer with CR's
-
-         ELSE
-
-CopyMsg  lda   ,x+
-         sta   ,u+
-         decb
-         cmpa  #C$CR
-         bne   CopyMsg
-CopyCR   sta   ,u+
-         decb
-         bne   CopyCR
-
-         ENDC
-
-         ldu   PD.DEV,y     Get device table entry address
-         beq   bpnam        Doesn't exist, exit with bad pathname error
-         ldx   V$STAT,u     Get devices' static storage address
-         lda   PD.PAG,y     Get devices page length
-         sta   V.LINE,x     Save it to devices static storage
-         ldx   V$DESC,u     Get descriptor address
-         ldd   PD.D2P,y     Get offset to device name (duplicate from dev dsc)
-         beq   L00CF        None, skip ahead
-
-         IFNE  H6309
-
-         addr  d,x          Point to device name in descriptor
-         lda   PD.MOD,y     Get device mode (Read/Write/Update)
-         lsrd               ??? (swap Read/Write bits around in A?)
-
-         ELSE
-
-         leax  d,x
-         lda   PD.MOD,y     Get device mode (Read/Write/Update)
-         lsra
-         rorb
-
-         ENDC
-
-         lsra
-         rolb
-         rola
-         rorb
-         rola
-         IFGT  Level-1
-         pshs  y            Save path descriptor pointer temporarily
-         ldy   <D.Proc      Get current process pointer
-         ldu   <D.SysPrc    Get system process descriptor pointer
-         stu   <D.Proc      Make system current process
-         ENDC
-         os9   I$Attach     Attempt to attach to device name in device desc.
-         IFGT  Level-1
-         sty   <D.Proc      Restore old current process pointer
-         puls  y            Restore path descriptor pointer
-         ENDC
-         bcs   OpenErr     Couldn't attach to device, detach & exit with error
-         stu   PD.DV2,y     Save new output (echo) device table pointer
-*         ldu   PD.DEV,y     Get device table pointer
-L00CF    ldu   V$STAT,u     Point to it's static storage
-
-         IFNE  H6309
-
-         clrd
-
-         ELSE
-
-         clra
-         clrb
-
-         ENDC
-
-         std   PD.PLP,y     Clear out path descriptor list pointer
-         sta   PD.PST,y     Clear path status: Carrier not lost
-         pshs  d            Save 0 on stack
-         ldx   V.PDLHd,u    Get path descriptor list header pointer
-* 05/25/93 mod - Boisy Pitre's non-sharable device patches
-* 01/15/10 mod - Boisy Pitre redoes his non-sharable device patch
-         beq   Yespath      No paths open, so we know we can open it
-* IOMan has already vetted the mode byte of the driver and the descriptor
-* and compared it to REGA of I$Open (now in PD.MOD of this current path).
-* here we know there is at least one path open for this device.
-* in order to properly support SHARE. (device exclusivity), we get the
-* mode byte for the path we are opening and see if the SHARE. bit is set.
-* if so, then we return error since we cannot have exclusivity to the device.
-         IFNE  H6309
-         tim   #SHARE.,PD.MOD,y
-         ELSE
-         lda   PD.MOD,y 
-         bita  #SHARE.
-         ENDC
-         bne   NoShare      
-* we now know that the path's mode doesn't have the SHARE. bit set, so 
-* we need to look at the mode of the path in the list header pointer to
-* see if ITS SHARE. bit is set (meaning it wants exclusive access to the
-* port).  If so we bail out
-         IFNE  H6309
-         tim   #SHARE.,PD.MOD,x
-         ELSE
-         lda   PD.MOD,x 
-         bita  #SHARE.
-         ENDC
-         beq   CkCar        Check carrier status
-NoShare  leas  2,s          Eat extra stack (including good path count)
-         comb
-         ldb   #E$DevBsy    Non-sharable device busy error
-         bra   OpenErr       Go detach device & exit with error
-         
-Yespath  sty   V.PDLHd,u    Save path descriptor ptr
-         bra   L00F8        Go open the path
-
-L00E6    tfr   d,x          Change to PD.PLP path descriptor
-CkCar    ldb   PD.PST,x     Get Carrier status
-         bne   L00EF        Carrier was lost, don't update count
-         inc   1,s          Carrier not lost, bump up count of good paths
-L00EF    ldd   PD.PLP,x     Get path descriptor list pointer
-         bne   L00E6        There is one, go make it the current one
-         sty   PD.PLP,x     Save path descriptor ptr as path dsc. list ptr
-L00F8    lda   #SS.Open     Internal open call
-         pshs  a            Save it on the stack
-         inc   2,s          Bump counter of good paths up by 1
-         lbsr  L025B        Do the SS.Open call to the driver
-         lda   2,s          Get counter of good paths
-         leas  3,s          Eat stack
-* NEW: return with error if SS.Open return error
-         bcs   L010F        +++BGP+++
-         deca               Bump down good path count
-         bne   L0129        If more still open, exit without error
-         blo   L010F        If negative, something went wrong
-         lbra  L0250        Set parity/baud & return
-
-* we come here if there was an error in Open (after I$Attach and F$SRqMem!)
-L010F    bsr   L0149        Error, go clear stuff out
-OpenErr  pshs  b,cc         Preserve error status
-         bsr   L0136        Detach device
-         puls  pc,b,cc      Restore error status & return
-
-* I$Close entry point
-close    pshs  cc           Preserve interrupt status
-         orcc  #IntMasks    Disable interrupts
-         ldx   PD.DEV,y     Get device table pointer
-         bsr   L0182        Check it
-         ldx   PD.DV2,y     Get output device table pointer
-         bsr   L0182        Check it
-         puls  cc           Restore interrupts
-         lda   PD.CNT,y     Any open images?
-         beq   L012B        No, go on
-L0129    clra               Clear carry
-L012A    rts                Return
-
-* Detach device & return buffer memory
-L012B    bsr   L0149
-         lda   #SS.Close    Get setstat code for close
-         ldx   PD.DEV,y     get pointer to device table
-         ldx   V$STAT,x     get static mem ptr
-         ldb   V.TYPE,x     Get device type    \ WON'T THIS SCREW UP WITH
-         bmi   L0136        Window, skip ahead / MARK OR SPACE PARITY???
-         pshs  x,a          Save close code & X for SS.Close calling routine
-         lbsr  L025B        Not window, go call driver's SS.Close routine
-         leas  3,s          Purge stack
-L0136    ldu   PD.DV2,y     Get output device pointer
-         beq   L013D        Nothing there, go on
-         os9   I$Detach     Detach it
-L013D    ldu   PD.BUF,y     Get buffer pointer
-         beq   L0147        None defined go on
-         ldd   #256         Get buffer size
-         os9   F$SRtMem     Return buffer memory to system
-L0147    clra               Clear carry
-         rts                Return
-
-L0149    ldx   #1
-         pshs  cc,d,x,y,u
-         ldu   PD.DEV,y     Get device table pointer
-         beq   L017B        None, skip ahead
-         ldu   V$STAT,u     Get static storage pointer
-         beq   L017B        None, skip ahead
-         ldx   V.PDLHd,u    Get path descriptor list header
-         beq   L017B        None, skip ahead
-         ldd   PD.PLP,y     Get path descriptor list pointer
-         cmpy  V.PDLHd,u
-         bne   L0172
-         std   V.PDLHd,u
-         bne   L017B
-         clr   4,s          Clear LSB of X on stack
-         bra   L017B        Return
-
-L016D    ldx   PD.PLP,x
-         beq   L0180
-L0172    cmpy  PD.PLP,x
-         bne   L016D
-         std   PD.PLP,x
-
-         IFNE  H6309
-
-L017B    clrd
-
-         ELSE
-
-L017B    clra
-         clrb
-
-         ENDC
-
-         std   PD.PLP,y
-L0180    puls  cc,d,x,y,u,pc
-
-
-* Check path number?
-* Entry: X=Ptr to device table (just LDX'd)
-*        Y=Path dsc. ptr
-L0182    beq   L012A        No device table, return to caller
-         ldx   V$STAT,x     Get static storage pointer
-         ldb   PD.PD,y      Get system path number from path dsc.
-         lda   PD.CPR,y     Get ID # of process currently using path
-         pshs  d,x,y        Save everything
-         cmpa  V.LPRC,x     Current process same as last process using path?
-         bne   L01CA        No, return
-         IFGT  Level-1
-         ldx   <D.Proc      Get current process pointer
-         ELSE
-         ldx   >D.Proc      Get current process pointer
-         ENDC
-         leax  P$Path,x     Point to local path table
-         clra               Start path # = 0 (Std In)
-L0198    cmpb  a,x          Same path as one is process' local path list?
-         beq   L01CA        Yes, return
-         inca               Move to next path
-         cmpa  #NumPaths    Done all paths?
-         blo   L0198        No, keep going
-         pshs  y            Preserve path descriptor pointer
-
-         IFNE  H6309
-
-         lda   #SS.Relea    Release signals SetStat
-         ldf   #D$PSTA      Get Setstat offset
-
-         ELSE
-
-         ldd   #SS.Relea*256+D$PSTA
-
-         ENDC
-
-         bsr   L01FA        Execute driver setstat routine
-         puls  y            Restore path pointer
-         IFGT  Level-1
-         ldx   <D.Proc      Get current process pointer
-         ELSE
-         ldx   >D.Proc      Get current process pointer
-         ENDC
-         lda   P$PID,x      Get parent process ID
-         sta   ,s           Save it
-         IFGT  Level-1
-         os9   F$GProcP     Get pointer to parent process descriptor
-         ELSE
-         ldx   <D.PrcDBT
-         os9   F$Find64
-         ENDC
-         leax  P$Path,y     Point to local path table
-         ldb   1,s          Get path number
-         clra               Get starting path number
-L01B9    cmpb  a,x          Same path?
-         beq   L01C4        Yes, go on
-         inca               Move to next path
-         cmpa  #NumPaths    Done all paths?
-         blo   L01B9        No, keep checking
-         clr   ,s           Clear process ID
-L01C4    lda   ,s           Get process ID
-         ldx   2,s          Get static storage pointer
-         sta   V.LPRC,x     Store it as last process
-L01CA    puls  d,x,y,pc     Restore & return
-
-* I$GetStt entry point
-getstt   lda   PD.PST,y     Path status ok?
-         lbne  L04C6        No, terminate process
-         ldx   PD.RGS,y     Get register stack pointer
-         lda   R$B,x        Get function code
-         bne   L01F8        If not SS.Opt, go on
-* SS.Opt Getstat
-         pshs  a,x,y        Preserve registers
-         lda   #SS.ComSt    Get code for Comstat
-         sta   R$B,x        Save it in callers B
-         ldu   R$Y,x        Preserve callers Y
-         pshs  u
-         bsr   L01F8        Send it to driver
-         puls  u            Restore callers Y
-         puls  a,x,y        Restore registers
-         sta   R$B,x        Do SS.OPT
-         ldd   R$Y,x        Get com stat
-         stu   R$Y,x        Put original callers Y back
-         bcs   L01F6        Return if error
-         std   PD.PAR,y     Update path descriptor
-L01F6    clrb               Clear carry
-L01F7    rts                Return
-
-* Execute device driver Get/Set Status routine
-* Entry: A=GetStat/SetStat code
-
-         IFNE  H6309
-
-L01F8    ldf   #D$GSTA      Get Getstat driver entry offset
-L01FA    ldx   PD.DEV,y     Get device table pointer
-         ldu   V$STAT,x     Get static storage pointer
-         IFGT  Level-1
-         ldx   V$DRIVEX,x   get execution pointer of driver
-         ELSE
-         pshs  d
-         ldx   V$DRIV,x     get driver module
-         ldd   M$EXEC,x
-         leax  d,x
-         puls  d
-         ENDC
-         pshs  y,u          Preserve registers
-         jsr   f,x          Execute driver
-         puls  y,u,pc       Restore & return
-
-         ELSE
-
-L01F8    ldb   #D$GSTA
-L01FA    ldx   PD.DEV,y
-         ldu   V$STAT,x
-         IFGT  Level-1
-         ldx   V$DRIVEX,x
-         ELSE
-         pshs  d
-         ldx   V$DRIV,x     get driver module
-         ldd   M$EXEC,x
-         leax  d,x
-         puls  d
-         ENDC
-         pshs  u,y
-LC486    jsr   b,x
-         puls  y,u,pc
-
-         ENDC
-
-
-* I$SetStt entry point
-setstt   lbsr  L04A2
-L0212    bsr   L021B        Check codes
-         pshs  cc,b         Preserve registers
-         lbsr  L0453        Wait for device
-         puls  cc,b,pc      Restore & return
-
-putkey   cmpa  #SS.Fill     Buffer preload?
-         bne   L01FA        No, go execute driver setstat
-         IFEQ  H6309
-         pshs  u,y,x
-         ENDC
-         IFGT  Level-1
-         ldx   <D.Proc      Get current process pointer
-         ELSE
-         ldx   >D.Proc      Get current process pointer
-         ENDC
-         lda   R$Y,u        Get flag byte for CR/NO CR
-         pshs  a            Save it
-         IFGT  Level-1
-         lda   P$Task,x     Get task number
-         ldb   <D.SysTsk    Get system task
-         IFNE  H6309
-         ldx   R$X,u        Get pointer to data to move
-         ldf   R$Y+1,u      Get number of bytes (max size of 256 bytes)
-         ldu   PD.BUF,y     Get input buffer pointer
-         clre               High byte of Y
-         tfr   w,y          Move size into proper register for F$Move
-         ELSE
-         pshs  d
-         clra
-         ldb   R$Y+1,u
-         ldx   R$X,u
-         ldu   PD.BUF,y
-         tfr   d,y
-         puls  d
-         ENDC
-* X=Source ptr from caller, Y=# bytes to move, U=Input buffer ptr
-         os9   F$Move       Move it
-         bcs   putkey1      Exit if error
-         tfr   y,d          Move number of bytes to D
-         ELSE
-loop
-         lda   ,x+
-         sta   ,u+
-         leay  -1,y
-         bne   loop
-         ENDC
-         lda   ,s           Get CR flag
-         bmi   putkey1      Don't want CR appended, exit
-         lda   #C$CR        Get code for carriage return
-         sta   b,u          Put it in buffer to terminate string
-         IFNE  H6309
-putkey1  puls  a,pc         Eat stack & return
-L021B    ldf   #D$PSTA      Get driver entry offset for setstat
-         ELSE
-putkey1  puls  a,x,y,u,pc   Eat stack & return
-L021B    ldb   #D$PSTA      Get driver entry offset for setstat
-         ENDC
-         lda   R$B,u        Get function code from caller
-         bne   putkey       Not SS.OPT, go check buffer load
-* SS.OPT SETSTAT
-         ldx   PD.PAU,y     Get current pause & page
-         IFGT  Level-1
-         pshs  y,x          Preserve Path pointer & pause/page
-         ldx   <D.Proc      Get current process pointer
-         lda   P$Task,x     Get task number
-         ldb   <D.SysTsk    Get system task number
-         ldx   R$X,u        Get callers destination pointer
-         leau  PD.OPT,y     Point to path options
-         ldy   #OPTCNT      Get option length
-         os9   F$Move       Move it to caller
-         puls  y,x          Restore Path pointer & page/pause status
-         bcs   L01F7        Return if error from move
-         ELSE
-         pshs  x,y
-         ldx   R$X,u
-         leay  PD.OPT,y
-         ldb   #OPTCNT
-optloop
-         lda   ,x+
-         sta   ,y+
-         decb
-         bne   optloop
-         puls  x,y
-         ENDC
-         IFEQ  H6309
-         pshs  x
-         ENDC
-         ldd   PD.PAU,y     Get new page/pause status
-         IFNE  H6309
-         cmpr  d,x          Same as old?
-         ELSE
-         cmpd  ,s++
-         ENDC
-         beq   L0250        Yes, go on
-         ldu   PD.DEV,y     Get device table pointer
-         ldu   V$STAT,u     Get static storage pointer
-         beq   L0250        Go on if none
-         stb   V.LINE,u     Update new line count
-L0250    ldx   PD.PAR,y     Get parity/baud
-         lda   #SS.ComSt    Get code for ComSt
-         pshs  a,x          Preserve them 
-         bsr   L025B        Update parity & baud
-         puls  a,x,pc       Restore & return
-
-* Update path Parity & baud
-L025B    pshs  x,y,u        Preserve everything
-         ldx   PD.RGS,y     Get callers register pointer
-         ldu   R$Y,x        Get his Y
-         lda   R$B,x        Get his B
-         pshs  a,x,y,u      Preserve it all
-         ldd   $10,s        Get current parity/baud
-         std   R$Y,x        Put it in callers Y
-         lda   $0F,s        Get function code
-         sta   R$B,x        Put it in callers B
-         IFEQ  H6309
-         ldb   #$0C
-         ENDC
-         lbsr  L04A7        Wait for device to be ready
-         lbsr  L0212        Send it to driver
-         puls  a,x,y,u      Restore callers registers
-         stu   R$Y,x        Put back his Y
-         sta   R$B,x        Put back his B
-         bcc   L0282        Return if no error
-         cmpb  #E$UnkSvc    Unknown service request?
-         beq   L0282        Yes, return
-         coma               Set carry
-L0282    puls  x,y,u,pc     Restore & return
-
-* I$Read entry point
-read     lbsr  L04A2        Go wait for device to be ready for us
-         bcc   L028A        No error, go on
-L0289    rts                Return with error
-L028A    inc   PD.RAW,y     Make sure we do Raw read
-         ldx   R$Y,u        Get number of characters to read
-         beq   L02DC        Return if zero
-         pshs  x            Save character count
-         ldx   #0
-         ldu   PD.BUF,y     Get buffer address
-         bsr   L03E2        Read 1 character from device
-         bcs   L02A4        Return if error
-         tsta               Character read zero?
-         beq   L02C4        Yes, go try again
-         cmpa  PD.EOF,y     End of file character?
-         bne   L02BC        No, keep checking
-L02A2    ldb   #E$EOF       Get EOF error code
-L02A4    leas  2,s          Purge stack
-         pshs  b            Save error code
-         bsr   L02D5        Return
-         comb               Set carry
-         puls  b,pc         Restore & return
-
-******************************
-*
-* SCF file manager entry point
-*
-* Entry: Y = Path descriptor pointer
-*        U = Callers register stack pointer
-*
-
-SCFEnt   lbra  open         Create path
-         lbra  open         Open path
-         lbra  bpnam        Makdir
-         lbra  bpnam        Chgdir
-         lbra  L0129        Delete (return no error)
-         lbra  L0129        Seek (return no error)
-         bra   read         Read character
-         nop
-         lbra  write        Write character
-         lbra  readln       ReadLn
-         lbra  writln       WriteLn
-         lbra  getstt       Get Status
-         lbra  setstt       Set Status
-         lbra  close        Close path
-
-* MAIN READ LOOP (no editing)
-L02AD    tfr   x,d          move character count to D
-         tstb               past buffer end?
-         bne   L02B7        no, go get character from device
-* Not often used: only when buffer is full
-         bsr   L042B        move buffer to caller's buffer
-         ldu   PD.BUF,y     reset buffer pointer back to start
-* Main char by char read loop
-L02B7    bsr   L03E2        get a character from device
-         bcs   L02A4        exit if error
-L02BC    ldb   PD.EKO,y     echo turned on?
-         beq   L02C4        no, don't write it to device
-         lbsr  L0565        send it to device write
-L02C4    ldb   #1           Bump up char count
-         abx
-         sta   ,u+          save character in local buffer
-         beq   L02CF        go try again if it was a null
-         cmpa  PD.EOR,y     end of record charcter?
-         beq   L02D3        yes, return
-L02CF    cmpx  ,s           done read?
-         blo   L02AD        no, keep going till we are
-
-L02D3    leas  2,s          purge stack
-L02D5    bsr   L042B        move local buffer to caller
-         ldu   PD.RGS,y     get register stack pointer
-         stx   R$Y,u        save number of characters read
-L02DC    bra   L0453        update path descriptor and return
-
-* Read character from device
-L03E2    pshs  u,y,x        Preserve regs
-         ldx   PD.DEV,y     Get device table pointer for input
-         beq   L0401        None, exit
-         ldu   PD.DV2,y     Get device table pointer for echoed output
-         beq   L03F1        No echoed output device, skip ahead
-L03EA    ldu   V$STAT,u     Get device static storage ptr for echo device
-         ldb   PD.PAG,y     Get lines per page
-         stb   V.Line,u     Store it in device static
-L03F1    tfr   u,d          Yes, move echo device' static storage to D
-         ldu   V$STAT,x     Get static storage ptr for input
-         std   V.DEV2,u     Save echo device's static storage into input device
-         clra
-         sta   V.WAKE,u     Flag input device to be awake
-         IFGT  Level-1
-         ldx   V$DRIVEX,x   Get driver execution pointer
-         ELSE
-         pshs  d
-         ldx   V$DRIV,x     get driver module
-         ldd   M$EXEC,x
-         leax  d,x
-         puls  d
-         ENDC
-         jsr   D$READ,x     Execute READ routine in driver
-L0401    puls  pc,u,y,x     Restore regs & return
-
-* Move buffer to caller
-* Entry: Y=Path dsc. ptr
-*        X=# chars to move
-L042B    pshs  y,x            Preserve path dsc. ptr & char. count
-         ldd   ,s             Get # bytes to move
-         beq   L0451          Exit if none
-         tstb                 Uneven # bytes (not even page of 256)?
-         bne   L0435          Yes, go on
-         deca                 >256, so bump MSB down
-L0435    clrb                 Force to even page
-         ldu   PD.RGS,y       Get callers register stack pointer
-         ldu   R$X,u          Get ptr to caller's buffer
-         IFNE  H6309
-         addr  d,u            Offset to even page into buffer
-         clre                 Clear MSB of count
-         ldf   1,s            LSB of count on even page?
-         bne   L0442          No, go on
-         ince                 Make it even 256 
-L0442
-         IFGT  Level-1
-         lda   <D.SysTsk      Get source task number
-         ENDC
-         ELSE
-         leau  d,u
-         clra
-         ldb   1,s
-         bne   L0442          No, go on
-         inca
-L0442    pshs  d
-         IFGT  Level-1
-         lda   <D.SysTsk      Get source task number
-         ENDC
-         ENDC
-         IFGT  Level-1
-         ldx   <D.Proc        Get destination task number
-         ldb   P$Task,x
-         ldx   PD.BUF,y       Get buffer pointer
-         IFNE  H6309
-         tfr   w,y            Put count into proper register
-         ELSE
-         puls  y
-         ENDC
-         os9   F$Move         Move it to caller
-         ELSE
-         puls  y
-         pshs  u
-L0443
-         lda   ,x+
-         sta   ,u+
-         leay  -1,y
-         bne   L0443
-         puls  u
-         ENDC
-L0451    puls  pc,y,x         Restore & return
-
-* I$ReadLn entry point
-readln   bsr   L04A2        Go wait for device to be ready for us
-         bcc   L02E5        No error, continue
-         rts                Error, exit with it
-L02E5    ldd   R$Y,u        Get character count
-         beq   L0453        If none, mark device as un-busy
-         tsta               Past 256 bytes?
-         beq   L02EF        No, go on
-         ldd   #$0100       Get new character count
-L02EF    pshs  d            Save character count
-         ldd   #$FFFF       Get maximum character count
-         std   PD.MAX,y     Store it in path descriptor
-         ldx   #0           Set character count so far to 0
-         ldu   PD.BUF,y     Get buffer ptr
-         lbra  L05F8        Go process readln
-
-* Wait for device - Clears out V.BUSY if either Default or output devices are
-* no longer busy
-* Modifies X and A
-L0453 
-         IFGT  Level-1
-         ldx   <D.Proc        Get current process
-         ELSE
-         ldx   >D.Proc        Get current process
-         ENDC
-         lda   P$ID,x         Get it's process ID
-         ldx   PD.DEV,y       Get device table pointer from our path dsc.
-         bsr   L045D          Check if it's busy
-         ldx   PD.DV2,y       Get output device table pointer
-L045D    beq   L0467          Doesn't exist, exit
-         ldx   V$STAT,x       Get static storage pointer for our device
-         cmpa  V.BUSY,x       Same process as current process?
-         bne   L0467          No, device busy return
-         clra
-         sta   V.BUSY,x       Yes, mark device as free for use
-L0467    rts                  Return
-
-L0468    pshs  x,a            Preserve device table entry pointer & process ID
-L046A    ldx   V$STAT,x       Get device static storage address
-         ldb   V.BUSY,x       Get active process ID
-         beq   L048A          No active process, device not busy go reserve it
-         cmpb  ,s             Is it our own process?
-         beq   L049F          Yes, return without error
-         bsr   L0453          Go wait for device to no longer be busy
-         tfr   b,a            Get process # busy using device
-         os9   F$IOQu         Put our process into the IO Queue
-         inc   PD.MIN,y       Mark device as not mine
-         IFGT  Level-1
-         ldx   <D.Proc        Get current process
-         ELSE
-         ldx   >D.Proc        Get current process
-         ENDC
-         ldb   P$Signal,x     Get signal code
-         lda   ,s             Get our process id # again for L046A
-         beq   L046A          No signal go try again
-         coma                 Set carry
-         puls  x,a,pc         Restore device table ptr (eat a) & return
-
-* Mark device as busy;copy pause/interrupt/quit/xon/xoff chars into static mem
-L048A    sta   V.BUSY,x       Make it as process # busy on this device
-         sta   V.LPRC,x       Save it as the last process to use device
-         lda   PD.PSC,y       Get pause character from path dsc.
-         sta   V.PCHR,x       Save copy in static storage (faster later)
-         ldd   PD.INT,y       Get keyboard interrupt & quit chars
-         std   V.INTR,x       Save copies in static mem
-         ldd   PD.XON,y       Get XON/XOFF chars
-         std   V.XON,x        Save them in static mem too
-L049F    clra                 No error & return
-         puls  pc,x,a         Restore A=Process #,X=Dev table entry ptr
-
-* Wait for device?
-L04A2    lda   PD.PST,y       Get path status (carrier)
-         bne   L04C4          If carrier was lost, hang up process
-L04A7
-         IFGT  Level-1
-         ldx   <D.Proc        Get current process ID
-         ELSE
-         ldx   >D.Proc        Get current process ID
-         ENDC
-         clra
-         sta   PD.MIN,y       Flag device is mine
-         lda   P$ID,x         Get process ID #
-         ldx   PD.DEV,y       Get device table pointer
-         bsr   L0468          Busy?
-         bcs   L04C1          No, return
-         ldx   PD.DV2,y       Get output device table pointer
-         beq   L04BB          Go on if it doesn't exist
-         bsr   L0468          Busy?
-         bcs   L04C1          No, return
-L04BB    lda   PD.MIN,y       Device mine?
-         bne   L04A2          No, go wait for it
-         sta   PD.RAW,y       Mark device with editing
-L04C1    ldu   PD.RGS,y       Get register stack pointer
-         rts                  Return
-
-* Hangup process
-L04C4    leas  2,s            Purge return address
-L04C6    ldb   #E$HangUp      Get hangup error code
-         cmpa  #S$Abort       Termination signal (or carrier lost)?
-         blo   L04D3          Yes, increment status flag & return
-         lda   PD.CPR,y       Get current process ID # using path
-         ldb   #S$Kill        Get kill signal
-         os9   F$Send         Send it to process
-L04D3    inc   PD.PST,y       Set path status
-         orcc  #Carry         Set carry
-         rts                  Return
-
-* I$WritLn entry point
-writln   bsr   L04A2          Go wait for device to be ready for us
-         bra   L04E1          Go write
-
-* I$Write entry point
-write    bsr   L04A2          Go wait for device to be ready for us
-         inc   PD.RAW,y       Mark device for raw write
-L04E1    ldx   R$Y,u          Get number of characters to write
-         lbeq  L055A          Zero so return
-         pshs  x              Save character count
-         ldx   #$0000         Get write data offset
-         bra   L04F1          Go write data
-
-L04EC    tfr   u,d            Move current position in PD.BUF to D
-         tstb                 At 256 (end of PD.BUF)?
-         bne   L0523          No, keep writing from current PD.BUF
-
-* Get new block of data to write into [PD.BUF]
-* Only allows up to 32 bytes at a time, and puts them in the last 32 bytes of
-* the 256 byte [PD.BUF] buffer. This way, can use TFR U,D/TSTB to see if fin-
-* inshed
-L04F1    pshs  y,x            Save write offset & path descriptor pointer
-         tfr   x,d            Move data offset to D
-         ldu   PD.RGS,y       Get register stack pointer
-         ldx   R$X,u          Get pointer to users's WRITE string
-         IFNE  H6309
-         addr  d,x            Point to where we are in it now
-         ldw   R$Y,u          Get # chars of original write
-         subr  d,w            Calculate # chars we have left to write
-         cmpw  #64            More than 64?
-         bls   L0508          No, go on
-         ldw   #64            Max size per chunk=64
-L0508    ldd   PD.BUF,y       Get buffer ptr
-         inca                 Point to PD.BUF+256 (1 byte past end
-         subr  w,d            Subtract data size
-         ELSE
-         leax  d,x
-         ldd   R$Y,u
-         subd  ,s
-         cmpd  #$0020
-         bls   L0508
-         ldd   #$0020
-L0508    pshs  d
-         ldd   PD.BUF,y
-         inca
-         subd  ,s
-         ENDC
-         tfr   d,u            Move it to U
-         lda   #C$CR          Put a carriage return 1 byte before start
-         sta   -1,u           of write portion of buffer
-         IFGT  Level-1
-         ldy   <D.Proc        Get current process pointer
-         lda   P$Task,y       Get the task number
-         ldb   <D.SysTsk      Get system task number
-         IFNE  H6309
-         tfr   w,y            Get number of bytes to move
-         ELSE
-         puls  y
-         ENDC
-         os9   F$Move         Move data to buffer
-         ELSE
-         puls  y
-         pshs  u
-L0509    lda   ,x+
-         sta   ,u+
-         leay  -1,y
-         bne   L0509
-         puls  u
-         ENDC
-         puls  y,x            Restore path descriptor pointer and data offset
-
-* at this point, we have
-* 0,s = end address of characters to write
-* X = number of characters written
-* Y = PD pointer
-* U = pointer to data buffer to write
-* Use callcode $06 to call grfdrv (old DWProtSW from previous versions,
-*   now unused by GrfDrv
-L0523    ldb   PD.PAR,y     get device parity: bit 7 set = window
-         cmpb  #$80         is it even potentially a CoWin window?
-         bne   L0524        no, skip the rest of the crap
-
-         clrb               set to no uppercase conversion
-         lda   PD.RAW,y     get raw output flag
-         bne   g.raw        if non-zero, we do raw writes: no conversion
-         ldb   PD.UPC,y     get uppercase conversion flag: 1 = do uppercase
-
-g.raw    pshs  b,x,y,u      save length, PD, data buffer pointers
-
-         IFGT  Level-1
-         lbsr  get.wptr     get window table ptr into Y
-         bcs   no.wptr      do old method on error
-
-* now we find out the number of non-control characters to write...
-g.fast   lda   5,s          grab page number
-         inca               go to the next page
-         clrb               at the top of it
-         subd  5,s          take out number of bytes left to write
-         pshs  b            max. number of characters
-
-         clrb               always <256 characters to write
-g.loop   lda   ,u+          get a character
-         cmpa  #$20         is it a control character?
-         blo   g.done       yes, we're done this stint
-         tst   1,s          get uppercase conversion flag
-         beq   g.loop1      don't convert
-         lbsr  L0403        do a lower-uppercase conversion, if necessary
-         sta   -1,u         save again
-
-g.loop1  incb               done one more character
-         cmpb  ,s           done as many as we can?
-         bne   g.loop
-
-g.done   leas  1,s          kill max. count of characters to use
-         cmpb  #1           one or fewer characters?
-         bls   no.wptr      yes, go use old method
-
-*         IFEQ  H6309
-* Note: this was present in the TuneUp version of SCF, and seems to
-* never allow grfdrv to be called directly, so did fast text screens
-* ever work in TuneUp??? - BGP
-*         bra   no.wptr      
-*         ENDC
-
-* now we call grfdrv...
-         ldu   5,s          get start pointer again
-         abx                done B more characters...
-         stx   1,s          save on-stack
-         lbsr  call.grf     go call grfdrv: no error possible on return
-         leau  b,u          go up B characters in U, too
-         stu   5,s          save old U, too
-         puls  b,x,y,u      restore registers
-         bra   L0544        do end-buffer checks and continue
-         ENDC
-
-no.wptr  puls  b,x,y,u      restore all registers
-
-L0524    lda   ,u+            Get character to write
-         ldb   PD.RAW,y       Raw mode?
-         bne   L053D          Yes, go write it
-         ldb   PD.UPC,y       Force uppercase?
-         beq   L052A          No, continue
-         bsr   L0403          Make it uppercase
-L052A    cmpa  #C$LF          Is it a Line feed?
-         bne   L053D          No, go print it
-         lda   #C$CR          Get code for carriage return
-         ldb   PD.ALF,y       Auto Line feed?
-         bne   L053D          Yes, go print carriage return first
-         bsr   L0573          Print carriage return
-         bcs   L055D          If error, go wait for device
-         lda   #C$LF          Now, print the line feed
-
-* Write character to device (call driver)
-L053D    bsr   L0573          Go write it to device
-         bcs   L055D          If error, go wait for device
-         ldb   #1             Bump up # chars we have written
-         abx
-L0544    cmpx  ,s             Done whole WRITE call?
-         bhs   L0554          Yes, go save # chars written & exit
-         ldb   PD.RAW,y       Raw mode?
-         lbne  L04EC          Yes, keep writing
-         lda   -1,u           Get the char we wrote
-         lbeq  L04EC          NUL, keep writing
-         cmpa  PD.EOR,y       End of record?
-         lbne  L04EC          No, keep writing
-L0554    leas  2,s            Eof record, stop & Eat end of buffer ptr???
-L0556    ldu   PD.RGS,y       Get callers register pointer
-         stx   R$Y,u          Save character count to callers Y
-L055A    lbra  L0453          Mark device write clear and return
-
-* Check for forced uppercase
-L0403    cmpa  #'a            Less then 'a'?
-         blo   L0412          Yes, leave it
-         cmpa  #'z            Higher than 'z'?
-         bhi   L0412          Yes, leave it
-         suba  #$20           Make it uppercase
-L0412    rts                  Return
-
-L055D    leas  2,s            Purge stack
-         pshs  b,cc           Preserve registers
-         bsr   L0556          Wait for device
-         puls  pc,b,cc        Restore & return
-
-* Check for end of page (part of send char to driver)
-L0573    pshs  u,y,x,a        Preserve registers
-         ldx   PD.DEV,y       Get device table pointer
-         cmpa  #C$CR          Carriage return?
-         bne   L056F          No, go print it
-         ldu   V$STAT,x       Get pointer to device stactic storage
-         ldb   V.PAUS,u       Pause request?
-         bne   L0590          Yes, go pause device
-         ldb   PD.RAW,y       Raw output mode?
-         bne   L05A2          Yes, go on
-         ldb   PD.PAU,y       End of page pause enabled?
-         beq   L05A2          No, go on
-         dec   V.LINE,u       Subtract a line
-         bne   L05A2          Not done, go on
-         ldb   #$ff           do a immediate pause request
-         stb   V.PAUS,u
-         bra   L059A          Go read next character
-
-L03DA    pshs  u,y,x        Preserve registers
-         ldx   PD.DV2,y     Get output device table pointer
-         beq   NoOut        None, exit
-         ldu   PD.DEV,y     Get device table pointer
-         lbra  L03EA        Process & return
-
-NoOut    puls  pc,u,y,x     No output device so exit
-
-* Wait for pause release
-L0590    bsr   L03DA          Read next character
-         bcs   L059A          Error, try again
-         cmpa  PD.PSC,y       Pause char?
-         bne   L0590          No, try again
-
-L059A    bsr   L03DA          Reset line count and read a character
-         cmpa  PD.PSC,y       Pause character?
-         beq   L059A          Yes, go read again
-
-* Process Carriage return - do auto linefeed & Null's if necessary
-* Entry: A=CHR$($0D)
-L05A2    ldu   V$STAT,x       Get static storage pointer
-         clra
-         sta   V.PAUS,u       Clear pause request
-         lda   #C$CR          Carriage return (in cases from pause)
-         bsr   L05C9          Send it to driver
-         lda   PD.RAW,y       Raw mode?
-         bne   L05C7          Yes, return
-         ldb   PD.NUL,y       Get end of line null count
-         pshs  b              Save it
-         lda   PD.ALF,y       Auto line feed enabled?
-         beq   L05BE          No, go on
-         lda   #C$LF          Get line feed code
-L05BA    bsr   L05C9          Execute driver write routine
-         bcs   L05C5          Error, purge stack and return
-L05BE    clra                 Get null character
-         dec   ,s             Done null count?
-         bpl   L05BA          No, go send it to driver
-         clra                 Clear carry
-L05C5    leas  1,s            Purge stack
-L05C7    puls  pc,u,y,x,a     Restore & return
-
-* Execute device driver write routine
-* Entry: A=Character to write
-* Execute device driver
-* Entry: W=Entry offset (for type of function, ex. Write, Read)
-*        A=Code to send to driver
-L05C9    ldu   V$STAT,x       Get device static storage pointer
-         pshs  y,x            Preserve registers
-         clrb
-         stb   V.WAKE,u       Wake it up
-         IFGT  Level-1
-         ldx   V$DRIVEX,x     Get driver execution pointer
-         ELSE
-         pshs  d
-         ldx   V$DRIV,x     get driver module
-         ldd   M$EXEC,x
-         leax  d,x
-         puls  d
-         ENDC
-         jsr   D$WRIT,x       Execute driver
-         puls  pc,y,x         Restore & return
-
-* Send character to driver
-L0565    pshs  u,y,x,a        Preserve registers
-         ldx   PD.DV2,y       Get output device table pointer
-         beq   L0571          Return if none
-         cmpa  #C$CR          Carriage return?
-         beq   L05A2          Yes, go process it
-L056F    ldu   V$STAT,x       Get device static storage pointer
-         clrb
-         stb   V.WAKE,u       Wake it up
-         IFGT  Level-1
-         ldx   V$DRIVEX,x     Get driver execution pointer
-         ELSE
-         pshs  d
-         ldx   V$DRIV,x     get driver module
-         ldd   M$EXEC,x
-         leax  d,x
-         puls  d
-         ENDC
-         jsr   D$WRIT,x       Execute driver
-L0571    puls  pc,u,y,x,a     Restore & return
-
-* Check for printable character
-L0413    ldb   PD.EKO,y       Echo turned on?
-         beq   NoEcho         No, return
-L0418    cmpa  #C$SPAC        CHR$(32) or higher?
-         bhs   L0565          Yes, go send to driver
-         cmpa  #C$CR          Carriage return?
-         bne   L0423          No, change it to a period
-         bra   L0565          Anything else output to driver
-
-NoEcho   rts
-
-L0423    pshs  a              Save code
-         lda   #'.            Get code for period
-         bsr   L0565          Output it to device
-         puls  pc,a           Restore & return
-
-L0624    bsr   L0418        check if it's printable and send it to driver
-* Process ReadLn
-L05F8    lbsr  L03E2        get a character from device
-         lbcs  L0370        return if error
-         tsta               usable character?
-         lbeq  L02FE        no, check path descriptor special characters
-         ldb   PD.RPR,y     get reprint line code
-         cmpb  #C$RPRT      cntrl D?
-         lbeq  L02FE        yes, check path descriptor special characters
-         cmpa  PD.RPR,y     reprint line?
-         bne   L0629        no, Check line editor keys
-         cmpx  PD.MAX,y     character count at maximum?
-         beq   L05F8        yes, go read next character
-         ldb   #1           Bump char count up by 1
-         abx
-         cmpx  ,s           done?
-         bhs   L0620        yes, exit
-         lda   ,u+          get character read
-         beq   L0624        null, go send it to driver
-         cmpa  PD.EOR,y     end of record character?
-         bne   L0624        no, go send it to driver
-         leau  -1,u         bump buffer pointer back 1
-L0620    leax  -1,x         bump character count back 1
-         bra   L05F8        go read next character
-
-* Process print rest of line
-L0629    cmpa  #C$PLINE       Print rest of line code?
-         bne   L0647          No, check insert
-L062D    pshs  u              Save buffer pointer
-         lbsr  L038B          Go print rest of line
-         lda   PD.BSE,y       Get backspace echo character
-L0634    cmpu  ,s             Beginning of buffer?
-         beq   L0642          Yes, exit
-         leau  -1,u           Bump buffer pointer back 1
-         leax  -1,x           Bump character count back 1
-         IFNE  H6309
-         bsr   L0565          Print it
-         ELSE
-         lbsr  L0565          Print it
-         ENDC
-         bra   L0634          Keep going
-L0642    leas  2,s            Purge buffer pointer
-         bra   L05F8          Return
-
-* Process Insert character (NOTE:Currently destroys W)
-L0647    cmpa  #C$INSERT      Insert character code?
-         bne   L0664          No, check delete
-         IFNE  H6309
-         pshs  x,y            Preserve x&y a moment
-         tfr   u,w            Dupe buffer pointer into w
-         ldf   #$fe           End of buffer -1
-         tfr   w,x            Source copy address
-         incw                 Include char we are on & dest address is+1
-         tfr   w,y            Destination copy address
-         subr  u,w            w=w-u (Size of copy)
-         tfm   x-,y-          Move buffer up one
-         puls  y,x            Get back original y & x
-         lda   #C$SPAC        Get code for space
-         sta   ,u             Save it there
-         ELSE
-         pshs  u
-         tfr   u,d
-         ldb   #$FF
-         tfr   d,u
-L06DE    lda   ,-u
-         sta   1,u
-         cmpu  ,s
-         bne   L06DE
-         lda   #C$SPAC
-         sta   ,u
-         leas  2,s
-         ENDC
-         bra   L062D          Go print rest of line
-
-* Process delete line
-L0664    cmpa  #C$DELETE      Delete character code?
-         bne   L068B          No, check end of line
-         pshs  u              Save buffer pointer
-         lda   ,u             Get character there
-         cmpa  PD.EOR,y       End of record?
-         beq   L0687          Yes, don't bother to delete it
-L0671    lda   1,u            Get character beside it
-         cmpa  PD.EOR,y       This an end of record?
-         beq   L067C          Yes, delete it
-         sta   ,u+            Bump character back
-         bra   L0671          Go do next character
-L067C    lda   #C$SPAC        Get code for space
-         cmpa  ,u             Already there?
-         bne   L0685          No, put it in
-         lda   PD.EOR,y       Get end of record code
-L0685    sta   ,u             Put it there
-L0687    puls  u              Restore buffer pointer
-         bra   L062D          Go print rest of line
-
-* Delete rest of buffer
-L068B    cmpa  PD.EOR,y       End of record code?
-         bne   L02FE          No, check for special path dsc. chars
-         pshs  u              Save buffer pointer
-         bra   L069F          Go erase rest of buffer
-
-L0696    pshs  a              Save code
-         lda   #C$SPAC        Get code for space
-         lbsr  L0565          Print it
-         puls  a              Restore code
-L069F    cmpa  ,u+            End of record?
-         bne   L0696          No, go print a space
-         puls  u              Restore buffer pointer
-
-* Check character read against path descriptor
-L02FE    tsta               Usable character?
-         beq   L030C        No, go on
-         ldb   #PD.BSP      Get start point in path descriptor
-L0303    cmpa  b,y          Match code in descriptor?
-         beq   L032C        Yes, go process it
-         incb               Move to next one
-         cmpb  #PD.QUT      Done check?
-         bls   L0303        No, keep going
-L030C    cmpx  PD.MAX,y     Past maximum character count?
-         bls   L0312        No, go on
-         stx   PD.MAX,y     Update maximum character count
-L0312    ldb   #1           Add 1 char
-         abx
-         cmpx  ,s           Past requested amount?
-         blo   L0322        No, go on
-         lda   PD.OVF,y     Get overflow character
-         lbsr  L0565        Send it to driver
-         leax  -1,x         Subtract a character
-         lbra  L05F8        Go try again
-
-L0322    ldb   PD.UPC,y     Force uppercase?
-         beq   L0328        No, put char in buffer
-         lbsr  L0403        Make character uppercase
-L0328    sta   ,u+          Put character in buffer
-         lbsr  L0413        Check for printable
-         lbra  L05F8        Go try again
-
-* Process path option characters
-L032C    pshs  x,pc         Preserve character count & PC
-         leax  <L033F,pc    Point to branch table
-         subb  #PD.BSP      Subtract off first code
-         lslb               Account for 2 bytes a entry
-         abx                Point to entry point
-         stx   2,s          Save it in PC on stack
-         puls  x            Restore X
-C8E3         jsr   [,s++]       Execute routine
-         lbra  L05F8        Continue on
-
-* Vector points for PD.BSP-PD.QUT
-L033F    bra   L03BB        Process PD.BSP
-         bra   L03A5        Process PD.DEL
-         bra   L0351        Process PD.EOR
-         bra   L0366        Process PD.EOF
-         bra   L0381        Process PD.RPR
-         bra   L038B        Process PD.DUP
-         rts                PD.PSC we don't worry about
-         nop
-         bra   L03A5        Process PD.INT
-         bra   L03A5        Process PD.QUT
-
-* Process PD.EOR character
-L0351    leas  2,s          Purge return address
-
-         sta   ,u           Save character in buffer
-         lbsr  L0413
-         ldu   PD.RGS,y     Get callers register stack pointer
-         ldb   #1           Bump up char count by 1
-         abx
-         stx   R$Y,u        Store it in callers Y
-         lbsr  L042B
-         leas  2,s
-         lbra  L0453
-
-* Process PD.EOF
-L0366    leas  2,s          Purge return address
-         leax  ,x           read anything?
-         lbeq  L02A2
-         bra   L030C
-
-L0370    pshs  b
-         lda   #C$CR
-         sta   ,u
-         lbsr  L0565        Send it to the driver
-         puls  b
-         lbra  L02A4
-
-* Process PD.RPR
-L0381    lda   PD.EOR,y     Get end of record character
-         sta   ,u           Put it in buffer
-         ldx   #0
-         ldu   PD.BUF,y     Get buffer ptr
-L0388    lbsr  L0418        Send it to driver
-L038B    cmpx  PD.MAX,y     Character maximum?
-         beq   L03A2        Yes, return
-         ldb   #1           Bump char count up by 1
-         abx
-         cmpx  2,s          Done count?
-         bhs   L03A0        Yes, exit
-         lda   ,u+          Get character from buffer
-         beq   L0388        Null, go send it
-         cmpa  PD.EOR,y     Done line?
-         bne   L0388        No go send it
-         leau  -1,u         Move back a character
-L03A0    leax  -1,x         Move character count back
-L03A2    rts                Return
-
-L03A3    bsr   L03BF
-* PD.DEL/PD.QUT/PD.INT processing
-L03A5    leax  ,x           Any characters?
-         beq   L03B8        No, reset buffer ptr
-         ldb   PD.DLO,y     Backspace over line?
-         beq   L03A3        Yes, go do it
-         ldb   PD.EKO,y     Echo character?
-         beq   L03B5        No, zero out buffer pointers & return
-         lda   #C$CR        Send CR to the driver
-         lbsr  L0565        send it to driver
-L03B5    ldx   #0           zero out count
-L03B8    ldu   PD.BUF,y     reset buffer pointer
-L03BA    rts                return
-
-* Process PD.BSP
-L03BB    leax  ,x           Any characters?
-         beq   L03A2        No, return
-L03BF    leau  -1,u         Mover buffer pointer back 1 character
-         leax  -1,x         Move character count back 1
-         ldb   PD.EKO,y     Echoing characters?
-         beq   L03BA        No, return
-         ldb   PD.BSO,y     Which backspace method?
-         beq   L03D4        Use BSE
-         bsr   L03D4        Do a BSE
-         lda   #C$SPAC      Get code for space
-         lbsr  L0565        Send it to driver
-L03D4    lda   PD.BSE,y     Get BSE
-         lbra  L0565        Send it to driver
-
-         IFGT  Level-1
-* check PD.DTP,y and update PD.WPTR,y if it's device type $10 (grfdrv)
-get.wptr pshs  x,u
-         ldu   PD.DEV,y     get device table entry
-         ldx   V$DRIV,u     get device driver module
-         ldd   M$Name,x     offset to name
-         ldd   d,x
-         cmpd  #"VT         is it VTIO?
-         bne   no.fast      no, don't do the fast stuff
-         ldd   >WGlobal+G.GrfEnt     does GrfDrv have an entry address?
-         beq   no.fast      nope, don't bother calling it.
-
-         ldu   V$STAT,u     and device static storage
-         tst   V.ParmCnt,u  are we busy getting more parameters?
-         bne   no.fast      yes, don't do buffered writes
-
-* Get window table pointer & verify it: copied from CoWin and modified
-         ldb   V.WinNum,u   Get window # from device mem
-         lda   #Wt.Siz      Size of each entry
-         mul                Calculate window table offset
-         addd  #WinBase     Point to specific window table entry
-         tfr   d,y          Move to y, the register we want
-         lda   Wt.STbl,y    Get MSB of scrn tbl ptr
-         bgt   VerExit      If $01-$7f, should be ok
-
-* Return illegal window definition error
-no.fast  comb               set carry: no error code, it's an internal routine
-         puls  x,u,pc
-
-VerExit  clra               No error
-         puls  x,u,pc
-
-call.grf pshs  d,x,y,u      save registers
-         ldx   #$0180       where to put the text
-         IFNE  H6309
-         pshs  cc           save old CC
-         ELSE
-         tfr   cc,a
-         sta   -2,x
-         ENDC
-         orcc  #IntMasks+Entire  shut everything else off
-
-         IFNE  H6309
-         clra               make sure high byte=0
-         tfr   d,w
-         tfm   u+,x+        move the data into low memory
-         ELSE
-l@       lda   ,u+
-         sta   ,x+
-         decb
-         bne   l@
-         ENDC
-
-         ldb   #6           alpha put
-         stb   >WGlobal+G.GfBusy  flag grfdrv busy
-         IFNE  H6309
-         lde   ,s+          grab old CC off of the stack
-         lda   1,s          get the number of characters to write
-         ELSE
-*         ldb   ,s+          grab old CC off of the stack
-         lda   1,s          get the number of characters to write
-         ENDC
-* A = number of bytes at $0180 to write out...
-         bsr   do.grf       do the call
-* ignore errors : none possible from this particular call
-call.out puls  d,x,y,u,pc   and return
-
-* this routine should always be called by a BSR, and grfdrv will use the
-* PC saved on-stack to return to the calling routine.
-* ALL REGISTERS WILL BE TRASHED
-do.grf   sts   >WGlobal+G.GrfStk    stack pointer for GrfDrv
-         lds   <D.CCStk     get new stack pointer
-         IFNE  H6309
-         pshs  dp,x,y,u,pc
-         pshsw
-         pshs  cc,d         save all registers
-         ELSE
-         pshs  dp,cc,d,x,y,u,pc
-         ENDC
-
-         ldx   >WGlobal+G.GrfEnt     get GrfDrv entry address
-
-         stx   R$PC,s       save grfdrv entry address as PC on the stack
-         IFNE  H6309
-         ste   R$CC,s       save CC onto CC on the stack
-         ELSE
-         stb   R$B,s
-         ldb   $017E
-         stb   R$CC,s
-         ENDC
-         jmp   [>D.Flip1]   flip to grfdrv and execute it
-         ENDC
-
-* GrfDrv will execute function, and then call [D.Flip0] to return here. It 
-* will use an RTS to return to the code that called here in the first place
-* Only SP, PC & CC are set up - ALL OTHER REGISTERS MAY BE MODIFIED
-
-*         ELSE
-*
-*call.grf pshs  u,y,x,d
-*         tfr   cc,a
-*         orcc  #IntMasks+Entire
-*         ldx   #$0180
-*         sta   -2,x
-*call.lp  lda   ,u+
-*         sta   ,x+
-*         decb
-*         bne   call.lp
-*         stb   ,x
-*         lda   1,s
-*         bsr   do.grf
-*         puls  u,y,x,d,pc
-*
-*do.grf   sts   >$1007
-*         lds   <D.CCStk
-*         ldu   #$1100
-*         ldb   #$3A
-*         stb   >$1002
-*         stb   >$017F
-*         pshs  pc,u,y,x,dp,b,a,cc
-*         ldx   >$106E
-*         stx   R$PC,s
-*         ldb   >$107E
-*         stb   ,s
-*         jmp   [>D.Flip1]
-*         ENDC
-
-         emod
-eom      equ   *
-         end
-