PageSourceSearch

https://retroapplejs.github.io/res/EMU_DEVICE_serialpro_terminal.js

js retroapplejs.github.io collected 2026-10-03 09:50:50 UTC 3,358 bytes, 131 lines download raw bytes

1//
2// Serial Pro browser-terminal console device.
3//
4// This is deliberately separate from SPSERIAL. SPSERIAL remains the real
5// byte-oriented UART line. SPTERM:console carries human/operator/status text
6// that must never enter the 6551 receive stream.
7//
8
9function SerialProTerminalDevice()
10{
11    var device = this;
12    var host = null;
13    var listeners = [];
14
15    this.id = {
16         "DCODE":"SPTERM"
17        ,"hostPCODE":"SPC"
18        ,"icon":"fa fa-terminal"
19        ,"description":"Serial Pro browser terminal console"
20    };
21
22    this.ports = {
23        "console":{
24             "direction":"duplex"
25            ,"mime":["text/plain; charset=utf-8"]
26            ,"handler":"receive"
27            ,"description":"Serial Pro terminal operator/status console"
28        }
29    };
30
31    function normalizeText(message)
32    {
33        var data = message && message.data!==undefined
34            ? message.data
35            : message;
36
37        if(data===undefined || data===null)
38            return "";
39
40        return String(data);
41    }
42
43    this.bindHost = function(card)
44    {
45        host = card || null;
46
47        if(host &&
48           typeof(host.bindSerialTerminalConsoleDevice)=="function")
49            host.bindSerialTerminalConsoleDevice(device);
50
51        return !!host;
52    };
53
54    /*
55     * Pipe -> browser terminal. This is UI/status text, not serial payload.
56     */
57    this.receive = function(message,context)
58    {
59        var text = normalizeText(message);
60        if(!text.length || !host ||
61           typeof(host.serialTerminalConsoleWrite)!="function")
62            return false;
63
64        host.serialTerminalConsoleWrite(
65            text,
66            {
67                 "source":"pipe"
68                ,"context":context || null
69            }
70        );
71        return text.length;
72    };
73
74    this.receiveText = function(text,meta)
75    {
76        text = normalizeText(text);
77        if(!text.length || !host ||
78           typeof(host.serialTerminalConsoleWrite)!="function")
79            return 0;
80
81        host.serialTerminalConsoleWrite(text,meta || {});
82        return text.length;
83    };
84
85    /*
86     * Browser-terminal console -> connected observers. The current oTERM input
87     * remains the serial-data input; this output side is reserved for future
88     * terminal control/diagnostic commands and generic pipeConnect().
89     */
90    this.subscribe = function(callback)
91    {
92        if(typeof(callback)!="function")
93            return function(){};
94
95        if(listeners.indexOf(callback)<0)
96            listeners.push(callback);
97
98        var subscribed = true;
99        return function()
100        {
101            if(!subscribed) return;
102            subscribed = false;
103
104            var index = listeners.indexOf(callback);
105            if(index>=0) listeners.splice(index,1);
106        };
107    };
108
109    this.transmitText = function(text,meta)
110    {
111        text = normalizeText(text);
112        var snapshot = listeners.slice();
113
114        for(var i=0;i<snapshot.length;i++)
115        {
116            try { snapshot[i](text,meta || {}); }
117            catch(error)
118            {
119                console.error("SPTERM console subscriber failed",error);
120            }
121        }
122
123        return text.length;
124    };
125
126    this.reset = function()
127    {
128        // Browser/operator console remains present across Apple II RESET.
129        return true;
130    };
131}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.