(DEFINE-FILE-INFO PACKAGE "INTERLISP" READTABLE "XCL" BASE 10)

(FILECREATED "30-Dec-2025 19:09:34" |{DSK}<Users>briggs>projects>medley>sources>MAIKOETHER.;7| 26899  

      :EDIT-BY |nhb|

      :CHANGES-TO (VARS MAIKOETHERCOMS)

      :PREVIOUS-DATE "30-Dec-2025 18:50:46" |{DSK}<Users>briggs>projects>medley>sources>MAIKOETHER.;6|
)


(PRETTYCOMPRINT MAIKOETHERCOMS)

(RPAQQ MAIKOETHERCOMS
       ((FNS \\10MB.RESTART.ETHER \\10MB.STARTDRIVER \\10MB.TURNOFFETHER \\10MB.TURNONETHER 
             \\10MBSENDPACKET \\10MBWATCHER \\MAIKO.10MBSENDPACKET \\MAIKO.10MBWATCHER 
             \\MAIKO.ETHERRESUME \\MAIKO.ETHERSUSPEND \\MAIKO.INPUT.INTERRUPT \\NS.SETTIME 
             \\PUP.SETTIME \\MAIKO.10MBSTARTDRIVER \\MAIKO.10MBTURNONETHER \\MAIKO.10MB.RESTART.ETHER
             \\MAIKO.CHECKSUM)
        (INITVARS (\\MAIKO.INPUT.PACKET)
               (|\\ETHERtopMonitor| (CREATE.MONITORLOCK "ETHERTopMonitor")))
        (DECLARE\: EVAL@COMPILE DONTCOPY (FILES (LOADCOMP)
                                                10MBDRIVER)
               (GLOBALVARS \\MAIKO.INPUT.PACKET |\\ETHERtopMonitor|)
               (GLOBALVARS \\MAIKO.IO-INTERRUPT-FLAGS \\MAIKO.IO-INTERRUPT-VECTOR))
        (ADDVARS (\\MAIKO.MOVDS (\\MAIKO.10MBSTARTDRIVER \\10MB.STARTDRIVER)
                        (\\MAIKO.10MBWATCHER \\10MBWATCHER)
                        (\\MAIKO.10MBSENDPACKET \\10MBSENDPACKET)
                        (\\MAIKO.ETHERSUSPEND \\10MB.TURNOFFETHER)
                        (\\MAIKO.10MBTURNONETHER \\10MB.TURNONETHER)
                        (\\MAIKO.ETHERRESUME \\10MB.RESTART.ETHER)
                        (\\MAIKO.CHECKSUM \\CHECKSUM)))
        (COMS 
              (* |;;| "MAIKO handler for new interrupt-driven incoming ethernet communication, rather than polling for it.")

              (FNS \\MAIKO.ETHER-INTERRUPT))
        (COMS 
              (* |;;| "MAIKO Log & Console message handling.  Interrupt-driven message printing, instead of polled printing.")

              (FNS \\MAIKO.CONSOLE-LOG-PRINT))
        (COMS 
              (* |;;| "Asynchronous I/O handling")

              (FNS \\MAIKO.IO-INTERRUPT)
              (VARS \\EPT.3TO10 (\\MAIKO.IO-INTERRUPT-FLAGS (\\CREATECELL \\FIXP))
                    (\\MAIKO.IO-INTERRUPT-VECTOR NIL)))))
(DEFINEQ

(\\10MB.RESTART.ETHER
  (LAMBDA NIL                                            (* \; "Edited 11-May-88 16:09 by MASINTER")
    (SUBRCALL ETHER-RESUME)))

(\\10MB.STARTDRIVER
  (LAMBDA (NDB RESTARTFLG MYNSNUMBER)                        (* \; "Edited  5-Apr-89 15:03 by snow")
    (DECLARE (GLOBALVARS \\MAIKO.INPUT.PACKET \\10MB.EXPECTED.RECEIVE.INTERVAL \\10MB.INPUT.TIMEOUT))
    (SUBRCALL ETHER-SUSPEND)
    (OR (\\INIT.ETHER.BUFFER.POOL)
        (ERROR "Unable to create buffer pool"))
    (|replace| NDBTQ |of| NDB |with| (|create| SYSQUEUE))
    (SETQ \\10MB.RAWPACKETQ (|create| SYSQUEUE))
    (SETQ \\10MB.INPUT.TIMEOUT (TIMES \\RCLKSECOND \\10MB.EXPECTED.RECEIVE.INTERVAL))
    (\\10MB.TURNONETHER NDB NIL NIL (OR MYNSNUMBER T)
           0 0)
    (PROG ((CSB (|fetch| NDBCSB |of| NDB)))
          (OR \\MAIKO.INPUT.PACKET (SETQ \\MAIKO.INPUT.PACKET (\\ALLOCATE.ETHERPACKET)))
          (|replace| DLFIRSTICB |of| (|fetch| NDBCSB |of| NDB) |with| \\ES.PENDING)
          (SUBRCALL ETHER-GET \\10MBPACKETLENGTH (|fetch| 10MBPACKETBASE |of| \\MAIKO.INPUT.PACKET))
          (|replace| NDBWATCHER |of| NDB |with| (ADD.PROCESS (LIST '\\10MBWATCHER (KWOTE NDB))
                                                       'RESTARTABLE
                                                       'SYSTEM
                                                       'AFTEREXIT
                                                       'DELETE))
          (RETURN NDB))))

(\\10MB.TURNOFFETHER
  (LAMBDA NIL                                            (* \; "Edited 11-May-88 16:11 by MASINTER")
    (SUBRCALL ETHER-SUSPEND)))

(\\10MB.TURNONETHER
  (LAMBDA (NDB SMASHSTATE NEWSTATE NSHOSTNUMBER ININTERRUPT OUTINTERRUPT)
                                                         (* \; "Edited 11-May-88 16:08 by MASINTER")

(* |;;;| "Reset and activate ether associated with NDB.  If SMASHSTATE is given, it is a CSB-length block into which state is saved for later restoration by passing as the NEWSTATE arg.  If NEWSTATE is NIL, then the remaining non-NIL args give parameters for this activation: the host number for microcode to watch for, T meaning my own number;  and interrupt masks for when a packet arrives or finishes transmitting")

    (* |;;| "For Daybreak, SMASHSTATE and NEWSTATE must be NIL")

    (PROG ((CSB (|fetch| NDBCSB |of| NDB)))
          (\\MAIKO.ETHERSUSPEND)
          (OR CSB (|replace| NDBCSB |of| NDB |with| (SETQ CSB (LOCF (|fetch| DLETHERNET |of| \\IOPAGE
                                                                           )))))
          (|replace| DLFIRSTOCB |of| CSB |with| 0)
          (|replace| DLFIRSTICB |of| CSB |with| 0)
          (AND NSHOSTNUMBER (COND
                               ((EQ NSHOSTNUMBER T)
                                (\\BLT (LOCF (|fetch| DLLOCALHOST0 |of| CSB))
                                       (LOCF (|fetch| (IFPAGE |NSHost0|) |of| |\\InterfacePage|))
                                       \\#WDS.NSHOSTNUMBER))
                               (T (\\STORENSHOSTNUMBER (LOCF (|fetch| DLLOCALHOST0 |of| CSB))
                                         NSHOSTNUMBER))))
          (AND OUTINTERRUPT (|replace| DLOUTPUTMASK |of| CSB |with| OUTINTERRUPT))
          (AND ININTERRUPT (|replace| DLINPUTMASK |of| CSB |with| ININTERRUPT))
          (|replace| DLMISSEDPACKETS |of| CSB |with| 0)
          (|replace| DLLASTICB |of| CSB |with| 0)
          (|replace| DLLASTOCB |of| CSB |with| 0)
          (SUBRCALL ETHER-RESET)
          (SUBRCALL ETHER-RESUME)
          (RETURN NDB))))

(\\10MBSENDPACKET
  (LAMBDA (NDB PACKET)                                   (* \; "Edited 11-May-88 16:10 by MASINTER")
    (PROG NIL
          (COND
             (\\RAWTRACING (\\MAYBEPRINTPACKET PACKET 'RAWPUT)))
          (COND
             ((OR (|fetch| 10MBMULTICASTP |of| PACKET)
                  (EQNSADDRESS.HOST \\MY.NSADDRESS (|fetch| 10MBDESTHOSTBASE |of| PACKET)))
                                                             (* \; 
                                  "We would hear this packet if our hardware let us, so fake receipt")
              (PROG ((COPYPACKET (\\ALLOCATE.ETHERPACKET)))
                    (\\BLT (LOCF (|fetch| 10MBLENGTH |of| COPYPACKET))
                           (LOCF (|fetch| 10MBLENGTH |of| PACKET))
                           (ADD1 (|fetch| 10MBLENGTH |of| PACKET)))
                                                             (* \; 
                                                     "Copy all data that would have been transmitted")
                    (|replace| EPNETWORK |of| COPYPACKET |with| NDB)
                    (|replace| EPTYPE |of| COPYPACKET
                       |with| (|for| PAIR |in| \\10MBTYPE.TRANSLATIONS
                                 |bind| (TYPE _ (|fetch| 10MBTYPE |of| PACKET))
                                 |when| (EQ TYPE (CAR PAIR)) |do| 

                                 (* |;;| "TYPE is the raw type of the etherpacket.  These do not always correspond one-to-one with the EPTYPE constants we use (in particular, for pups), so translate if necessary.")

                                                                  (RETURN (CDR PAIR))
                                 |finally| (RETURN TYPE)))
                    (COND
                       (\\RAWTRACING (\\MAYBEPRINTPACKET COPYPACKET 'RAWGET)))
                    (\\HANDLE.RAW.PACKET COPYPACKET))))
          (UNINTERRUPTABLY
              (SUBRCALL ETHER-SEND (IMAX (|fetch| 10MBLENGTH |of| PACKET)
                                         \\10MB.MINPACKETLENGTH)
                     (|fetch| 10MBPACKETBASE |of| PACKET))
              (|replace| EPNETWORK |of| PACKET |with| NIL)
              (\\REQUEUE.ETHERPACKET PACKET))
          (RETURN T))))

(\\10MBWATCHER
  (LAMBDA (NDB)                                          (* \; "Edited 16-May-88 22:24 by MASINTER")

    (* |;;| "merge message and packet reading")

    (PROG ((CNTR 0)
           MESSAGE-BUFFER MESSAGE-LENGTH PACKET)
      LP  (IF (SUBRCALL MESSAGE-READP)
              THEN (PROMPTPRINT (IF (SETQ MESSAGE-LENGTH (SUBRCALL MESSAGE-READ (OR MESSAGE-BUFFER
                                                                                    (SETQ 
                                                                                     MESSAGE-BUFFER
                                                                                     (ALLOCSTRING
                                                                                      1024)))
                                                                1024))
                                    THEN (SUBSTRING MESSAGE-BUFFER 1 MESSAGE-LENGTH)
                                  ELSE "?? system message: polling failed")))
          (UNINTERRUPTABLY
              (SUBRCALL ETHER-CHECK)
              (SETQ PACKET (\\MAIKO.INPUT.INTERRUPT NDB)))
          (COND
             (PACKET (\\HANDLE.RAW.PACKET PACKET)
                    (COND
                       ((ILESSP (|add| CNTR 1)
                               \\MAXWATCHERGETS)
                        (GO LP)))))
          (BLOCK)
          (SETQ CNTR 0)
          (GO LP))))

(\\MAIKO.10MBSENDPACKET
  (LAMBDA (NDB PACKET)                                       (* \; "Edited 31-Oct-89 14:10 by bvm")
    (PROG NIL
          (COND
             (\\RAWTRACING (\\MAYBEPRINTPACKET PACKET 'RAWPUT)))
          (COND
             ((OR (|fetch| 10MBMULTICASTP |of| PACKET)
                  (EQNSADDRESS.HOST \\MY.NSADDRESS (|fetch| 10MBDESTNSADDRESSBASE |of| PACKET)))
                                                             (* \; 
                                  "We would hear this packet if our hardware let us, so fake receipt")
              (PROG ((COPYPACKET (\\ALLOCATE.ETHERPACKET)))
                    (\\BLT (LOCF (|fetch| 10MBLENGTH |of| COPYPACKET))
                           (LOCF (|fetch| 10MBLENGTH |of| PACKET))
                           (ADD1 (|fetch| 10MBLENGTH |of| PACKET)))
                                                             (* \; 
                                                     "Copy all data that would have been transmitted")
                    (|replace| EPNETWORK |of| COPYPACKET |with| NDB)
                    (|replace| EPTYPE |of| COPYPACKET
                       |with| (|for| PAIR |in| \\10MBTYPE.TRANSLATIONS
                                 |bind| (TYPE _ (|fetch| 10MBTYPE |of| PACKET))
                                 |when| (EQ TYPE (CAR PAIR)) |do| 

                                 (* |;;| "TYPE is the raw type of the etherpacket.  These do not always correspond one-to-one with the EPTYPE constants we use (in particular, for pups), so translate if necessary.")

                                                                  (RETURN (CDR PAIR))
                                 |finally| (RETURN TYPE)))
                    (COND
                       (\\RAWTRACING (\\MAYBEPRINTPACKET COPYPACKET 'RAWGET)))
                    (\\HANDLE.RAW.PACKET COPYPACKET))))
          (UNINTERRUPTABLY
              (SUBRCALL ETHER-SEND (IMAX (|fetch| 10MBLENGTH |of| PACKET)
                                         \\10MB.MINPACKETLENGTH)
                     (|fetch| 10MBPACKETBASE |of| PACKET))
              (|replace| EPNETWORK |of| PACKET |with| NIL)
              (\\REQUEUE.ETHERPACKET PACKET))
          (RETURN T))))

(\\MAIKO.10MBWATCHER
  (LAMBDA (NDB)                                          (* \; "Edited 16-May-88 22:24 by MASINTER")

    (* |;;| "merge message and packet reading")

    (PROG ((CNTR 0)
           MESSAGE-BUFFER MESSAGE-LENGTH PACKET)
      LP  (IF (SUBRCALL MESSAGE-READP)
              THEN (PROMPTPRINT (IF (SETQ MESSAGE-LENGTH (SUBRCALL MESSAGE-READ (OR MESSAGE-BUFFER
                                                                                    (SETQ 
                                                                                     MESSAGE-BUFFER
                                                                                     (ALLOCSTRING
                                                                                      1024)))
                                                                1024))
                                    THEN (SUBSTRING MESSAGE-BUFFER 1 MESSAGE-LENGTH)
                                  ELSE "?? system message: polling failed")))
          (UNINTERRUPTABLY
              (SUBRCALL ETHER-CHECK)
              (SETQ PACKET (\\MAIKO.INPUT.INTERRUPT NDB)))
          (COND
             (PACKET (\\HANDLE.RAW.PACKET PACKET)
                    (COND
                       ((ILESSP (|add| CNTR 1)
                               \\MAXWATCHERGETS)
                        (GO LP)))))
          (BLOCK)
          (SETQ CNTR 0)
          (GO LP))))

(\\MAIKO.ETHERRESUME
  (LAMBDA NIL                                            (* \; "Edited 11-May-88 16:09 by MASINTER")
    (SUBRCALL ETHER-RESUME)))

(\\MAIKO.ETHERSUSPEND
  (LAMBDA NIL                                            (* \; "Edited 11-May-88 16:11 by MASINTER")
    (SUBRCALL ETHER-SUSPEND)))

(\\MAIKO.INPUT.INTERRUPT
  (LAMBDA (NDB)                                          (* \; "Edited 11-May-88 16:05 by MASINTER")

    (* |;;| "This routine gets called when 10MB input signals an interrupt.  See if the \\MAIKO.INPUT.PACKET has indeed been processed, and if so, take care of it")

    (PROG (LENGTH (PACKET \\MAIKO.INPUT.PACKET))
          (COND
             ((NEQ (SETQ LENGTH (|fetch| DLFIRSTICB |of| (|fetch| NDBCSB |of| NDB)))
                   \\ES.PENDING)
              (|replace| 10MBLENGTH |of| PACKET |with| LENGTH)
              (\\RCLK (LOCF (|fetch| EPTIMESTAMP |of| PACKET)))
              (|replace| EPNETWORK |of| PACKET |with| NDB)
              (|replace| EPTYPE |of| PACKET |with| (|for| PAIR |in| \\10MBTYPE.TRANSLATIONS
                                                      |bind| (TYPE _ (|fetch| 10MBTYPE |of| PACKET))
                                                      |when| (EQ TYPE (CAR PAIR))
                                                      |do| (RETURN (CDR PAIR))
                                                      |finally| (RETURN TYPE)))
              (COND
                 (\\RAWTRACING (\\MAYBEPRINTPACKET PACKET 'RAWGET)))
              (RETURN (PROG1 PACKET
                          (SETQ \\MAIKO.INPUT.PACKET (\\ALLOCATE.ETHERPACKET))
                          (|replace| DLFIRSTICB |of| (|fetch| NDBCSB |of| NDB) |with| \\ES.PENDING)
                          (SUBRCALL ETHER-GET \\10MBPACKETLENGTH (|fetch| 10MBPACKETBASE |of| 
                                                                                 \\MAIKO.INPUT.PACKET
                                                                        )))))
             (T (RETURN NIL))))))

(\\NS.SETTIME
  (LAMBDA (RETFLG)                                       (* \; "Edited 13-May-88 15:22 by MASINTER")
    (CL:UNLESS (AND RETFLG (NOT (STRINGP RETFLG)))
        (SETQ |\\TimeZoneComp| (SUBRCALL GETUNIXTIME 8 NIL)))
    (\\PROCESS.RESET.TIMERS)
    (DAYTIME)))

(\\PUP.SETTIME
  (LAMBDA (RETFLG)                                       (* \; "Edited 13-May-88 15:22 by MASINTER")
    (CL:UNLESS (AND RETFLG (NOT (STRINGP RETFLG)))
        (SETQ |\\TimeZoneComp| (SUBRCALL GETUNIXTIME 8 NIL)))
    (\\PROCESS.RESET.TIMERS)
    (DAYTIME)))

(\\MAIKO.10MBSTARTDRIVER
  (LAMBDA (NDB RESTARTFLG MYNSNUMBER)                       (* \; "Edited 30-Dec-2025 18:50 by nhb")
                                                             (* \; "Edited  4-May-91 15:50 by jds")

    (* |;;| "Start the \"driver\" for the 10MB ethernet on Sun Medley.  In particular, turn on the C ehternet code, queue up the first input packet, and start the \\10MBWATCHER process.")

    (SUBRCALL ETHER-SUSPEND)
    (OR (\\INIT.ETHER.BUFFER.POOL)
        (ERROR "Unable to create buffer pool"))
    (|replace| NDBTQ |of| NDB |with| (|create| SYSQUEUE))
    (SETQ \\10MB.RAWPACKETQ (|create| SYSQUEUE))
    (SETQ \\10MB.INPUT.TIMEOUT (TIMES \\RCLKSECOND \\10MB.EXPECTED.RECEIVE.INTERVAL))
    (\\10MB.TURNONETHER NDB NIL NIL (OR MYNSNUMBER T)
           0 0)
    (PROG ((CSB (|fetch| NDBCSB |of| NDB)))
          (OR \\MAIKO.INPUT.PACKET (SETQ \\MAIKO.INPUT.PACKET (\\ALLOCATE.ETHERPACKET)))
          (|replace| DLFIRSTICB |of| (|fetch| NDBCSB |of| NDB) |with| \\ES.PENDING)
          (AND (SUBRCALL ETHER-GET \\10MBPACKETLENGTH (|fetch| 10MBPACKETBASE |of| 
                                                                                 \\MAIKO.INPUT.PACKET
                                                             ))
               (\\MAIKO.ETHER-INTERRUPT))

     (* |;;| "Commented out the 10MBWATCHER adder, so this process never gets created.")

     (* |;;| "(replace NDBWATCHER of NDB with (ADD.PROCESS (LIST '\\10MBWATCHER (KWOTE NDB)) 'RESTARTABLE 'SYSTEM 'AFTEREXIT 'DELETE))")

          (RETURN NDB))))

(\\MAIKO.10MBTURNONETHER
  (LAMBDA (NDB SMASHSTATE NEWSTATE NSHOSTNUMBER ININTERRUPT OUTINTERRUPT)
                                                         (* \; "Edited 11-May-88 16:08 by MASINTER")

(* |;;;| "Reset and activate ether associated with NDB.  If SMASHSTATE is given, it is a CSB-length block into which state is saved for later restoration by passing as the NEWSTATE arg.  If NEWSTATE is NIL, then the remaining non-NIL args give parameters for this activation: the host number for microcode to watch for, T meaning my own number;  and interrupt masks for when a packet arrives or finishes transmitting")

    (* |;;| "For Daybreak, SMASHSTATE and NEWSTATE must be NIL")

    (PROG ((CSB (|fetch| NDBCSB |of| NDB)))
          (\\MAIKO.ETHERSUSPEND)
          (OR CSB (|replace| NDBCSB |of| NDB |with| (SETQ CSB (LOCF (|fetch| DLETHERNET |of| \\IOPAGE
                                                                           )))))
          (|replace| DLFIRSTOCB |of| CSB |with| 0)
          (|replace| DLFIRSTICB |of| CSB |with| 0)
          (AND NSHOSTNUMBER (COND
                               ((EQ NSHOSTNUMBER T)
                                (\\BLT (LOCF (|fetch| DLLOCALHOST0 |of| CSB))
                                       (LOCF (|fetch| (IFPAGE |NSHost0|) |of| |\\InterfacePage|))
                                       \\#WDS.NSHOSTNUMBER))
                               (T (\\STORENSHOSTNUMBER (LOCF (|fetch| DLLOCALHOST0 |of| CSB))
                                         NSHOSTNUMBER))))
          (AND OUTINTERRUPT (|replace| DLOUTPUTMASK |of| CSB |with| OUTINTERRUPT))
          (AND ININTERRUPT (|replace| DLINPUTMASK |of| CSB |with| ININTERRUPT))
          (|replace| DLMISSEDPACKETS |of| CSB |with| 0)
          (|replace| DLLASTICB |of| CSB |with| 0)
          (|replace| DLLASTOCB |of| CSB |with| 0)
          (SUBRCALL ETHER-RESET)
          (SUBRCALL ETHER-RESUME)
          (RETURN NDB))))

(\\MAIKO.10MB.RESTART.ETHER
  (LAMBDA (NDB)                                          (* \; "Edited 11-May-88 16:08 by MASINTER")

(* |;;;| "Kick the Ethernet receiver task to restart the Ethernet receiver task.  This function gets called when the 10MBDRIVER thinks the Ethernet has been accidentally disabled")

    (SUBRCALL ETHER-RESUME)))

(\\MAIKO.CHECKSUM
  (LAMBDA (BASE NWORDS INITSUM)                          (* \; "Edited 20-May-88 11:48 by MASINTER")
    (SUBRCALL CHECK-SUM BASE NWORDS INITSUM)))
)

(RPAQ? \\MAIKO.INPUT.PACKET )

(RPAQ? |\\ETHERtopMonitor| (CREATE.MONITORLOCK "ETHERTopMonitor"))
(DECLARE\: EVAL@COMPILE DONTCOPY 

(FILESLOAD (LOADCOMP)
       10MBDRIVER)

(DECLARE\: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS \\MAIKO.INPUT.PACKET |\\ETHERtopMonitor|)
)

(DECLARE\: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS \\MAIKO.IO-INTERRUPT-FLAGS \\MAIKO.IO-INTERRUPT-VECTOR)
)
)

(ADDTOVAR \\MAIKO.MOVDS (\\MAIKO.10MBSTARTDRIVER \\10MB.STARTDRIVER)
                        (\\MAIKO.10MBWATCHER \\10MBWATCHER)
                        (\\MAIKO.10MBSENDPACKET \\10MBSENDPACKET)
                        (\\MAIKO.ETHERSUSPEND \\10MB.TURNOFFETHER)
                        (\\MAIKO.10MBTURNONETHER \\10MB.TURNONETHER)
                        (\\MAIKO.ETHERRESUME \\10MB.RESTART.ETHER)
                        (\\MAIKO.CHECKSUM \\CHECKSUM))



(* |;;| 
"MAIKO handler for new interrupt-driven incoming ethernet communication, rather than polling for it.")

(DEFINEQ

(\\MAIKO.ETHER-INTERRUPT
  (LAMBDA NIL                                               (* \; "Edited 30-Dec-2025 18:36 by nhb")
                                                             (* \; "Edited  4-May-91 13:46 by jds")

    (* |;;| "This routine gets called when 10MB input signals an interrupt.  See if the \\MAIKO.INPUT.PACKET has indeed been processed, and if so, take care of it")

    (PROG ((NDB \\10MBLOCALNDB)
           LENGTH)

     (* |;;| "First, turn off the interrupt flag:")

          (|replace| (INTERRUPTSTATE ETHERINTERRUPT) |of| \\INTERRUPTSTATE |with| NIL)

     (* |;;| "Now handle it:")

          (UNINTERRUPTABLY
              (WITH.MONITOR |\\ETHERtopMonitor|
                  (PROG ((PACKET \\MAIKO.INPUT.PACKET))

                   (* |;;| "We come back here if there's more than one packet ready to be read, so we process as many as possible in one swell foop.")

                    READ-MORE-LOOP
                        (COND
                           ((NEQ (SETQ LENGTH (|fetch| DLFIRSTICB |of| (|fetch| NDBCSB |of| NDB)))
                                 \\ES.PENDING)
                            (|replace| 10MBLENGTH |of| PACKET |with| LENGTH)
                            (\\RCLK (LOCF (|fetch| EPTIMESTAMP |of| PACKET)))
                            (|replace| EPNETWORK |of| PACKET |with| NDB)
                            (|replace| EPTYPE |of| PACKET
                               |with| (|for| PAIR |in| \\10MBTYPE.TRANSLATIONS
                                         |bind| (TYPE _ (|fetch| 10MBTYPE |of| PACKET))
                                         |when| (EQ TYPE (CAR PAIR)) |do| (RETURN (CDR PAIR))
                                         |finally| (RETURN TYPE)))
                            (COND
                               (\\RAWTRACING (\\MAYBEPRINTPACKET PACKET 'RAWGET)))
                            (\\HANDLE.RAW.PACKET PACKET)
                            (SETQ \\MAIKO.INPUT.PACKET (\\ALLOCATE.ETHERPACKET))
                            (|replace| DLFIRSTICB |of| (|fetch| NDBCSB |of| NDB) |with| \\ES.PENDING)
                            (COND
                               ((SUBRCALL ETHER-GET \\10MBPACKETLENGTH (|fetch| 10MBPACKETBASE
                                                                          |of| \\MAIKO.INPUT.PACKET))

                                (* |;;| 
                                "Returned T, so there's another packet waiting already.  Process it.")

                                (SETQ PACKET \\MAIKO.INPUT.PACKET)
                                (GO READ-MORE-LOOP)))))))))))
)



(* |;;| 
"MAIKO Log & Console message handling.  Interrupt-driven message printing, instead of polled printing."
)

(DEFINEQ

(\\MAIKO.CONSOLE-LOG-PRINT
  (LAMBDA NIL                                            (* \; "Edited 18-Dec-89 12:16 by jds")

    (* |;;| "Read any pending Console or Log messages, and print them in the prompt window.")

    (* |;;| 
 "Called from INTERRUPTED when the Maiko emulator sets the LogMsgPending flag in \\INTERRUPTSTATE.")

    (PROG (MESSAGE-BUFFER MESSAGE-LENGTH)
          (|replace| (INTERRUPTSTATE LOGMSGSPENDING) |of| \\INTERRUPTSTATE |with| NIL)
          (|while| (SUBRCALL MESSAGE-READP)
             |do| (FRESHLINE PROMPTWINDOW)
                   (PRIN1 (|if| (SETQ MESSAGE-LENGTH (SUBRCALL MESSAGE-READ (OR MESSAGE-BUFFER
                                                                                    (SETQ 
                                                                                     MESSAGE-BUFFER
                                                                                     (ALLOCSTRING
                                                                                      1024)))
                                                                1024))
                              |then| (SUBSTRING MESSAGE-BUFFER 1 MESSAGE-LENGTH)
                            |else| "?? system message: polling failed")
                          PROMPTWINDOW)))))
)



(* |;;| "Asynchronous I/O handling")

(DEFINEQ

(\\MAIKO.IO-INTERRUPT
  (LAMBDA NIL                                            (* \; "Edited 18-Dec-89 13:09 by jds")

    (* |;;| "Handle I/O pending on an asynchronous file descriptor.")

    (* |;;| 
  "Called from INTERRUPTED when the Maiko emulator sets theIOINTERRUPT flag in \\INTERRUPTSTATE.")

    (PROG NIL
          (|replace| (INTERRUPTSTATE IOINTERRUPT) |of| \\INTERRUPTSTATE |with| NIL)
          (FOR INFO IN \\MAIKO.IO-INTERRUPT-VECTOR
             WHEN (NOT (ZEROP (LOGAND (CAR INFO)
                                         \\MAIKO.IO-INTERRUPT-FLAGS)))
             DO (CL:FUNCALL (CADR INFO))))))
)

(RPAQQ \\EPT.3TO10 513)

(RPAQ \\MAIKO.IO-INTERRUPT-FLAGS (\\CREATECELL \\FIXP))

(RPAQQ \\MAIKO.IO-INTERRUPT-VECTOR NIL)
(DECLARE\: DONTCOPY
  (FILEMAP (NIL (2301 20787 (\\10MB.RESTART.ETHER 2311 . 2475) (\\10MB.STARTDRIVER 2477 . 3863) (
\\10MB.TURNOFFETHER 3865 . 4029) (\\10MB.TURNONETHER 4031 . 6121) (\\10MBSENDPACKET 6123 . 8481) (
\\10MBWATCHER 8483 . 9926) (\\MAIKO.10MBSENDPACKET 9928 . 12296) (\\MAIKO.10MBWATCHER 12298 . 13747) (
\\MAIKO.ETHERRESUME 13749 . 13912) (\\MAIKO.ETHERSUSPEND 13914 . 14079) (\\MAIKO.INPUT.INTERRUPT 14081
 . 15925) (\\NS.SETTIME 15927 . 16211) (\\PUP.SETTIME 16213 . 16498) (\\MAIKO.10MBSTARTDRIVER 16500 . 
18150) (\\MAIKO.10MBTURNONETHER 18152 . 20247) (\\MAIKO.10MB.RESTART.ETHER 20249 . 20606) (
\\MAIKO.CHECKSUM 20608 . 20785)) (21751 24528 (\\MAIKO.ETHER-INTERRUPT 21761 . 24526)) (24652 26015 (
\\MAIKO.CONSOLE-LOG-PRINT 24662 . 26013)) (26061 26741 (\\MAIKO.IO-INTERRUPT 26071 . 26739)))))
STOP
