From 5d6d37223a84f7992159230a7a453b4d1c5c25c0 Mon Sep 17 00:00:00 2001 From: burniouf Date: Fri, 13 Aug 2021 20:34:20 +0200 Subject: [PATCH] KERNEL:Memory reorg, GETTY,LOGIN,PS....lots of bytes saved, SSC:bugfixes in command line parsing, MEMDUMP:bugfixes paged listing and display --- .Docs/Forth Words.md | 79 ++++----- .Floppies/A2OSX.BUILD.po | Bin 33553920 -> 33553920 bytes BIN/EDIT.S.txt | 2 +- BIN/MEMDUMP.S.txt | 56 ++++--- BIN/PS.S.txt | 17 +- BIN/TELNET.S.txt | 106 ++++++------ BIN/TUITEST.S.txt | 59 ++++++- DRV/SSC.DRV.S.txt | 1 + DRV/SSC.I.DRV.S.txt | 1 + INC/LIBTUI.I.txt | 21 ++- INC/NET.TELNET.I.txt | 3 +- LIB/LIBTUI.S.txt | 349 +++++++++++++++++++++++++++++++++++---- SBIN/GETTY.S.txt | 32 ++-- SBIN/LOGIN.S.txt | 57 ++++--- SHARED/X.SSC.DRV.S.txt | 6 +- SYS/KERNEL.S.BIN.txt | 32 ++++ SYS/KERNEL.S.MEM.txt | 27 --- SYS/KERNEL.S.txt | 2 +- 18 files changed, 615 insertions(+), 235 deletions(-) diff --git a/.Docs/Forth Words.md b/.Docs/Forth Words.md index 372c148c..e077a7ea 100644 --- a/.Docs/Forth Words.md +++ b/.Docs/Forth Words.md @@ -2,7 +2,7 @@ ## Description -This document lists all of the **Forth Words** supported in the A2osX implementation of **FigForth**. Note that not all **Words** are implemented at this time, please check the *Status* and *Comment* Columns. Currently only an interpreter is available (*../bin/forth*) | | | though a compiler is planned | +This document lists all of the **Forth Words** supported in the A2osX implementation of **FORTH-79**. Note that not all **Words** are implemented at this time, please check the *Status* and *Comment* Columns. Currently only an interpreter is available (*../bin/forth*) | | | though a compiler is planned | ## Word Notation @@ -75,12 +75,15 @@ The definitions are listed in ASCII alphabetical order in several groups con | Word | Syntax | I/C | Status | Description | Comment | |-|-|-|-|-|-| | DUP | n -- n n | I,C | Working | Duplicate top of stack | | -| ?DUP | n -- n n | I,C | impl. | duplicate n if non-zero | | +| ?DUP | n -- n n | I,C | Working | duplicate n if non-zero | | | DROP | n -- | I,C | Working | Drop top number from the stack | | | SWAP | n1 n2 -- n2 n1 | I,C | Working | Reverse top two stack items | | | OVER | n1 n2 -- n1 n2 n1 | I,C | Working | Leave a copy of the second number on the stack. | | - - +| ROT | n1 n2 n3 -- n2 n3 n1 | I,C | Working | Rotate the top three values, bringing the deepest to the top. | | +| DEPTH | -- n | | | Leave number of the quantity of 16-bit values contained in the data stack, before n added | | +| >R | n -- | C | | Move n to return stack | | +| R> | -- n | C | | Transfer n from the return stack to the data stack. | | +| R@ | -- n | C | | Copy the number on top of the return stack to the data stack. | | ## COMPARISON @@ -110,6 +113,18 @@ The definitions are listed in ASCII alphabetical order in several groups con | 2+ | n -- n+2 | | | Increment n by two | | | 2- | n -- n-2 | | | Decrement n by two | | | MOD | n1 n2 -- n3 | I,C | Working | Divide n1 by n2, leaving the remainder n3, with the same sign as n1. | | +| U* | un1 un2 -- ud3 | | | Perform an unsigned multiplication of un1 by un2, leaving the double number product ud3. All values are unsigned. | | +| U. | un -- | I,C | Working | Display un converted according to BASE as an unsigned number, in a free-field format, with one trailing blank. | | +| U/MOD | ud1 un2 -- un3 un4 | | | Perform the unsigned division of double number ud1 by un2, leaving the remainder un3, and the quotient un4. All values are unsigned. | | +| U< | un1 un2 -- flag | | | Leave the flag representing the magnitude comparison of un1 < un2 where un1 and un2 are treated as 16-bit unsigned integers. | | +| ABS | n1 -- n1 | I,C | Working | Absolute value of n1 | | +| MAX | n1 n2 -- n3 | I,C | Working | Leave the greater of two numbers. | | +| MIN | n1 n2 -- n3 | I,C | Working | Leave the lesser of two numbers. | | +| NEGATE | n -- -n | | | Leave the two's complement of a number, i.e., the difference of zero less n. | | +| DNEGATE | d -- -d | I,C | Working | Leave the two's complement of a double number. | | +| AND | n1 n2 -- n3 | I,C | Working | Leave Logical bitwise AND of n1 and n2 | | +| OR | n1 n2 -- n3 | I,C | Working | Leave the bitwise inclusive-or of two numbers. | | +| XOR | n1 n2 -- n3 | I,C | Working | Leave the bitwise exclusive-or of two numbers. | | ## MEMORY @@ -117,11 +132,16 @@ The definitions are listed in ASCII alphabetical order in several groups con |-|-|-|-|-|-| | @ | addr -- n | I,C | Working | Put on stack number at addr | | | ! | n addr -- | I,C | Working | Store second word at address on top | | +| C@ | addr -- byte | | Working | Leave on stack addr, with high bits set to 0 for 16-bit field | | +| C! | n addr -- | | Working | Store least significant of n in addr | | ## CONTROL STRUCTURES | Word | Syntax | I/C | Status | Description | Comment | |-|-|-|-|-|-| +| IFTRUE | flag -- | I | | Begin an
IFTRUE ... OTHERWISE ... IFEND
conditional sequence. These conditional words operate like
IF ... ELSE ... THEN
except that they cannot be nested, and are to be used only during interpretation. In conjunction with the words [ and ] they may be used within a colon-definition to control compilation, although they are not to be compiled. | | +| OTHERWISE | | I | | An interpreter-level conditional word. See IFTRUE. | | +| IFEND | | I | | Terminate a conditional interpretation sequence begun by IFTRUE. | | | DO | n1 n2 -- | C | Working | Used in a colon-definition:
DO ... LOOP or
DO ... +LOOP
Begin a loop which will terminate based on control parameters. The loop index begins at n2, and terminates based on the limit n1. At LOOP or +LOOP, the index is modified by a positive or negative value. The range of a DO-LOOP is determined by the terminating word. DO-LOOP may be nested. Capacity for three levels of nesting is specified as a minimum for standard systems. | | | LOOP | -- | C | Working |Increment the DO-LOOP index by one, terminating the loop if the new index is equal to or greater than the limit. The limit and index are signed numbers in the range {-32,768..32,767}. | | | +LOOP | n -- | C | Working | Increment index by n. Terminate loop if outside limit | | @@ -130,6 +150,7 @@ The definitions are listed in ASCII alphabetical order in several groups con | J | -- n | C | | Return the index of the next outer loop. May only be used within a nested DO-LOOP in the form:
DO ... DO ... J ... LOOP ... LOOP | | | IF | flag -- | C | Working | Used in a colon-definition in the form:
flag IF ... ELSE ... THEN or
flag IF ... THEN
If flag is true, the words following IF are executed and the words following ELSE are skipped. The ELSE part is optional. If flag is false, words between IF and ELSE, or between IF and THEN (when no ELSE is used), are skipped. IF-ELSE-THEN conditionals may be nested. | | | ELSE | -- | C | Working | Used in a colon-definition in the form:
IF ... ELSE ... THEN
ELSE executes after the true part following IF. ELSE forces execution to skip till just after THEN. It has no effect on the stack. (see IF) | | +| THEN | -- | C | Working | Used in a colon-definition in the form:
IF ... ELSE ... THEN or
IF ... THEN
THEN is the point where execution resumes after ELSE or IF (when no ELSE is present). | | | BEGIN | -- | C | Working | Used in a colon-definition in the form:
BEGIN ... flag UNTIL or
BEGIN ... flag WHILE ... REPEAT
BEGIN marks the start of a word sequence for repetitive execution. A BEGIN-UNTIL loop will be repeated until flag is true. A BEGIN-WHILE-REPEAT loop will be repeated until flag is false. The words after UNTIL or REPEAT will be executed when either loop is finished. flag is always dropped after being tested. | | | WHILE | flag -- | C | Working | Used in the form:
BEGIN ... flag WHILE ... REPEAT
Select conditional execution based on flag. On a true flag, continue execution through to REPEAT, which then returns back to just after BEGIN. On a false flag, skip execution to just after REPEAT, exiting the structure. | | | REPEAT | -- | C | Working | Used in a colon-definition in the form:
BEGIN ... WHILE ... REPEAT
At run-time, REPEAT returns to just after the corresponding BEGIN. | | @@ -158,7 +179,9 @@ The definitions are listed in ASCII alphabetical order in several groups con | <# | -- | | | Initialize pictured number output | | | #> | d -- addr n | | | Terminate output string for TYPE | | | BASE | -- addr | U | | Leave address of variable containing current input-output number conversion base. {{2..70} | | +| OCTAL | -- | | | Set the number base to 8. | | | DECIMAL | -- | | | Set input-output numeric conversation base to ten | | +| HEX | -- | | | Set the numeric input-output conversion base to sixteen. | | | CONVERT | d1 addr1 -- d2 addr2 | | | Convert to the equivalent stack number the text beginning at addr1+1 with regard to BASE. The new value is accumulated into double number d1, being left as d2. addr2 is the address of the first non-convertible character. | | ## MASS STORAGE INPUT-OUTPUT @@ -171,6 +194,16 @@ The definitions are listed in ASCII alphabetical order in several groups con | SAVE-BUFFERS | | | | Write all blocks to mass-storage that have been flagged as UPDATEd. An error condition results if mass-storage writing is not completed. | | | EMPTY-BUFFERS | | | | Mark all block buffers as empty, without necessarily affecting their actual contents. UPDATEd blocks are not written to mass storage. | | +## DEFINING WORDS +| Word | Syntax | I/C | Status | Description | Comment | +|-|-|-|-|-|-| +| : | -- | I | Working | Begin a colon definition | | +| ; | -- | C | Working | End of a colon definition | | +| CONSTANT | n -- | I,C | Working | A defining word used in the form:
n CONSTANT **name**
to create a dictionary entry for **name**, leaving n in its parameter field. When **name** is later executed, n will be left on the stack. | | +| VARIABLE | n -- | I,C | Working | A defining word executed in the form:
VARIABLE **name** to create a dictionary entry for **name** and allot two bytes for storage in the parameter field. The application must initialize the stored value. When **name** is later executed, it will place the storage address on the stack. | | + + + ## Words | Word | Syntax | I/C | Status | Description | Comment | @@ -183,28 +216,18 @@ The definitions are listed in ASCII alphabetical order in several groups con | . | n -- | I,C | Working | Print number | | | ." | -- | I,C | Working | Print message terminated by " | | | 79-STANDARD | | | | Returns Error if FORTH-79 Standard is not available| | -| : | -- | I | Working | Begin a colon definition | | -| ; | -- | C | Working | End of a colon definition | | | >IN | -- addr | U | | Leave addr of variable of char offset input stream {0,,1023}| | -| >R | n -- | C | | Move n to return stack | | | ? | addr -- | I,C | Working | Print contents of address | | | ABORT -- | | | | Clear data and return stacks | | -| ABS | n1 -- n1 | I,C | Working | Absolute value of n1 | | | ALLOT | n -- | I,C | Working | Add n bytes to parameter field of most recently defined word | | -| AND | n1 n2 -- n3 | I,C | Working | Leave Logical bitwise AND of n1 and n2 | | | BLK | -- addr | U | | Leave the address of a variable containing the number of the mass storage block being interpreted as the input stream. If the content is zero, the input stream is taken from the terminal.| | | BUFFER | n -- addr | | | Obtain next block buffer, assign to n | | -| C! | n addr -- | | Working | Store least significant of n in addr | | -| C@ | addr -- byte | | Working | Leave on stack addr, with high bits set to 0 for 16-bit field | | | CMOVE | addr1 addr2 n -- | | | Move n bytes at addr1 to addr2 | | | COMPILE | | C | | When a word containing COMPILE executes, the 16-bit value following the compilation address of COMPILE is copied (compiled) into the dictionary. i.e., COMPILE DUP will copy the compilation address of DUP.
COMPILE [ 0 , ] will copy zero. | | -| CONSTANT | n -- | I,C | Working | A defining word used in the form:
n CONSTANT **name**
to create a dictionary entry for **name**, leaving n in its parameter field. When **name** is later executed, n will be left on the stack. | | | CONTEXT | -- addr | U | | Leave the address of a variable specifying the vocabulary in which dictionary searches are to be made, during interpretation of the input stream. | | | CREATE | | | | A defining word used in the form:
CREATE **name**
to create a dictionary entry for , without allocating any parameter field memory. When **name** is subsequently executed, the address of the first byte of **name**'s parameter field is left on the stack. | | | CURRENT | -- addr | U | | Leave the address of a variable specifying the vocabulary into which new word definitions are to be entered. | | | DEFINITIONS | -- | | | Set current vocabulary to context vocabulary | | -| DEPTH | -- n | | | Leave number of the quantity of 16-bit values contained in the data stack, before n added | | -| DNEGATE | d -- -d | I,C | impl. | Leave the two's complement of a double number. | | | DOES | | I,C | | Define the run-time action of a word created by a high-level defining word. Used in the form:
: **name** ... CREATE ... DOES> ... ;
and then **namex name**
Marks the termination of the defining part of the defining word **name** and begins the defining of the run-time action for words that will later be defined by **name**. On execution of **namex** the sequence of words between DOES> and ; are executed, with the address of **namex**'s parameter field on the stack. | | | EXECUTE | addr -- | | | Execute the dictionary entry whose compilation address is on the stack. | | | EXIT | | C | | When compiled within a colon-definition, terminate execution of that definition, at that point. May not be used within a DO...LOOP. | | @@ -216,30 +239,16 @@ The definitions are listed in ASCII alphabetical order in several groups con | HOLD | char -- | | | Insert ASCII character into pictured output string. May only be used between <# and #>. | | | IMMEDIATE | | | | Marks the most recently made dictionary entry as a word which will be executed when encountered during compilation rather than compiled. | | | LITERAL | n -- | I | | f compiling, then compile the stack value n as a 16-bit literal, which when later executed, will leave n on the stack. | | -| MAX | n1 n2 -- n3 | I,C | Working | Leave the greater of two numbers. | | -| MIN | n1 n2 -- n3 | I,C | Working | Leave the lesser of two numbers. | | | MOVE | addr1 addr2 n -- | | | Move the specified quantity n of 16-bit memory cells beginning at addr1 into memory at addr2. The contents of addr1 is moved first. If n is negative or zero, nothing is moved. | | -| NEGATE | n -- -n | | | Leave the two's complement of a number, i.e., the difference of zero less n. | | | NOT | flag1 -- flag2 | | | Reverse the boolean value of flag1. This is identical to 0=. | | -| OR | n1 n2 -- n3 | I,C | Working | Leave the bitwise inclusive-or of two numbers. | | | PAD | -- addr | I,C | Working | The address of a scratch area used to hold character strings for intermediate processing. The minimum capacity of PAD is 64 characters (addr through addr+63). | | | PICK | n1 -- n2 | | | Return the contents of the n1-th stack value, not counting n1 itself. An error condition results for n less than one.
2 PICK is equivalent to OVER. {1..n} | | | QUIT | | | | Clear the return stack, setting execution mode, and return control to the terminal. No message is given. | | -| R> | -- n | C | | Transfer n from the return stack to the data stack. | | -| R@ | -- n | C | | Copy the number on top of the return stack to the data stack. | | | ROLL | n -- | | | Extract the n-th stack value to the top of the stack, not counting n itself, moving the remaining values into the vacated position. An error condition results for n less than one. {1..n}
3 ROLL = ROT
1 ROLL = null operation | | -| ROT | n1 n2 n3 -- n2 n3 n1 | I,C | Working | Rotate the top three values, bringing the deepest to the top. | | | SCR | -- addr | U | | Leave the address of a variable containing the number of the screen most recently listed. | | | SIGN | n -- | C | | Insert the ASCII "-" (minus sign) into the pictured numeric output string, if n is negative. | | | STATE | -- addr | U | | Leave the address of the variable containing the compilation state. A non-zero content indicates compilation is occurring, but the value itself may be installation dependent. | | -| THEN | | C | Working | Used in a colon-definition in the form:
IF ... ELSE ... THEN or
IF ... THEN
THEN is the point where execution resumes after ELSE or IF (when no ELSE is present). | | -| U* | un1 un2 -- ud3 | | | Perform an unsigned multiplication of un1 by un2, leaving the double number product ud3. All values are unsigned. | | -| U. | un -- | I,C | Working | Display un converted according to BASE as an unsigned number, in a free-field format, with one trailing blank. | | -| U/MOD | ud1 un2 -- un3 un4 | | | Perform the unsigned division of double number ud1 by un2, leaving the remainder un3, and the quotient un4. All values are unsigned. | | -| U< | un1 un2 -- flag | | | Leave the flag representing the magnitude comparison of un1 < un2 where un1 and un2 are treated as 16-bit unsigned integers. | | -| VARIABLE | n -- | I,C | Working | A defining word executed in the form:
VARIABLE **name** to create a dictionary entry for **name** and allot two bytes for storage in the parameter field. The application must initialize the stored value. When **name** is later executed, it will place the storage address on the stack. | | | VOCABULARY | -- | | | A defining word executed in the form:
VOCABULARY **name**
to create (in the CURRENT vocabulary) a dictionary entry for **name**, which specifies a new ordered list of word definitions. Subsequent execution of **name** will make it the CONTEXT vocabulary. When **name** becomes the CURRENT vocabulary (see DEFINITIONS), new definitions will be created in that list.
In lieu of any further specification, new vocabularies 'chain' to FORTH. That is, when a dictionary search through a vocabulary is exhausted, FORTH will be searched. | | -| XOR | n1 n2 -- n3 | I,C | Working | Leave the bitwise exclusive-or of two numbers. | | | [ | | I | | End the compilation mode. The text from the input stream is subsequently executed. See ] | | | [COMPILE] | | I,C | | Used in a colon-definition in the form:
[COMPILE] **name**
Forces compilation of the following word. This allows compilation of an IMMEDIATE word when it would otherwise be executed. | | | ] | | | | Sets the compilation mode. The text from the input stream is subsequently compiled. See [ | | @@ -259,17 +268,16 @@ DOUBLE NUMBER WORD SET | 2ROT | d1 d2 d3 -- d2 d3 d1 | | | Rotate the third double number to the top of the stack. | | | 2SWAP | d1 d2 -- d2 d1 | | | Exchange the top two double numbers on the stack. | | | 2VARIABLE | | | | A defining word used in the form:
2VARIABLE **name**
to create a dictionary entry of **name** and assign four bytes for storage in the parameter field. When **name** is later executed, it will leave the address of the first byte of its parameter field is placed on the stack. | | -| D+ | d1 d2 -- d3 | I,C | impl. | Leave the arithmetic sum of d1 and d2. | | -| D- | d1 d2 -- d3 | I,C | impl. | Subtract d2 from d1 and leave the difference d3. | | -| D. | d -- | I,C | impl. | Display d converted according to BASE in a free field format, with one trailing blank. Display the sign only if negative. | | +| D+ | d1 d2 -- d3 | I,C | Working | Leave the arithmetic sum of d1 and d2. | | +| D- | d1 d2 -- d3 | I,C | Working | Subtract d2 from d1 and leave the difference d3. | | +| D. | d -- | I,C | Working | Display d converted according to BASE in a free field format, with one trailing blank. Display the sign only if negative. | | | D.R | d n -- | | | Display d converted according to BASE, right aligned in an n character field. Display the sign only if negative. | | | D0= | d -- flag | | | Leave true if d is zero. | | | D< | d1 d2 -- flag | | | True if d1 is less than d2. | | | D= | d1 d2 -- flag | | | True if d1 equals d2. | | -| DABS | d1 -- d2 | I,C | impl. | Leave as a positive double number d2, the absolute value of a double number, d1. {0..2,147,483,647} | | +| DABS | d1 -- d2 | I,C | Working | Leave as a positive double number d2, the absolute value of a double number, d1. {0..2,147,483,647} | | | DMAX | d1 d2 -- d3 | | | Leave the larger of two double numbers. | | | DMIN | d1 d2 -- d3 | | | Leave the smaller of two double numbers. | | -| DNEGATE | d -- -d | I,C | impl. | Leave the double number two's complement of a double number, i.e., the difference 0 less d. | | | DU< | ud1 ud2 -- flag | | | rue if ud1 is less than ud2. Both numbers are unsigned. | | ## Assembler Word Set @@ -329,10 +337,7 @@ The Reference Word Set contain both Standard Word Definitions and uncontrolled | ERASE | addr n -- | | Working | Fill an area of memory over n bytes with zeros, starting at addr. If n is zero or less, take no action. | | | FLD | -- addr | | | A variable pointing to the field length reserved for a number during output conversion. | | | H. | n -- | | | Output n as a hexadecimal integer with one trailing blank. The current base is unchanged. | | -| HEX | -- | | | Set the numeric input-output conversion base to sixteen. | | | I' | -- n | C | | Used within a colon-definition executed only from within a DO-LOOP to return the corresponding loop index. | | -| IFEND | | | | Terminate a conditional interpretation sequence begun by IFTRUE. | | -| IFTRUE | flag -- | | | Begin an
IFTRUE ... OTHERWISE ... IFEND
conditional sequence. These conditional words operate like
IF ... ELSE ... THEN
except that they cannot be nested, and are to be used only during interpretation. In conjunction with the words [ and ] they may be used within a colon-definition to control compilation, although they are not to be compiled. | | | INDEX | n1 n2 -- | | | Print the first line of each screen over the range {n1..n2}. This displays the first line of each screen of source text, which conventionally contains a title. | | | INTERPRET | | | | Begin interpretation at the character indexed by the contents of >IN relative to the block number contained in BLK, continuing until the input stream is exhausted. If BLK contains zero, interpret characters from the terminal input buffer. | | | K | -- n | C | | Within a nested DO-LOOP, return the index of the second outer loop. | | @@ -347,9 +352,7 @@ The Reference Word Set contain both Standard Word Definitions and uncontrolled | NOR | n1 n2 -- n3 | | | The one's complement of the logical or of n1 and n2. | | | NUMBER | addr -- n | | | Convert the count and character string at addr, to a signed 32-bit integer, using the current base. If numeric conversion is not possible, an error condition exists. The string may contain a preceding negative sign. | | | O. | n -- | | | Print n in octal format with one trailing blank. The value in base is unaffected. | | -| OCTAL | | | | Set the number base to 8. | | | OFFSET | -- addr | | | A variable that contains the offset added to the block number on the stack by BLOCK to determine the actual physical block number. The user must add any desired offset when utilizing BUFFER. | | -| OTHERWISE | | | | An interpreter-level conditional word. See IFTRUE. | | | PAGE | | | | Clear the terminal screen or perform an action suitable to the output device currently active. | | | READ-MAP | | | | Read to the next file mark on tape constructing a correspondence table in memory (the map) relating physical block position to logical block number. The tape should normally be rewound to its load point before executing READ-MAP. | | | REMEMBER | | | | A defining word used in the form:
REMEMBER **name**
Defines a word which, when executed, will cause **name** and all subsequently defined words to be deleted from the dictionary. **name** may be compiled into and executed from a colon definition. The sequence
DISCARD REMEMBER DISCARD
provides a standardized preface to any group of transient word definitions. | | diff --git a/.Floppies/A2OSX.BUILD.po b/.Floppies/A2OSX.BUILD.po index 4b7189362944137d6dbe60fae70964bdd555ef7a..64188a7f205374e7e2dbc9d5e1fde052e864df08 100644 GIT binary patch delta 36281 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 AU;qFB delta 37246 zcma%k2V7J~*Z15lu&{+?JN?2gD2OXy0}IlHh=43A8Z{uGpa=-qjj&O$M6g9CrWhnb z#7M*v(L@u|HOZS0W1iT%D2fTDJTaB;%-p-n65sFleet*4d#9W^GjrygGyggFruwg5 zw`%yc-4lsi2N~VBb&HH5!62Q>HnrFYDZwt=M!}8qpn=kDxp4DONPukHI=Ep5A=$PA z;-`epgFLqVB@X6l2Ro5UgIy12IGu6Xrj+HYgw`;GP!2)@6dNOA5%R;2qP*F|2b3A7 zHETs8)FeXB1}K#1w_AuU3K6?*Q(rKOib9-Rw~e~+fRSzsy0~eG2SS^JkQDuO3n9rM zy=npS%!w2=x9zxhQ<;rWS)i{D^#J$L z!Ftzi>$;4hIUyb{hYxhEmI+5@zKa>9%Qrh738eV1S54||rr(r|2s7?3Uu=DRTKHOv z@8K^V5BFzU+Zj)$m%*2w76#%hkAeY*m9ituQD0`%3Yq5qnzJ?E);Flxl|4^OYTQFF8QdQ;D*m$zPSx=H`u!0t5) zZCu+x+p}XHxo=zrRrlOzy4e^4H`Rxmt~dS{ZVZy-rk=(KxGNl(6PaVk!QmA%_G6qQ zP~zh`f{%{Q7PLzQOYgQHpC>pZ@Y0W|eR}<@Q6=9$i(YeWWU5PRJ5DyJdkWalZd|)S zutWgY-UWic1Q`$U-z9><3b3 z9#<)dBiGfHf{g-?`|a+F1mm3DTOvYRRG}@Ip)KX1EkD)uc;g{yqD(f!hrR8+H_Tae zxyPx632hODwg`fIs}<~d?`k1?$s6xZ6B%?JKCIez;O6+IR}-6*V_Wh(?vzHm0$R*?V5idp%3ov!~Prnyj<`Pv0ZgPxcqqk z=qkY@KOYh6a-s#1@pSxKNCz0TD|QKPi5XG*Pp=CUF#`je?w>&&eyv89WVZ&;OVcIt z&~%a3cn5|(^*8K&TaYJh2cKX?NV+Vn8*R+lKiY`X?x}pd+zy^S z!)%`4;NB=ac>PtgY2D|_-&#)B++&p|aLm+kegY`?+B{*_pi!o}(Wce`oFoL%OCvft z!bHU2-gQyOFRi2Led{O_J~&;X#Y0Yxb;42eh3U^QM|7c@l04qGP*)4hhK(;lQ zrR%sbGKX)k=`IdGF;=aGVkS~dcIHIK>85)f-?yBoK815mjP)4Sr$P3uxmk0owiDQF zx(l6Y90N7lg7DI1biH@CqQJ>8NH20 zBaw>+G7y5z13Pau-Qpx<)SBxxH`rx3cDYcGKM3;nku=@uxz=>M=MpYmE}X}x@WtiA zC?*7JRtU|^5gfllxH#%JwlRnd^0b=!`470;v@^Xu?t30=xp=w-ZMnGS!6~+*vw8%V z7jdSiV^CAq8AHd>l|o76G^-#2DcunYWzFof0aXFk0A!RJJ&b<_m|=e7jTXx5eiPdo z$g;Qm+kWBJFzGA#HFiMTn}>3<&3@(Ic5Z(V3vtzIlipJ!;gSmeLA z=~5ADR2tX<|F-P?-fXK6&78RBV$-EYHj*UA?q}Inf0B$(9TBqHKiSQi{l09gA2)ez z&Y#}usK>t^5n7mOIOT2OLgxS$)CKz${@`ul*yf``0j|C$*d(}r7rS=};>mSNmtfz~ zV?q%V4k{q5$9Y3aZ@8&ixWV1D#gzJbV}t6T$#aWoFMI#)7Skzp&&LhwgQhcobjTs0 zefV)<217LS+INI^1wY?yFMC%QEO7qhfgy+0-^UFng&z_^I8s`Rd z&}oaP$K`a#Z=KGa;_63`1^fUHTp65mPN;PTwgO4#R-O}vkOx~&BmCguU7nW~SnE)! zN7Qt@!?R&<3nFv&&pF{R1N6alji5$&k^Qs1(2$dAC;rrT!ZdAZS7cW&u-Yd4s;tXE zNC3h1*6)NqB6(={MsHN-gARF<=D)unEb_D^?K#$Te53qCo#MoP#fgJ7fBHpXAelz% zMd6TGkNa(YYrJcG>LX83y&_^EMZU(j#t#PDcf(fimfoCXpt^DViMr$ypzL~kdn6a3 z+A@4hN55oG(eyI&Jp1tj5x8^Z49+d@%$ z^-U0$9ruI>Nb13RLW4kazx|7Q!nc{`ZXwvm`y~4ZVX*v@2hG(ddsVx7RnSuVh#!Pc z37UTr8gO-wFk3L^Zu`X^VGy&!RaD(96A8wf)6H=yX|b8pkZ(G()0_}%HKxSIhZ?7* zq^5=%v(g|xF+MpR`DFZGaxLRyk=G>rj6&og_Q_;IUc|Wyks5DOh@2P;N!CiTvZiGu zA~uUYNmEnO5+|l7BqHNv{H;P1;4*~?ITbV*MNh^5C`4nKY&^zI6zVdKOHG)L7rKe! znWypFkUC-plbANeoRye4aickQx;22@1t7^xuCR0#VRG`siPMnlGjN-p3Htz94uh** zMIR7ZlGM1I^iy}J*!fqQB!(hcjiAY;2-OIysz3W*=Dx$Hd|zDyL{-n z61)P?rcKukMUtB9n+2UWnr=5ZeRHwn3i~;0FL<~CvG))y`$a&LXTQP3a_|91YJ9J^)4%!xR?AoU&mTbSq><{dmeoL=4u7bPh!H!ugU6GPD;hU?J? z5hK8E!$iLE(~X;jY=g1Ig<28frX0E+Eb5roAUb%x=H_Yma|`sq%^sJqh%@YF^XZPC z!6=Zjtt`E~*yD-IhKY0{_8nsmUO!Ca&)u~S69sX1{~0D)<=(FuS~P#SC}#lmi`rzJ zolTu*belz=-p%i%UQ(U#)WPd@f>Sw#6AKowNjq|+ez@9OG@5w{pYRq<|Cd6?CLhsI zGJn&2L@UUA{>KLz2h9?EbcD!AG(8R+DJu1W6z?^thH23xpe6=9!(L)3 z4vrLU7x>-7$&sR9w@)6Jj7kan^SL(P)WP32G>;OAaCM}J+L(kW(N&``A?n8f7nC#aI`2hJgWPUQuz~XA(TDc zM8o9$r!N0L4G8$T(A(Q_;j|0t__=oO1~#gj&FVI!4(Y}t#)(3!@RhdY+PTRu7Q9-s zyRcwaP2&c#8lW%i_3uHF8zcu2m^ZYX{q}oy!S{r3Pe^W>3v>=CT|`@z8ybXLl+AMq z#T?i+&4nJrrim#0Lzg=**St#q?jnEpl0QI)rtFTq^C~2;P^9tBt~IaM>|sM5wndSa ziHX=)^nKm@?|}!*#E1fB)O_F23#t=j4V_upBRP}WBWhV3nFAi!!|xlEp$!6Hu}8WN zo=$iC(#cf!u#0Xry=EwAs(GWSp`f{D?;-TmzLW0f+eA;nf5C3+B|R>|&dCi7)WA(K zqN~m@g-P|d&f^WSqLEdP&P$T%+(AzUMs@<*Ic&>?wxBw%3$Gv*yW(P-nEmb2W=(Rd z*99W7EduhFJ#d+Lp1rheXx$qZ8kiQrmP%L{XiFtG?r^V6UUyL0;IXB0T_NN-9Ykz# zcUyLY6BG&Up5EXE8Ag)h%;k)0aOQJ-_$o@8f%D=-GnAV9ZP(UR)-2la$E$R!jlYf) z=|_cjSBv(XZTgmqr0^hG2jpC#R%kc-+qt$x*phE(aD_A%NSo2!Hmt#AOJ$w-6r^J| zUKEu}`vJ0iu&hUMW=O|xd&-&?vSY4oR_D;Wx36w?p*Q$yo2hk}@QhQB=8UMv6EUA`d1K{~0fe zHh~5m%k>|+zkv=&N_T_opwr$SK})Y^qd(YEJTpP$B>+B`Cy3S;?Y`WIT9K-UxkuO` zy*-3_l=m7CNJGb;?C#4T1=Y}3w=I=T<%S}`-lmEo;vlpQC62*{1|^IvG=W;&+4{?b z5O^jnD!A_>w^h(1X1C(vMA4uDUtA`Vdj|FR)V+0?mFe2_q{)`vGr~5h>%NuWUA}+$ z>gDds_`O6?fZxa~AdzBf+CNu5I)v7PzXP2?1XZ}%`WEg@6nPMh;+Z7!3V8lXn_qqD zm5oJL>gHdePSd^aHZc`>UJh~HRd;{9G)XjpD2PvzMCOvgSL=pcH5DqAuz2Uy4Y*oZ zFu!i#)mM6Z*>hJ&)#f4tsEl)0nu^GhjLad-*KN50JKBC8u8UakA#D&)e>1BEsULK{UJY5vLFYh*c`%%PXQ z?L^}Vg8n3M_38tzz0!5H0X3rI-~&ldpBdHT^eS?{SKYIrCtxGVfpkdd5uLtQ{Ra=2MvM6%woNM#0m0SZf4JBkwK^d`G$%x9nzR~&Qq=#D& z*@1%QXX~zk>W4HW;nEB_XsR4nCyN?#ww&K~-si%B%lOLTD=}9quC2H^9saGjslMk7 z|J3)w@1@_Hag+QbIg9VDho@Kgza(va*LL_f{pOyoJzYoOpZ@;wuF&pJ9_a6nxk9e( z)hVKn1XU$IulO|j-0;5b{fGBo-a$UWKA}ECd?I{?`<(Z_~sEoe%H)eCNM+e!uhAo!&cw&RutQ-`R5~sB=)~Q=LmYSM@Iw`b42d zA@~M)cMbJBZ*P3}_A3Hrvx}h#+!yvnC;lN7tX|$-JbxmfL38fnHz$e`1d#q{q9_I* zOc$lgMWK!2lP}(>Gj_83?qK;mkwUJAiHNzJty4M1I;YI@!ma|H8J4@Kh0D)iGE1mfKJdwYk^e+B$o+yZ1jq^oQ$F97) z`L65)`S%K3U%LCs-QDny{opQmHSFGM*P3wl>RsUIgS)L4-vfyQt$Nnf!x-j-vG3i* z?ej$`J4!@B&1IrtIH*Lleqw1?YgyM@C0z#g^u5hY&i>V1t!uj8daf&SV@+3GZC3+e zrkh0sCEd8Tt8QJ_{+h1V+Ael4=h`8UsWtS{I0DursgXfywDeN-)Y40KA~Q-wvkTk1s1`UzFZ;lV+4s9F zsHhS3&iD7XceNhtS`%F}j%Zd>z2g3wxSIG@=lf*AxjlphXJFkw0?PkDOD(8mQLU~<`{H^xFvLBEqUL7NJIvedOpcfl_%MV|PHzw#CY0bXv)A0NxdRIHERJ0m z=dC4tpJ*G}AU$}tF`C>C+}lxy-ybRT*A0Wm&7$h*)x$}ZLpRT8dKLl>1l4?WK+R03 z2~)55C$|pf{LN6Tlu2~>TAEmlKS&e%58WTewuWAlFDrn@~7 z!cz!PY3l3|Q@FSl(5RRcp$0Eo8y$!rdo!8%i%c<#gEvGE!y=1VgRu`&1nBq*=I9); zM+Cm^Ib~dX#0Ia(MvP=fB=`e@GMkkIzU?}!UD8tpV>4iDQAoiW*xJk^?No@f~# zhR^wV8{e!)`YF$=qYEjA=QgLcj?SZFnmM4DW*b6!QcHQr**oSa6s zOc_Wz8|{p?q$Vb2AZ0!>kHkeKc{~9{fde^w|NSy=Q8)@K!kfMp4`Jrvo;>FPBV6Yr za}=gad;#2r*_OCvS{jm+pq+Gumm;bJBxQ(h`2rSV?+&qlRXJ%nYg(*zdPasNqp}>S zDj~(8Tj5B&2<=3Q#SVNR{Sxw&Yt68jvvOw_7nln(ETK!0bSYmq7O9t$63eVcix~=K zWTYg3x`Hvoq}o8fvEb0EWk~w0y^>@V+F4Yx3~8&-&b%^PWjOdr0Bt9&hA}KDu$qA* zD{$oT+`o9RROVJz02j*DHi9+r8IuE%vc{1W3)0kb6$ux3^fzLcQESo8%G{+$x89-a zmaN#U$)r9<4k{9N!f$b`7>fElb@YPHi9V^a7< zdz+R-izOvJ%{&>#*kdP7Ju5am^^$D}koaXN?e+@)9G7AZ4@2Tt(F;hki!?XQ5+9qI zYRxDwDyd9D?hV|~*xSMD=dVGtIS*`$^hk1dBGaNT2*JxLQMS-NIqlWm8g z@_wUl(21M{uO44eX`MrdQL~rt3rI>*YV3H+ppi)0LeiF6jU$oko2behfr~53kz_yG zSyq^frx~;3Z%-4t>y?Tk{sh#%yASFMo<#XJGPGXbzk!?&pH+J!r095 zQ;_Ba+IjSxIOe>vK}&T<^*^_AW^o4s`<;H4}y}&pH|M-(Ezuj#q(rJ9J!;$uB?7vN|@dYJD zMl7pnK|%VWN+h3!UQVg2;@0wY6rzE9 zIi|iGrE-}7ii9#X3>n@8vjR%Yn3$Pq20qMb=@3tlhNPfXsH8#vL6?xRwhQ3_K5Hm4 z97LEMt;b?Ta9rDF z&GaE@I0eu7RpzlEF+B;%KC(3ti6oy8d$bH0KIOX>Q3FLnttF+_yu#daq&^Lm$&~jE ztmX`#G!@(go-NJiwzR(91%5%tJvg%SdCD&G_}JL;c!o*l&DXInQ|hiUo6 zmdK@%X$kt3%0m@5A%_1Fo#3D#d5$%Y`}r0`u#x0<&ctc|u*o}Dcr8&WhCl61*>wt? zqrZ3+@;B!tNdMu=sX==wdigrU140^v{ac*XP7Fib0380c!efd?%s3A5I?|HfiRsgM z#1iwu;7scwi3F}tOzOfHgLYi`Tdo}`Z6`;@mzOh~X;CnoGw#M6p0G+=(`3l&9n~eB z1C=`vwTX8I(Uwvb!`TGz2Gq<>JpZnfCpI-l>jZiRPx4jyn3V>ugk6()Fx(adl$<96 z-cFuf$pv~bc=xs<<4|v&Egz08y)R*F(&Ut^twblyC;!8vzZ4hSeIjI9Q0~zAO5i%qwiv)8aX)s?b66psq_?wwxZQx+W9EmAvVdj|` z!ZG6-Mwm%VOF&-XIPJ8PrzV22lX~79XMt%A8;YyViDtpjVYuz6%z!_JV$5*dW=~2Ad0~;i@bvcqZmAYk+(?@FdCmZXQx+(ThEpxtisv{6U;k647kb7pn0+?J;1bIf9Tr>>O^i?te@)O~jiWhbY=N$dgY2YoD8~V`; zjSdQu#Pr^B&!*ueqYgMX&Q*SjsJ|KW+pSR*g&{&M?$$}7mFKzCj$dyLtRQiA?W6RP zPosA{_7N%iHe$<==Sj>=k$5ogWB2V&y4j~-z3}RqIvVN^9d>UdB^XJGRUy0DNTdRz zVs{Q;p@4e?=7mq0ob85lC|yA6y_*SAl8aOayZOf|z--_2nx_zl1#E0S-m( zU_JVBU^l4#ny5JHi7{S+iZ@tSOXvksbi|d>u9!QdcHvGf~~`x z)LOMG>%tgo`#k(rU>jWklUKr(Mz?V-+q>Q|M_gQTWbM!sQbiw~e zWjB?~fo@T0d+P~_g+PO%<_{&Qg0yv*8R_(ofDvIP+xedzv&C`-g3)G+e`1OqL6at>cW;w6rMD5C?htzRNO$%2-s||~hi4yD|M*8v%L9so zwc*W8qL|V2eD4sPfGJ09QFe?yqztZtRzy8ga^wfV90V9BTb(35MtU+A=KU4idq4s_ zVyVK#yPa9;!c;5VK+i@eWlXkCoSZr|0=qqSiB`C=d|GTm!qABJ>5pCZFtvZUH2>i` z2m9qn2a8q&Ry>O>Inozqlc=)fqPc}Ec!s6r%SN#*YYI#zsRZ6-C#M!ID5`WwO)XvG zP_$p!J_>;eY}~TSf(kRC(>@?qdZElkQYVxcatQN76fVPL#oYiT)`?D$7!+Kpa50c$ zko5`|qv?Ei{pD@~KXL^K2zj^uRyPG9FL!ewB<@hS=&C}y>m?6K$;QXzAi_{De@IJ7 z9s*7oNkK|DDQSfBJ2(LyQ!_UCMMFXK-ok=$HRE3F5PUjr-J0keNLyfexUXjma5Jn(Y)&t1 zeqzE_PSa~VX@X^P9HedF)4aH}I8x4*=50$$O-$Q>SLDT|H5bbS_)56kh%??4y5rE5 zUVZ|fKttQNr$ieVmKxU9ELwDm6^a+b(hL~nGsl8CL73%#KXuX z63;A?c>+T4!Cr~CY80l9-cH11y>X$Hl z65#9sNi%u%3W^s%2eMhQd2xPMZ+h=ugU(@O4%!H|#NWGvh$t7$}<+8E@q$$BS%4KSEnFFn)^fGXFWecGt zej}%-AUy?dCn+U05os6E?SeZ%3LFr{?R0cYaL;u&ErCsK$vApMp>9@Uc{x%p?@J}y zBJm2e7U@@#X(zxjag)Q=@f$$hDxOb*Mccx3kPd(adv_<7R1{PumMlgFE52GG(|bSn zFF{$&lZZuzHQ2pUrVp#J5lyjXC8nk&W~FCjS`YC@Af}K!|v<{nY>t;Xo-dJ0%Ng zUxT#1Ef^Vkz`FpI;Na}6q7fWSrfr0Bz@Wnvg(HtW{qW=QnTd&6DQV*^D69#0FOm&W zzCqj`USNqV<1yD_`~-%5_=Bs3I#vy!g?*?Kmlotrp?C#9@$6fe8CB>PN??iwMZ^<> z=mn5|8+L9%%0vA}Ipi?@pT)A^tRql^^WDUNT_EkzCpKYWNPf(=%#2~k1)vLXWu8My zI}RGPk@__6aw=)e30yj=aI^{V3WouN?Z*3@DDb)!1%qpet40<2PT~|RatHXLUkx=l zmSjPY8hjba#~g~T1V@vMm5rDT+)Rq;SmKcGGdyW@q1N>@q=JeK zU}E4==9K}eOrz_#;5h03@YxYa_caA1yup#Ao}~?t0DyujiCE-wmMjg8i*oTtZETq0ml9qF$ z8%Ni({vP4lP8@(Kx)!7adf@2DA2_ThV>h0@TozD8QH5oWgj9ekaH`A>wfAsmI?_j6 zZ$Xk&04ek@qy|KxqOu<)?Js1iK#s{w1AJzl7@Lixzw(0!*6cSlg&TC(J^oH`xF^~F z!_K}8paD)y5|I?(0e&Xby?xTe3mQNJlUB&oRR9gx3JJNLG?hkf2;D@CP3p`kup1ZK z3+n(Hux}vjn%D<`0zQ?VL9F3vCB$X{Qbf=L+wR`NDQSI-E7=G;9Jz2x$5qPM_8Ky7 zGpUi=u!BC$;sy8ue*c>ULyVif-PnlIifr?QDR7eDrsO)r8_0g>0%sKgU7+kv!ymeg zH>o6AelM=$+Vs+6wmI5UV6b5g04NYiwkdn57r(KG#qaYktig|B4FO>;;1h%PfO8gq zj;J=EKiWVIr_^YJ2yn(9{@NB1kuu>5+Qq6UF?8F*x_C z*iSHm!3U#bwSFUco`)hy6sZOWqoW{+o+}~!7@WHbR_s`gef>D>zc^VN;uXW}EGR9v z8cmVlXOzyJTU=l*rCmYtSU`2jit7ShhDpwPl&f^tsaV)+)zc9cvnlBR@oq_WKbS~`dc5t?oS9{*r{*b{Gf!SAyz6Ag*AlbhQ!JLriOBF2_FpU0 zfXxCfXG@F91$xKhrvM#D9C`ZzCTO#t!u-(=qlrOVpE-Im@dg-Fd zGB`uiO#;pGt61%)CGK+H@mK8RtmM^5V&S;dXJNLaP#dfR&)FeNz*1RG&fzpuo?sAP zUn|2^xpoL*Hb+O7XLA$@eYzZsLyYp)1pH|-Cwg$A9VmfuA+Jv%X^EYb zM;Rg2cSe*EYq3mC&xDWx@TeWC@}nRvx7TDVX-&Lnz09*}5#RRE2qYn%Hk=}nKm`W^ z_O`*}=DVQ-WAg@?R$!{a{u^Y*s%j|U zZUx#l%|0<4SZfIOL*=1%kCo=(C@Z$|Ke`YJ`L4d&H1swgn z%rJ1fy(Qvh6HPQdBduVG1;P!a;AL~ujl5pQtDc8R0H2!rl`sdph~-~Oy=UqWO@M>! zOk&4LG)IG-K{xQ4iMpmiY01dtb;Jdwx$L2sm=)=piFZP_m0ZJoe1-lEQqSh;@*xXT zOOSFeN6&Viq;0WronD-83(gSlgPD+kZ%snwl>507wi@nlaTM(R^f-V^Hp&dlL2euO zFPGZ$Fy6mW=27+b6Y~o1LyEz%M(*wZA}EHVLF5S@wOu^oi%TmC?A*OWD!og%THZI> z;uDanKgs#z{~8RB_mF{>wnyZ^{0t6<_y^DT@r*h+2L!Jh>FGh?zlN*?X+N~F=P*J_ z-U+u2iuhw7Kn@Sdns)uvEkk@cqmL8uK?;!@SY@KXI2uSYm0Kfj*=T2OejW*dqotVDpL2^Jjif2Fznwho}4ycW-s-h5l;6kCKJt9*6m5&Q2(#U@n z_RE%g;G8LPXU}IimFj>#AaM>*(&u996uFia&n9H^o*Xc7K4gRx;O;5%V5d27?=jb5 zzzXSrS&ATCJ&zkOszJyCOhPKK_+$cz^`TRWq+s`XXIBiSAF096lkPbVVJW10mC+%@ zZ%vgu%?Fe2ID~+n5jEom=G}1!!NPO)hZ{mL^0pxaJKui@!NMcWGKV3wjo5NBVl1-) z$7IVj%(G-@be5`qgEEl>{~;}ya0k)KrinE4Q2HFlEv#b+7;}2SvxYywso~Z@L@jQ~ zmWNkS!_7mhWZG5hL5|5L-xf8B6kxt-3Y-{+A>H%+8s+15#2cYEDlp{49*}XTiVvxY zDTfq?k(F%X`QU8&48(4+>17MNod<6l);cy1n8#LI^NwV+0J(8YIW(tu!Iqd}g^Js8 z_|tN2)ef%1zS!0d9ldpqtqeu%i+t6o;4boOcMz-#GN$H<$%q94q6X!i#2QH{R#s75LW|L)!!xb|rvz85!>OAG##T=tO`J>=O*)X|_^?I*26 zQYwvf6`72M>yK1i|xyDn!PD=T4A=Ne}ZrF>7ZvuI* zTV!rMykxie@e2prb_X&fot*otzl(=FBiF^;p%g z!_%T6RpI93#B3x6+z&~0fOtvBvVmo1z}NER`YJf%CLMuONe-ih-9E+q$c__Qgg7GP z2EZSs2uwh>*q3ktkwgCr7aS6Z#Qso3Pf z3gu8R&0rhuYGV`}X}}ZvxU`H1-x}W1fCUafB1gYZCb6B55Q{9IuK2Y9w|}4p3vCDjp4zMx9I$=rM#Uz>Xx>u8Olm<3Sli zY!lLsWBMy&s*3@Zq`DX|NE#>~#{rro#)2R%*|X1xBFcRE;B^s|^bfSwo) zMXJltaQF_YG2+b$iK$2ms-J2YhV6etrxO-LtNeQlE?C1l>z01+R_`wGlRkv?dyJ*FBS^|gSUq( zyj>RLRu+PyF@=yP6M340G=mU0o92nBrEu9`PMl;7L6T4cQD-3iU>wsc*G(LPU}wLB z?1n+XDZ;o-E+m;P$PhvD%yFB{8Og+JHD@Om!37zHait(EJ`)g!tn4f>NOMb&aRg}_ zzuzl&Vn)KPk8?r!f~Ck5i4XdE_&8OTFJ6j_+rvnD3EY}SK^Y@6npARLkUtzU$I$z- zCHYHH;8r5su|(Y_6)+#-2A8lQpr9?26p zUdLxZhdh&TETiy%l?t>{=awN!GDk<90#(eG%^VrHjYIMYC?VWVC6%L+0M-eq(jdni zw;4v|Ia5Md80=co@s`0#jmVe*uf7NrO2IZp*0V#bP-2g9Zg&CJaXIRw2v$~sDWTd# zPwYn?l0u9sFX#|>NY$6t(-tSn9mEVJqN#@SBwl7gScg%?1U81+QZO_8nsNsd!|wqr z%ZGwVcL#H0PZ$OXaw(V^UTTB<@!L8@peTTWV^ua$;~_9IcuPr)r^eM}KVu8zbiGdy ze#M~h9x;GZo(@MudaxoyxQ8SY17yx3e@6`Oi)@9^^FjCrgF+WdPMx?FsHCS(6z@zS zsEq_n1l>Y{l^_;oKm-o+Py`uxyFln>78J);l4Gf9C~7z^@lZtik6@lhYOn$3WQ#Q- zzJ@5K+}RL<7|F359ECsgPz;og2LA$LDwiRzG58M;g(ou>YdsZyGsbcHTo3x4XzPD9 zA^|l|N0+F14n`IyfQ@j6gC+Zj5~PBJvho8eN#2ptoiJ5?Z^i+8J zQiY$(wPOZ^BC#YN!GRLp~Zbx>=JL3IlLC>2u~l zC<`>M&HQ%-Nc7DDGiD16B|{dxdM>Ff$Wa?>9m{u*&qn&WJA4#6r$P`Bwg`LsDEx-a<0leK zN-=4iI>|6PFk<=zWC;){?i+bX_AJ4rKAJ;(cVmmcBEY4Q%M5%SuYy$fJxmDg(1_uY;Unr% zU=uz}3OD2P{)%wZ8(d-aUMMwUcxG4xFT?OASPM^QAE9FugujV10~BG*eym>XGJt8t zZw4p^FmKT(;Q@$rm>Hl5WZG~ZZx4@+Su&YKJUpBy&p z;Hna@ob14PJE{GLU>xLJ)6pUAr4DHo0)0mI+yImaV2|K%cpPUzIw7Z2c_iF+d<#K4 zw#J=E_{0;=GufEay;B(Skl2?2-#YImOCVY&uQ(c<7l_cIVgC@qBIP93LuT6(a!sza zZ!m2;ci0TWO9Tq~R*<_JuX~hSZ7+BH)Jd(UK*eC|mqJfQjjboOx(OP73p9258aObq z(il{=77}e+6+ZYBd@F9F5{2Bsuj2MXg-J!l1Y+?3l(tH8gqH^7~c z54KOY`w(uriP57kC~3p!TS-;oaByl!Y!5xt97ZOztPs57;hddT((N{_MaB_nz~8br zl0;8ziNnSDv}FHXTt-5DY*EUR(cHwU#t^Y^d>w?3{?R^%B+*9S_M;yfBbNq9(P|Dt2ugJdyc8SsI9%I zYrd%e1;@TMRa<3+K$jsjrXs;Q2l`7j95{KD zdVFa~MNxi1xivRGA8;jF##)wJQL&`7Jm0#csIrh88Dzps4OV#TWC6HAJOzCc<&=a{ zz_$YNt3Dns3BKcL8VxRao_;`(L=_d6&Mhh#6@X01G}jjRvCdw=)*O@xO2K|#8BBtp zr?7c|mq}opfE&It1XQIm(7%c4SrD~PzDsCYLHhD+L1o^M1*Mhw0mv|su_Py^rf%Z1 z>BF-DNRq~ls}%fB+ouaN;Ff;6P(I22I@U&{&SWz9Zf_)~#zP^J#==bIf?hldXj=G4 zq{!l5+p4FpY)vL6#AC<2v2N{d9fn5}B^){zkWUn=)9j)WXWhTo9(bu+`3 z<_KP9u)DzB54*n?_PlV=J_c9SO@ogEycbp|WZNP3QV4nR?}xp1^iw$=*8F*X%Gx@a$sDL3$TF@`JX4?Ngf3uu+Hx9 znB%QzSA@jP&cJ2m@WrGJ%i~6x6mF<6zH;eiE?mV`2|@@e2u_mS5yVwgE(O12WBc9Z zaUSqR<3=YZ!Ps$_S>^gq^UHC}jx{n7c3l-0G*%u&1V0u&DpXX76a%;i-hd6{)`nLw zgnU>MC()ORXk3Zy0Ux|7RZmrhLM#o0i>JpXY$UQI8O)zFo4NX`AvAw-8Y!`XmH;q~ zLguiUAsxl&0;Y=OGkEKo;tGz@&>1q$Vgrw}$^lfZvKiO@@i1uV@5PI)M28We%}6L5iH zo4N*24JZvWDxJZPG$hUBhB|1L<7lRq=H}Pn@K4n0D)lo@bW}2%pNTxKt|s5HZc=I9 zBCvA>T%Kxm}SdCTteOrO)uckW2|>YBi@9;aIQsU z-CB11cYHv^TJAnRGd(pmA&vK{3MPUnT}N}`Q`0Spyf;>m2X=BjF>NpGI2IwT;#Uz_ zvEa{4vJOK!v5i|gE$c`sg!wvgjJZ1_uE$whNd|zz5?g}V5}%n?$EUj3Q^`W2sS(KC zl~2u}l>xgoOZk)}ni7G$Wwr$K?5vcmRNxz$2@F5w9EQB*xMNM67o))NUaF7U-Hk75 zp>>BMUnQPZ6X(OYJk#!;!m&Pnk+dj6m*MJ|USVj6^D( zjYtbp=T zO?u*F5U^jmV~mB+c@7OzWj#@7vb~TP&|ajSy8Tgt#+dy?IRJfa!~pk&gU;=5B={P{ zGYRB9s~}gTuuXWdl!#lvP&e#nKwQ1BlSLR z$Q+VnZ}NOcz>9YK2?cmH0r+ht{J!PLulfKtDGrsL+ejCX>p{YQ6_uGo98aplL}na; z5Xljq>$kZQZbwN83WLzeZRfL(aoMiNNj5Qu9`7(*RB=7=r!0wCwh(RgySxB!(YOip z{O|-}597Ud4ma>)F5i-M)F}ai!Y@b?yqHh$uaboE%%^y)OM;pC z3>Uj3gjNkWO-hpOG5Np;fFk7k59GL+eE(rJ|MiCe290~4%q%apbcLvVb1e~JB_lD(M!!DF40y=Q;Lje+!QsLyYl zJK&c4-#dI`$4HR=ECW;t2tdD`z=w7s^|y>Yeuc*ALp;E_ekjRz1SQeex+c`RCf2$p zHM@>KTXixz2<48LxBOAH!fYNAEPB)tx8&98Ws>3lwSMF~wC2$W-<7Xunkp1m8-yJd z)|V{>eQvqqK6I|{}fB6eBUcN(%M~%37@6z)hRG+LuY*WRi?aVTR{^jSEKc2hE z`fMb8(|T!#Rd(UiisKc^YJcX!E`~*w1tq2IkfO3ISGhSiZ*F--*sxLQ#R~?HNl43| zvuLR~O;m0k?tivo$2TVjoXMX4b2na9yYA!!0F~!;Iw_8L7X{yi0Z(9A` ztijG>mfd-rlVsVH6#b8LV8V%LQ&fcIYS1Q)@ZB+ozxdAi*3DZ7W*RfAhL3*Z!h_O3 z&cFZH$b){Lj(ikz(mdO5cx1s34Zmy+58CE@#bln<`1NWO{aZuSsNWa1c)jrE_ut(_ zm6twU-M+16SIodTr8N!-oDl0;0XWx?xdoM#%c`deJ|8G#S=1EJ(bL=5aOS!pr@DnP zCf1x4C`+~+6b9xORJ7hK_KT{@$-TBUvOI1~!|9JFG6^zE=gX>j5br9u%zUL#NIn}I z=KRaTTcQ*$>*9Eo;ec};Bn@y%<{)EikVOQeDGrU z%j<*gE?%Y3ebbXulJIl&h%t&`+jg}69u;!wm(3>%HJ@#*`SwoU@9S30Q+{+Qc23p8 zs5bG>j}ApWzTo{=*_~NS%9cN_=qY>ay`N&joGKSSZiv0+C5!qop;+}(S?$#wF7dhJ z^;NsA)k9vdzxAWaWl~Jj$5%BjUS3&imp#r7c=hS>A77s(XxT43TmJW?m;P8f^-;`N zlS|a6=)}lJzo75Bf(H8^8SlBgth9c>_%*dZ-mI+Jx98p`zh?et$UB;!zIrab)iCbY z-D}@FvU%ic;og^nJJRn6B`X^um&LMG-x*%~ZSC7m({3(W^v++Q5lcFed*-O$FQwMK z{?)~}QRkJfzdWhE-YMeKBib|H)>q!&_NJj@+P-k}r)c z(f+o&2CuFeFktgBQB|+_$h6^6F=u}~VDx(bpNxtu=|cQGv+McLgSw7!YX>A{$r?vR zy!Y_(fQ&(dw)aGSvuxScMX8^TUh%Q_*!m?=Ww&Q^vK#CEZn75nwe8Ic{pij8Gr#*@ zST$_ayDN(g+gGFptvan}7=Po@_3>-cRBe95@Bi)X;y-phdi$wY0t1R; z`lKzdXii0bb*|vzH$>WuMJ27JITcNU$`(UFL0LoN{x+xFnp;A#MB%0kEcP3{`%C8Y zAz!}R7;|T1Vn*Nx&mSINHMjHfp@*A)N{Sj_TDA4!q)onUd*^tktV>*WTAlRkgpI>p zYyXNF@YKjdQ$P8*M^NNb%A8-j<&G$F?UqYu&gJ@zGg9Z=OgX-1rNPZF|5)|ru36>7 zj$hst=B6L8$@!=1fAWXmFROcguik&GZdQ-*!&A*;+Mao42NSU@=dIU5^|w#OR?SKk zJ^R(2y}NvaoEl4=#rHotac@p_x|8tZghw%c9nPEH?EFx?xn8lv^~|ZThqv6~c0XR| zdSZ>s^@Yzy+}M!#_DA1euNDl_Gycj`PDlK_qdZlEo8yJs8yUa)zNjPfx$L z_U+kc^MCni@uUCK)}4n#-Nkg-g%rA5BUNJT9AB#U$>M9%IcqA8ls*y+nYqM-q?AqR zPX%5UQ*!^lax-n?Q}yeFs$hMm*2cx9xTQtgIgi4g^ze3dO*9Gl>^?^)?5NEt5zl0l zEAGQl)YsD(|F`&j(0192`!}}jAr=*1o<_Tye;1Y@>v+f~G&g@#-@w%CSU?E3sC0;^ zq~}LB;>D7LmIQM7nNvgP7(7z+5_V4L-CF__qRiW&)Q69V~(B9j%sr?i&f?nx}<*Rs#WIgW2{aIuD4~3#*DPJ${dEBdUH1M@Bd8KZLG|NoA{qu`t zLrbc$N(L-PuYl9J_qvAg1V8$EUTmDi@{?O^G3M6{xvd|4Z%^o@c(N~!L?!&Q{Q4~q zVY1impw#P?$!;4Y^xQ}>2}&nzg3wes%zU(L1)o!OJZ)WWHu?8Rw=#)|?sX+gx(6)9 z2+03tlwV!4D(jSL1h#F*#&Mp6(sPx{v-l`~^17j+dHFpu-BxnuRYXj&yh4Lgd&0U4 zOW7$URdaDvZ>p7JW{f=Bba{StvxLtJ*`CL)@_77C-!$HWhNQYEaBr~KP+nMmrfp`e zkQ2j=rim%+4I>x#|FzR_?Z&D=g)1Aw_ZzN?3k{rgTe>kqN&4TL<}2em>)J5U0|Pmb$z1xSUm@ayDid)Z;-{#(X z%S*JZQYJR=PX4OmWD*RgWtY{aFH3TaB8-YSZVm=I)FOO)gN%8WlzudQ7m-Soc$-&u z%`%Ug<2)AwUh5I+R!Nw2sKBv|jt=Ji!{5Gsbsah%5a<)DyY*7=q%9TmE?K7g(W?xt z_AZNaYWjRU$IhfMdKo!D=(-F-xcX z^=K~6%=krpST0owqpuj&7M=3Kd~QF-EFdH8K#Jeil#`uUDXN#gzsHqt{TZ{ymG7cr zQf}@_t(GO+H~VyAta6qdVQX;a^d$D&?_wqW7l@Aga6_vf!yH`^D$$jYlWGOp4f$MU^D)3}X6J z_io=_Hktczl&R(zR&4X@@QRLxmX@K>bz;-Ut`r?dlNg!AhSO9@`FZY@0FLx$>7hyY zQ)Sh0$qSl#TiZC?{3-0jhdjzWqbY|KplN4$HqLU)h8iYslf8au8EGAm}J59qKcLBYif$9F;t=g`Eb?w zh_zT2Gv>MQa`h)e^i?9ve`z%&EQD>s4Up)-kQf9>oCHxy8c)JvC<=1wWIBy%sj6YT zXtlhI?2^Swnh(vK6n|NhIuZ^%eJd#5|5Tlos2Q3tWyoPY(@ISawzgN*zH@$Rx4oxM zPe$-z`y0!?W=*l}r_;@2`YNx0?jK4#Vbv3X|^P8Sk11| ze4qHxpsF$J>!(5q33;Wi1Qde}<*leQ6n|Djt9-whj9lE#w6{#ri)_q~~W!2Q+ z?g6_RqsFSh;dbtM${ESNpdnWMRh}>PLyz!*``>vrtHX2Uqe&O z4PrL+k?#Hvir1s_E}bdfSVX(_>O%3sqP#+t?BbYWqoRF<#f8O@2QR#bGj7?cQaTR+Y;E%|u+ zX^+s~)!#MgK(#iJZbvs!?-s5M3_L=v)+QK>1Z#znv-j`yH!?p9g~JSUKS`I*mA`2C z7gH{vyt<1uGF^G_MonxtRB)mlVT4l;1NQuC8< z$US?H37<8X#*c9~U6U`L6__~xj-0C=D4sWtd-NLRN8)jwDiQhXIwVv43?li#kZ7+E6alAhK{@fUG6hB82MTv>M z(f`~oSkGF|xff5E7O6{bwotR{jovz7HTQJW@w>I;SU&HC!}bVmY8>VsKl;UILAZ}W zv{uUxeiTFD*Y4O@*``~w@!@fF8g|?*>Mw(b8o#D2l46>9?>^g_Yg5~CGafsI^gH-8 z_4P|E!||4?c=}=dc!P1Hg&(cX!SPAkycxAX%iyIAXMW7Ul7|1}T|28#yE`@~dfLsE zM*R7ZEm#p&Mi)rLHt}*Q2~#vnBbhhMS#L|m@-$aln~!pbJ~Ax3sb{%oBE9Lkc_M-N zj`U`YH*dLHTo%q5oX497klZKF=$@7k>^>VJxv`LV-5 z8~e@8d@{X`ut21>{-RMuuN>7?rr0b?T>Ok%zJ25~M@{#4!={_Oi8F+mHf62;E!Uje zq`&?XwGZzz-5GG4ib_bfwC1J3S^oDn*E~DU+l+U~Pnh4L)l8o3S7#CTf6j?5|6#4( zV)s!q%v-5U0goMXH)QMr&ori{l3DIY#L|D zuk}V<>3`$*Q6e0ug4`*>2~nuJK&H`p9#W-<-*Zt}3pCObuZWafnQ5-f^NkqcT=TOJ z^|SbgVYp5;o>>r@jdtlcdVhlvPyK{pcI6?AKcAsU+B-rEF76 zWNlGtSWarOdRp#d6v(2U{1T&jQRi`8z~y77AMZ$*?scL|bdH;h{E*;VR=n>F`uNJU zdvC*{pBh2V&3^3GEcw>cF3$R{N=NeV>y(gRW||#&ul2BFB{k1pSDqkF_{+b5&ywcQ z+-s{ZzE34oX1x>YZ_@m|`2Y9X|1AC<+`K=lza*YO#7SVJq)AvR1+@t2WJ?7lwSGDI zs3sZOl8u#jR-5O1leND1>|C^pbWsg4RkQ1|bq!g5ZP#0y0ol~e-K%Zq73BAHA9pA= z)_Z<6JSp5hRNz-0jnsUCXQp zv45l6TyaxD>P1@KzQkgaBHXo0sl_fu=L%k3F6I<#7O4~zUoEcS+}L-kSa`#_^wNW) zQ#Za;aMv#_8{+2Sl_%d2qBN#oyt+>$uD%|KR&y;MS}DX%C`4B$oI;sQde6`q6=!lbZ$=BL*{$ z4|j7pm{`^2F;A=~C1z096Gxa89m~9v{HRrq!fRGAx)|DP#*Z%JXMe&9<%_ z++8!rA{bEmzrDJ+Ih!wi(WwjbjI)5*EX%hPEvnl?q_^Q03@uprhdi_+lEPaamzdzr z^%3$%8AdZ6ssXP}-VDZxC($fKlW4!juGUs+YOS}?YuzvzIH#;6Vhc81ZK%t{b;iD7 z+I3hR8(~Ihlf-U@{cpIfy=QC6h{Lk?&SR!Lm^!D9vH}Ma38{V(P5!E` zm)Czl|0rKAOI()}m1gst8x&B-=MKGjT_4C6=m}qO*@C5WEV9v1QcyBKCZ`uO#f%(e z$+U69#42xd&Zl%XTF)|;&U9{y@S|Sjo(Vy3{~vrmHlXUwzl~O>MATmVXKvLdZ%GSn z;=jS)|HK9sZXK8vQyg&`4a0nkPvj$0m@8CO6y!EB$#Zvz7kNL=$xe@DlbW8A!~*l#^)KGrAG!Hp zfu!p59Bjfs48)6-4jb&Vk`HQA(ckF`T9~=+4jh#i)!Yme2pKC>ee=`^}bo0 z>B%xz>#grd`vxpcUEW}4p@Adu)_vY2WA7}KIW?qzPzpOdwCRz0_p|d5Gp}K=TH;-O z=+rk0SGxsP|BI&3`Ac+V?7ey3RGCW{TzM*iTB1R|A0;50MX?nJc))3R`0em;)|9I6 zSaW$tW?g1o1IAMzdYol!Ox-kluYsd+XHFUI@&JDC(Nk_Yk7PzO*t_ZY z)58q5xi&>@!RwLki{+9r7Dw&2T{*K*POd%1uW`fnI}JX#T-!#ndEIDZsfHDEYuI$5 zjCR+_UC{ltDxymq)5HrJ6 z--kaM<2w`=LB6wk3RN;i?N^G;6ZeR*gIc_gqKGX1osLiM1HajA2@GSXM;boMX=H{B zPo%C*AG4k6GOX)hRB`WMUn%1mSPYIJDJ>y|r~FA7G<6LU{ZGnR{a?%|kUe`F zpH8$>XhQjr|JGbf+1fRlI>6lATN!xA)XZ$-%!@tjHu_Thn3Z`6xh%a1`;}`^Df5OK z5h#rY1?l_En*A0u>a84&(;AeB8~2>4b(k}6(=7JkoJ!eKB7qvmm9`}6cRUaaJ`F{D zUg~VqIm^u-mU$-CxX;GaXN0Lctl=}P5irbnOWLyQM;F~sQg*JME|zKL4pT`I2ARzRpWSp@aA*blmzAIymbUmH#(& z1icwydj77{(_1DhKCK01C=lr)`l5^FT3>P(C$skx=ep&_~ z3qX4Sw*a^mz-<6-2hagPM*w#KxD&u#06GD<8^FH-{0Bg10QUg67r=c0x&XKzzykof z0(cNWHvruM^Z?KkKra9f0eBd|BLI2>=mX$U0DS@U1MnDt{s0C57zkhxfWZKU02m73 zaR5&McoIN1fMEcJ19%F+2mm7ii~^7YAQwO$fYAWP0LTaMG=KoWSODVyj0Z3Qz(fGg z0C*O_Bmk2E6abh4;5h)#1DFcn1pw0kOb0Lnz>5H00x%Q6EC4S9m=A-;B5f!0C*R`N&xQxSOwsH z03QJOFM!nm)&N)wU>$(<05$;F2w)R{%>cFl*b1N!z%~He0elEx2Y`C~1Ujq0Fz^H<&~K_kMMMcv zMpO`0L=9Prs3UZQfoLF_h!&!a=pf4wT|^IAj;ugdBCC+qh(2O~7$R#BBg7b4i>yP| zBPNI`Vuox$HX`Q8Cd2}ryVC$bB1 zLUtp6BmW@I$R1=bvJY`V_9F)nSL7h#hPWdh2%7nz7jg(Wj2uC{5g+6z;*0np#}I!c z00~5bkYFSP2}O=0Cy! zvq%z>j0lhvSTZ.G bEscMode clc rts *-------------------------------------- -* \e[xx;yyR +* \e[xxx;yyyR *-------------------------------------- .3 stz TmpByte diff --git a/BIN/MEMDUMP.S.txt b/BIN/MEMDUMP.S.txt index e5d299d5..d4f3634c 100644 --- a/BIN/MEMDUMP.S.txt +++ b/BIN/MEMDUMP.S.txt @@ -9,6 +9,8 @@ NEW .INB inc/a2osx.i .INB inc/kernel.i .INB inc/io.i +*-------------------------------------- +PAGE.LEN .EQ 23 *-------------------------------------- .DUMMY .OR ZPBIN @@ -55,6 +57,7 @@ L.MSG1.HEX .DA MSG1.HEX L.MSG1X .DA MSG1X L.MSG2 .DA MSG2 L.MSG3 .DA MSG3 +L.MSG.CRLF .DA MSG.CRLF .DA 0 *-------------------------------------- CS.INIT clc @@ -71,7 +74,7 @@ CS.RUN ldx #ZPCodeLen-1 >SYSCALL GetMemStat jsr CS.RUN.INIT - +*-------------------------------------- CS.RUN.LOOP inc MEM.COUNT skip slot 0 jsr CS.RUN.CheckStop @@ -95,9 +98,13 @@ CS.RUN.LOOP inc MEM.COUNT skip slot 0 bne CS.RUN.LOOP jsr CS.RUN.SUMMARY + + jsr CS.RUN.MSTAT + + jsr CS.RUN.PrintCRLF jsr CS.RUN.INIT - +*-------------------------------------- CS.RUN.LOOPX inc MEM.COUNT skip slot 0 jsr CS.RUN.CheckStop @@ -124,7 +131,6 @@ CS.RUN.LOOPX inc MEM.COUNT skip slot 0 jsr CS.RUN.SUMMARY - jsr CS.RUN.MSTAT jsr CS.RUN.XSTAT lda #0 @@ -142,13 +148,17 @@ CS.RUN.INIT >LDYAI Mem.Table+S.MEM skip slot 0 stz USED.COUNT rts *-------------------------------------- -CS.RUN.SUMMARY >PUSHW L.MSG2 +CS.RUN.SUMMARY jsr CS.RUN.PrintCRLF + + >PUSHW L.MSG2 >PUSHB USED.COUNT >PUSHB MEM.COUNT >PUSHBI 2 jmp CS.RUN.PrintF *-------------------------------------- -CS.RUN.MSTAT >PUSHW L.MSG3 +CS.RUN.MSTAT jsr CS.RUN.PrintCRLF + + >PUSHW L.MSG3 >PUSHW.G MemStat+S.MSTAT.MH >PUSHW.G MemStat+S.MSTAT.MF >PUSHW.G MemStat+S.MSTAT.ML @@ -163,7 +173,9 @@ CS.RUN.MSTAT >PUSHW L.MSG3 >PUSHBI 8 jmp CS.RUN.PrintF *-------------------------------------- -CS.RUN.XSTAT >PUSHW L.MSG3 +CS.RUN.XSTAT jsr CS.RUN.PrintCRLF + + >PUSHW L.MSG3 >PUSHW.G MemStat+S.MSTAT.XH >PUSHW.G MemStat+S.MSTAT.XF >PUSHW.G MemStat+S.MSTAT.XL @@ -234,6 +246,7 @@ CS.RUN.PRINTMEM >PUSHW L.MSG1 jsr CS.RUN.PrintINV .12 >PUSHBI 9 + >SYSCALL PrintF lda (ZPPTR1) @@ -270,8 +283,7 @@ CS.RUN.PRINTMEM.DATA >PUSHW ZPPTR2 String >PUSHBI 3 - jsr CS.RUN.PrintF - rts + jmp CS.RUN.PrintF .2 >PUSHW L.MSG1.HEX @@ -284,8 +296,7 @@ CS.RUN.PRINTMEM.DATA >PUSHBI 16 - jsr CS.RUN.PrintF - rts + jmp CS.RUN.PrintF CS.RUN.PRINTMEM.BIN >PUSHW L.MSG1.BIN @@ -295,8 +306,7 @@ CS.RUN.PRINTMEM.BIN >SYSCALL GetMemPtr >PUSHYA >PUSHBI 2 - jsr CS.RUN.PrintF - rts + jmp CS.RUN.PrintF *-------------------------------------- CS.RUN.PRINTMEMX >PUSHW L.MSG1X @@ -358,8 +368,8 @@ CS.RUN.PRINTMEMX jsr CS.RUN.PrintINV .12 >PUSHBI 9 - jsr CS.RUN.PrintF - rts + + jmp CS.RUN.PrintF *-------------------------------------- CS.RUN.CHECKPS ldx #0 @@ -419,16 +429,21 @@ CS.RUN.PrintINV >PUSHW L.MSG1.INV >SYSCALL PrintF rts *-------------------------------------- +CS.RUN.PrintCRLF + >PUSHW L.MSG.CRLF + >PUSHBI 0 + CS.RUN.PrintF >SYSCALL PrintF bcs .9 inc LINE.COUNT lda LINE.COUNT - cmp #22 + cmp #PAGE.LEN bcc .8 dec bSTOP stz LINE.COUNT + clc .8 .9 rts *-------------------------------------- @@ -448,15 +463,16 @@ ZPCodeLen .EQ *-ZPCode MSG0 .AZ "hMem Flags PID REF PTR LEN BINPATH/DATA\r\n" MSG1.INV .AZ "\e[7m" MSG1 .AZ "$%h %s %3d %3d $%H %5D " -MSG1.BIN .AZ "{%s}\e[0m\r\n" +MSG1.BIN .AZ "\e[7m%s\e[0m\r\n" MSG1.STR .AZ "[%03d:%s]\e[0m\r\n" MSG1.HEX .AZ "?HEX:%h%h.%h%h.%h%h.%h%h.%h%h.%h%h.%h%h.%h%h\e[0m\r\n" MSG1X .AZ "$%h %s %3d %3d $%H %5D\e[0m\r\n" MSG2 .AZ "Allocated hMem:%d, Total:%d\r\n" -MSG3 .AS "\r\nHigh Memory: $%H\r\n" - .AS "Free ULimit: $%H\r\n" - .AS "Low Memory: $%H\r\n" - .AZ "Free Memory: %D Bytes.\r\n\r\n" +MSG3 .AS "High Memory: $%H, " + .AS "Free ULimit: $%H, " + .AS "Low : $%H, " + .AS "Free : %5D Bytes." +MSG.CRLF .AZ "\r\n" MSG.FLAGS .AS "UZXAfcds" MSG.FLAGSX .AS "UZXAidep" *-------------------------------------- diff --git a/BIN/PS.S.txt b/BIN/PS.S.txt index e263b098..586f6c20 100644 --- a/BIN/PS.S.txt +++ b/BIN/PS.S.txt @@ -86,9 +86,8 @@ CS.RUN lda #1 sec rts -.10 >PUSHW L.MSG0 - >PUSHBI 0 - >SYSCALL PrintF +.10 >LDYA L.MSG0 + >SYSCALL Puts ldx Index .1 lda PS.Table.hPS,x @@ -213,9 +212,8 @@ CS.RUN.PrintArgs inc ZPArgV+1 bra .1 -.8 >PUSHW L.MSG3 - >PUSHBI 0 - >SYSCALL PrintF +.8 >LDYA L.MSG3 + >SYSCALL Puts .9 rts *-------------------------------------- CS.DOEVENT sec @@ -225,10 +223,11 @@ CS.QUIT clc rts *-------------------------------------- CS.END -MSG0 .AS "\e[?7lhPS pPID PID cPID CPU\% Status Flags UID Cmd Line" -MSG3 .AZ "\r\n" +MSG0 .DA #C.ESC + .AZ "[?7lhPS pPID PID cPID CPU\% Status Flags UID Args" MSG1 .AZ "%3d %3d %3d %3d %3d\% %6s %s %3d" -MSG2 .AZ " %s" +MSG2 .AS " %s" +MSG3 .DA #0 MSG.FLAGS .AS "HS???XEN" MSG.INIT .AZ "Init" MSG.RUN .AZ "Run" diff --git a/BIN/TELNET.S.txt b/BIN/TELNET.S.txt index 84545a02..eb50bacc 100644 --- a/BIN/TELNET.S.txt +++ b/BIN/TELNET.S.txt @@ -51,7 +51,6 @@ L.MSG.IPKO .DA MSG.IPKO L.MSG.USAGE .DA MSG.USAGE L.MSG.UNKNOWN .DA MSG.UNKNOWN L.MSG.HOSTOK .DA MSG.HOSTOK -L.MSG.SKTKO .DA MSG.SKTKO L.MSG.SKTOK .DA MSG.SKTOK L.MSG.SKTERR .DA MSG.SKTERR L.MSG.IOERR .DA MSG.IOERR @@ -61,6 +60,7 @@ L.MSG.USER .DA MSG.USER CS.INIT >LDYA L.LIBTCPIP >SYSCALL LoadLib bcs .9 + sta hLIBTCPIP .9 rts @@ -80,8 +80,10 @@ CS.RUN.IPOK ldy #S.PS.ARGC lda (pPS),y cmp #1 bcc .9 + ldy #S.IPCFG.IP+3 ldx #3 + .1 lda (ZPIPCfgPtr),y sta SA.LOCAL+S.SOCKADDR.ADDR,x dey @@ -120,6 +122,7 @@ CS.RUN.IPOK ldy #S.PS.ARGC CS.RUN.HOSTOK lda #2 >SYSCALL ArgV bcs CS.RUN.PORTOK + >SYSCALL AToI >STYA SA.REMOTE+S.SOCKADDR.PORT @@ -144,19 +147,14 @@ CS.RUN.OPENSKT >PUSHBI S.SOCKET.T.STREAM >LIBCALL hLIBTCPIP,LIBTCPIP.Socket bcs .9 - sta hSocket +.1 sta hSocket >PUSHA >PUSHW L.SA.LOCAL >LIBCALL hLIBTCPIP,LIBTCPIP.Bind bcc .2 -.9 pha - >LDYA L.MSG.SKTKO - >SYSCALL PutS - pla - sec -.99 rts +.9 jmp CS.RUN.SKTERR .2 lda #TIMEOUT.MAX sta TimeOut @@ -177,78 +175,71 @@ CS.RUN.OPENSKT >PUSHBI S.SOCKET.T.STREAM lda #ERR.SKT.NOCONN bra .9 -.4 >PUSHW L.MSG.SKTOK - >PUSHBI 0 - >SYSCALL PrintF +.4 >LDYA L.MSG.SKTOK + >SYSCALL Puts >LDYAI BUFSIZE >SYSCALL GetMem - bcs .99 + bcc .5 - >STYA ZPBufPtr +.5 >STYA ZPBufPtr stx hBuf - +*-------------------------------------- CS.RUN.LOOP >SLEEP lda hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.EOF - bcs .98 + bcs CS.RUN.SKTERR tay bne .2 EOF, no char - >PUSHB hSocket - >PUSHW ZPBufPtr - >PUSHWI BUFSIZE + lda hSocket + jsr CS.RUN.PushRead >LIBCALL hLIBTCPIP,LIBTCPIP.Read -.98 bcs .99 + bcs CS.RUN.SKTERR >STYA ZPBufLen ldy #S.PS.hStdOut lda (pPS),y - >PUSHA - >PUSHW ZPBufPtr - - >PUSHW ZPBufLen + jsr CS.RUN.PushWrite >SYSCALL FWrite - bcs .11 + bcs CS.RUN.IOERR .2 ldy #S.PS.hStdIn lda (pPS),y >SYSCALL FEOF - bcs .11 CS.RUN.IOERR + bcs CS.RUN.IOERR tay bne CS.RUN.LOOP EOF = true, no char from STDIN ldy #S.PS.hStdIn lda (pPS),y - >PUSHA - >PUSHW ZPBufPtr - >PUSHWI BUFSIZE + jsr CS.RUN.PushRead >SYSCALL FRead -.11 bcc .3 + bcs CS.RUN.IOERR - bra CS.RUN.IOERR -.99 bra CS.RUN.SKTERR - -.3 >STYA ZPBufLen + >STYA ZPBufLen lda (ZPBufPtr) cmp #$14 Ctrl-T - beq CS.RUN.USER + beq CS.RUN.USERINT - >PUSHB hSocket - >PUSHW ZPBufPtr - >PUSHW ZPBufLen + lda hSocket + jsr CS.RUN.PushWrite >LIBCALL hLIBTCPIP,LIBTCPIP.Write -.9 bcs CS.RUN.SKTERR + bcc CS.RUN.LOOP +*-------------------------------------- +CS.RUN.SKTERR ldx #0 - jmp CS.RUN.LOOP + bra CS.RUN.ERR *-------------------------------------- -CS.RUN.SKTERR pha - >PUSHW L.MSG.SKTERR +CS.RUN.IOERR ldx #2 + +CS.RUN.ERR pha + >PUSHW L.MSG.SKTERR,x pla pha >PUSHA @@ -258,28 +249,31 @@ CS.RUN.SKTERR pha sec rts *-------------------------------------- -CS.RUN.IOERR pha - >PUSHW L.MSG.IOERR - pla - pha - >PUSHA - >PUSHBI 1 - >SYSCALL PrintF - pla - sec - rts -*-------------------------------------- -CS.RUN.USER >LDYA L.MSG.USER +CS.RUN.USERINT >LDYA L.MSG.USER >SYSCALL PutS lda #0 sec rts *-------------------------------------- +CS.RUN.PushRead >PUSHA + >PUSHW ZPBufPtr + >PUSHWI BUFSIZE + rts +*-------------------------------------- +CS.RUN.PushWrite + >PUSHA + >PUSHW ZPBufPtr + >PUSHW ZPBufLen + rts +*-------------------------------------- CS.DOEVENT lda (pEvent) bpl .9 is it a TIMER event? + lda TimeOut beq .9 + dec TimeOut + .9 sec do not discard TIMER event rts *-------------------------------------- @@ -308,8 +302,7 @@ MSG.IPKO .AZ "TCP/IP Not Loaded/Configured." MSG.USAGE .AZ "Usage : TELNET [port]" MSG.UNKNOWN .AZ "%s: Unknown host\r\n" MSG.HOSTOK .AZ "Connecting to %d.%d.%d.%d:%D (%s)..." -MSG.SKTKO .AZ "Failed to Open Socket." -MSG.SKTOK .AZ "Connected\r\n(Exit key is Ctrl-T)\r\n" +MSG.SKTOK .AZ "Connected\r\n(Exit key is Ctrl-T)" MSG.SKTERR .AZ "Socket Error : $%h\r\n" MSG.IOERR .AZ "I/O Error : $%h\r\n" MSG.USER .AZ "User interrupt." @@ -327,8 +320,7 @@ SA.REMOTE .DA #AF.INET S.SOCKADDR.AF .DUMMY .OR 0 DS.START -DS.END - .ED +DS.END .ED *-------------------------------------- MAN SAVE usr/src/bin/telnet.s diff --git a/BIN/TUITEST.S.txt b/BIN/TUITEST.S.txt index 8d8db43a..9aa090ae 100644 --- a/BIN/TUITEST.S.txt +++ b/BIN/TUITEST.S.txt @@ -12,6 +12,9 @@ NEW .DUMMY .OR ZPBIN ZS.START +ZPPtr1 .BS 2 +hScreen .BS 1 +hListBox .BS 1 ZS.END .ED *-------------------------------------- * File Header (16 Bytes) @@ -33,6 +36,8 @@ CS.START cld .DA CS.DOEVENT .DA CS.QUIT L.LIBTUI .DA LIBTUI +L.LBOX1 .DA LBOX1 +L.MSG.Screen .DA MSG.Screen .DA 0 *-------------------------------------- CS.INIT >LDYA L.LIBTUI @@ -44,16 +49,54 @@ CS.INIT >LDYA L.LIBTUI .9 clc rts *-------------------------------------- -CS.RUN +CS.RUN >LIBCALL hLIBTUI,LIBTUI.Open + bcs .9 - lda #E.SYN - sec - rts + sta hScreen + >SYSCALL GetMemPtr + >STYA ZPPtr1 + + >PUSHW L.MSG.Screen + + ldy #S.OBJ.X1 + +.1 lda (ZPPtr1),y + >PUSHA + iny + cpy #S.OBJ.Y2+1 + bne .1 + + >PUSHBI 6 + >SYSCALL printf + + >PUSHB hScreen + >PUSHW L.LBOX1 + >LIBCALL hLIBTUI,LIBTUI.LBOXNew + bcs .9 + + sta hListBox + +.2 >SYSCALL GetChar + bcs .9 + + cmp #3 + beq .9 + + >SYSCALL putchar + bcc .2 + + +.9 rts *-------------------------------------- CS.DOEVENT sec do not discard TIMER event rts *-------------------------------------- -CS.QUIT lda hLIBTUI +CS.QUIT lda hScreen + beq .1 + + >LIBCALL hLIBTUI,LIBTUI.Close + +.1 lda hLIBTUI beq .8 >SYSCALL UnloadLib @@ -66,7 +109,11 @@ CS.END LIBTUI .AZ "libtui" hLIBTUI .BS 1 *-------------------------------------- -LBOX1 .DA #10 X1 +MSG.Screen .AZ "Screen : X1=%d, Y1=%d, W=%d, H=%d,X2=%d, Y2=%d\r\n" +*-------------------------------------- +LBOX1 .DA #S.OBJ.T.LBOX T + .BS 3 + .DA #10 X1 .DA #4 Y1 .DA #20 W .DA #10 H diff --git a/DRV/SSC.DRV.S.txt b/DRV/SSC.DRV.S.txt index 50980c96..590d2d15 100644 --- a/DRV/SSC.DRV.S.txt +++ b/DRV/SSC.DRV.S.txt @@ -6,6 +6,7 @@ SSCIRQ .EQ 0 *-------------------------------------- .INB inc/macros.i .INB inc/a2osx.i + .INB inc/kernel.i .INB inc/mli.e.i .INB inc/com.i .INB inc/com.6551.i diff --git a/DRV/SSC.I.DRV.S.txt b/DRV/SSC.I.DRV.S.txt index fe320a3b..db126d2d 100644 --- a/DRV/SSC.I.DRV.S.txt +++ b/DRV/SSC.I.DRV.S.txt @@ -6,6 +6,7 @@ SSCIRQ .EQ 1 *-------------------------------------- .INB inc/macros.i .INB inc/a2osx.i + .INB inc/kernel.i .INB inc/mli.e.i .INB inc/com.i .INB inc/com.6551.i diff --git a/INC/LIBTUI.I.txt b/INC/LIBTUI.I.txt index 580897c5..6e36d1a2 100644 --- a/INC/LIBTUI.I.txt +++ b/INC/LIBTUI.I.txt @@ -1,8 +1,9 @@ NEW AUTO 3,1 *-------------------------------------- -LIBTUI.Init .EQ 4 +LIBTUI.Open .EQ 4 LIBTUI.Close .EQ 6 +LIBTUI.LBOXNew .EQ 8 *-------------------------------------- S.OBJ.T .EQ 0 S.OBJ.T.SCRN .EQ 0 @@ -12,6 +13,8 @@ S.OBJ.F .EQ 2 S.OBJ.F.bTITLE .EQ %10000000 S.OBJ.F.bMENU .EQ %01000000 S.OBJ.F.bSTATUS .EQ %00100000 +S.OBJ.F.bHBorder .EQ %00010000 +S.OBJ.F.bVBorder .EQ %00001000 S.OBJ.S .EQ 3 S.OBJ.S.bVISIBLE .EQ %10000000 S.OBJ.S.bACTIVE .EQ %01000000 @@ -25,7 +28,21 @@ S.OBJ.pTITLE .EQ 10 S.OBJ.pMENU .EQ 12 S.OBJ.pSTATUS .EQ 14 * -S.OBJ .EQ 16 +S.OBJ.InnerX .EQ 16 +S.OBJ.InnerY .EQ 17 +S.OBJ.InnerW .EQ 18 +S.OBJ.InnerH .EQ 19 +* +S.OBJ.Childs .EQ 32 +* +S.OBJ .EQ 48 +*-------------------------------------- +S.SCRN.bEscMode .EQ S.OBJ +S.SCRN.InBufPtr .EQ S.OBJ+1 +S.SCRN.InBuf .EQ S.OBJ+2 +S.SCRN.EndBuf .EQ S.OBJ+15 +* +S.SCRN .EQ S.OBJ+16 *-------------------------------------- S.LBOX.pL .EQ S.OBJ+0 S.LBOX.Idx .EQ S.OBJ+2 diff --git a/INC/NET.TELNET.I.txt b/INC/NET.TELNET.I.txt index ae516a73..362ed54b 100644 --- a/INC/NET.TELNET.I.txt +++ b/INC/NET.TELNET.I.txt @@ -1,6 +1,5 @@ NEW -PREFIX -AUTO 4,1 + AUTO 3,1 *-------------------------------------- * https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/+/jb-dev/sysroot/usr/include/arpa/telnet.h * https://web.maths.unsw.edu.au/~lafaye/CCM/internet/telnet.htm diff --git a/LIB/LIBTUI.S.txt b/LIB/LIBTUI.S.txt index 2a4f9c60..10a74f3f 100644 --- a/LIB/LIBTUI.S.txt +++ b/LIB/LIBTUI.S.txt @@ -7,14 +7,14 @@ NEW *-------------------------------------- .INB inc/macros.i .INB inc/a2osx.i - .INB inc/kernel.i + .INB inc/net.telnet.i .INB inc/libtui.i *-------------------------------------- .DUMMY .OR ZPLIB -hCtx .BS 1 +hScrn .BS 1 .BS 1 -ZPCtxPtr .BS 2 +ZPScrnPtr .BS 2 ZPObjPtr .BS 2 ZPPtr1 .BS 2 .ED @@ -35,39 +35,127 @@ CS.START cld *-------------------------------------- .1 .DA LIB.LOAD .DA LIB.UNLOAD - .DA Init - .DA Close + .DA LIB.Open + .DA LIB.Close + .DA LIB.LBOXNew *-------------------------------------- +L.SEQ.TERMCAP .DA SEQ.TERMCAP L.SEQ.INIT .DA SEQ.INIT +L.FMT.ESCCSI.R .DA FMT.ESCCSI.R .DA 0 *-------------------------------------- -LIB.LOAD clc - rts -*-------------------------------------- -LIB.UNLOAD clc - rts -*-------------------------------------- -Init >LDYAI 256 - >SYSCALL GetMem +LIB.LOAD lda LibCnt + bne .8 + + >LDYAI 256 + >SYSCALL2 GetMem bcs .9 + stx hLineBuf - txa -* clc + +.8 inc LibCnt + clc .9 rts *-------------------------------------- -Close clc +LIB.UNLOAD dec LibCnt + bne .8 + + lda hLineBuf + >SYSCALL2 FreeMem + +.8 clc rts *-------------------------------------- -LIBTUI.LBOXNew >PULLB hCtx - >SYSCALL GetMemPtr - >STYA ZPCtxPtr +LIB.Open >LDYAI S.SCRN + >SYSCALL2 GetMem + bcs .99 - >PULLW ZPPtr1 + >STYA ZPScrnPtr + txa + >PUSHA + + lda #0 + + ldy #S.SCRN-1 + +.10 sta (ZPScrnPtr),y + dey + bpl .10 + + jsr CheckCh.Reset + + >LDYA L.SEQ.TERMCAP + >SYSCALL2 puts + + lda #0 + >PUSHA + +.1 >SLEEP + + ldy #1 + lda (pStack),y + jsr GetScrn + + jsr CheckCh + bcs .97 + + beq .2 + + >SYSCALL2 PutChar + bcs .97 + +.2 ldy #S.OBJ.W + lda (ZPScrnPtr),y + bne .8 + + lda (pStack) + dec + sta (pStack) + bne .1 + + lda #80 + + ldy #S.OBJ.W + sta (ZPScrnPtr),y + + lda #24 + iny S.OBJ.H + sta (ZPScrnPtr),y + +.8 inc pStack + + >LDYA ZPScrnPtr + jsr LIB.SetObjX2Y2 + + >PULLA hScrn + clc + rts + +.97 inc pStack + inc pStack + +.98 pha + lda hScrn + >SYSCALL2 FreeMem + pla + sec + +.99 rts +*-------------------------------------- +LIB.Close >SYSCALL2 FreeMem + + clc + rts +*-------------------------------------- +LIB.LBOXNew >PULLW ZPPtr1 Params + + >PULLA hScrn + jsr GetScrn >LDYAI S.LBOX - >SYSCALL GetMem + >SYSCALL2 GetMem bcs .9 >STYA ZPObjPtr @@ -76,36 +164,43 @@ LIBTUI.LBOXNew >PULLB hCtx sta (ZPObjPtr) ldy #S.OBJ.P - lda hCtx + lda hScrn sta (ZPObjPtr),y iny #S.OBJ.F + lda #S.OBJ.F.bHBorder+S.OBJ.F.bVBorder + sta (ZPObjPtr),y + + ldy #S.OBJ.X1 .1 lda (ZPPtr1),y sta (ZPObjPtr),y - + iny cpy #S.OBJ.H+1 bne .1 + + .8 txa clc .9 rts *-------------------------------------- -LIBTUI.LBOXLoad >SYSCALL GetMemPtr +LIB.LBOXSetData >SYSCALL2 GetMemPtr >STYA ZPObjPtr rts *-------------------------------------- -LIBTUI.LBOXFocus +LIB.LBOXFocus *-------------------------------------- -LIBTUI.LBOXRun +LIB.LBOXRun *-------------------------------------- -LIBTUI.LBOXClose +LIB.LBOXClose clc rts *-------------------------------------- -LIBGUI.SetupX2Y2 +LIB.SetObjX2Y2 >STYA ZPObjPtr + ldy #S.OBJ.X1 jsr .1 @@ -122,11 +217,207 @@ LIBGUI.SetupX2Y2 sta (ZPObjPtr),y rts *-------------------------------------- -LIBTUI.DrawFrame +LIB.DrawFrame + clc + rts +*-------------------------------------- +CheckCh ldy #S.PS.hStdIn + lda (pPS),y + >SYSCALL2 FEOF + bcs .9 + tay + bne .18 + + >SYSCALL2 GetChar + bcs .9 + + tax + + ldy #S.SCRN.bEscMode + lda (ZPScrnPtr),y + beq .20 + + bmi .40 IAC mode + + iny S.SCRN.InBufPtr + lda (ZPScrnPtr),y + + cpx #'[' CSI ? + bne .10 + + cmp #S.SCRN.InBufPtr + bne .49 buffer not empty...bad SEQ + +.10 jsr CheckCh.ToBuf + bcs .49 Buffer Full + + cpx #'[' + beq .18 + + cpx #64 + bcs CheckCh.ESCSEQ if CC, not a letter...SEQ is incomplete + +.18 lda #0 + clc + rts +*-------------------------------------- +.20 cpx #C.ESC + bne .30 + + inc A = $01 + + jsr CheckCh.SetMode + + lda #0 + clc + rts +*-------------------------------------- +.30 cpx #IAC + bne .38 + + dec A = $FF + jsr CheckCh.SetMode + + inx X = 0 + +.38 txa + clc + rts +*-------------------------------------- +.40 jsr CheckCh.ToBuf + bcs .49 Buffer Full + + cpy #S.SCRN.InBuf First char... + beq .48 + + ldy #S.SCRN.InBuf + lda (ZPScrnPtr),y + cmp #SB + bne CheckCh.IACSEQ + + cpx #SE + bne .48 + + bra CheckCh.IACSEQ + +.49 jsr CheckCh.Reset + +.48 lda #0 + clc +.9 rts +*-------------------------------------- +CheckCh.ESCSEQ cmp #S.SCRN.InBuf+2 + bcs .2 + + ldy #ESC.Out-ESC.In-1 + txa + +.1 cmp ESC.In,y + beq .7 + + dey + bpl .1 + + bra .6 +*-------------------------------------- +* \e[xxx;yyyR +*-------------------------------------- +.2 cpx #'R' Response to cursor position query? + bne .6 + + lda #S.SCRN.InBuf+1 skip ESC [ + jsr GetScrnOfs + >PUSHYA + + >PUSHW L.FMT.ESCCSI.R + + lda #S.OBJ.H + jsr GetScrnOfs + >PUSHYA + + lda #S.OBJ.W + jsr GetScrnOfs + >PUSHYA + + >PUSHBI 4 2 pointers + >SYSCALL2 sscanf + +.6 ldx #0 + bra .8 + +.7 ldx ESC.Out,y + +.8 jsr CheckCh.Reset + + txa + clc +.9 rts +*-------------------------------------- +CheckCh.IACSEQ + >DEBUG + jsr CheckCh.Reset + + lda #0 + clc + rts +*-------------------------------------- +CheckCh.Reset lda #0 + +CheckCh.SetMode ldy #S.SCRN.bEscMode + sta (ZPScrnPtr),y + + iny Y = S.SCRN.InBufPtr + tya + sta (ZPScrnPtr),y + + rts +*-------------------------------------- +CheckCh.ToBuf ldy #S.SCRN.InBufPtr + lda (ZPScrnPtr),y + + cmp #S.SCRN.EndBuf buffer full + bcs .9 + + phy + inc + tay + txa + sta (ZPScrnPtr),y + tya + ply + sta (ZPScrnPtr),y + +* clc + +.9 rts +*-------------------------------------- +GetScrn sta hScrn + >SYSCALL2 GetMemPtr + >STYA ZPScrnPtr + rts +*-------------------------------------- +GetScrnOfs clc + adc ZPScrnPtr + tay + lda ZPScrnPtr+1 + adc #0 +.9 rts *-------------------------------------- CS.END *-------------------------------------- +LibCnt .BS 1 +hLineBuf .BS 1 +*-------------------------------------- +ESC.In .AS "DBAC" +ESC.Out .HS 080A0B15 +*-------------------------------------- +FMT.ESCCSI.R .AZ "%d;%d" +*-------------------------------------- +SEQ.TERMCAP .DA #C.ESC + .AS "[999;999H" Set Cursor Pos to 999,999 + .DA #C.ESC + .AZ "[6n" then query Cursor Pos SEQ.INIT .AS "\ec\e(B\e)0" SEQ.SCROLLRGN .AZ "\e[?7l\e[2;%dr" SEQ.SCROLLCURUP .AS "\e[?7l\e[%d;%dr" diff --git a/SBIN/GETTY.S.txt b/SBIN/GETTY.S.txt index 882a02f7..fdfdb4dc 100644 --- a/SBIN/GETTY.S.txt +++ b/SBIN/GETTY.S.txt @@ -10,7 +10,7 @@ NEW .INB inc/net.telnet.i *-------------------------------------- TIMEOUT.MAX .EQ 40 4 sec. -IAC.BUF.MAX .EQ 32 +IAC.BUF.MAX .EQ 20 *-------------------------------------- .DUMMY .OR ZPBIN @@ -22,10 +22,14 @@ ArgDev .BS 1 ArgProg .BS 1 hFILE .BS 1 bExitOnClose .BS 1 + IAC.CMD .BS 1 IAC.SUBCMD .BS 1 IAC.SB.CMD .BS 1 IAC.SB.LEN .BS 1 + +IAC.BUF .BS IAC.BUF.MAX + ZS.END .ED *-------------------------------------- * File Header (16 Bytes) @@ -90,13 +94,13 @@ CS.RUN ldy #S.PS.ARGC stx ArgProg bra .1 -.9 >PUSHW L.MSG.USAGE - >PUSHBI 0 - >SYSCALL PrintF +.9 >LDYA L.MSG.USAGE + >SYSCALL PutS + lda #E.SYN sec .99 rts - +*-------------------------------------- .8 lda ArgProg beq .9 @@ -120,7 +124,7 @@ CS.RUN ldy #S.PS.ARGC sta (pPS),y iny #S.PS.hStdErr sta (pPS),y - +*-------------------------------------- CS.RUN.LOOP0 >SLEEP >PUSHW L.ENV.TERM @@ -229,6 +233,7 @@ CS.RUN.IAC.SB >SYSCALL GetChar Wait for IAC SB.IS or SEND sta IAC.SB.CMD stz IAC.SB.LEN + .2 >SYSCALL GetChar bcs .9 @@ -236,10 +241,10 @@ CS.RUN.IAC.SB >SYSCALL GetChar Wait for IAC SB.IS or SEND beq .4 end of DATA, go wait SE ldy IAC.SB.LEN - sta (pData),y + sta IAC.BUF,y iny lda #0 - sta (pData),y + sta IAC.BUF,y sty IAC.SB.LEN cpy #IAC.BUF.MAX bne .2 @@ -261,9 +266,10 @@ CS.RUN.IAC.SB >SYSCALL GetChar Wait for IAC SB.IS or SEND bne .8 >PUSHW L.ENV.TERM - >PUSHW pData IAC.SB.DATA + >PUSHWI IAC.BUF >SYSCALL SetEnv .8 jmp CS.RUN.LOOP1 + .9 rts *-------------------------------------- CS.RUN.GREETINGS @@ -328,14 +334,15 @@ CS.END OptionList .AS "Ee" OptionVars .DA #bExitOnClose,#bExitOnClose MSG.GREETINGS .AZ "\r\nA2osX-GeTTY %d.%d on %s\r\n" -MSG.USAGE .AS "Usage : GETTY \r\n" - .AZ " -E : Exit on disconnect\r\n" +MSG.USAGE .AS "Usage : GETTY " + .DA #C.CR,#C.LF + .AZ " -E : Exit on disconnect" *-------------------------------------- TELNETOPTS .DA #IAC,#WILL,#TN.O.BINARY .DA #IAC,#WILL,#TN.O.ECHO .DA #IAC,#WILL,#TN.O.SGA .DA #IAC,#DO,#TN.O.SGA -* .DA #IAC,#DO,#TN.O.NAWS + .DA #IAC,#DO,#TN.O.NAWS .DA #IAC,#DO,#TN.O.TTYPE .DA #IAC,#DO,#TN.O.LINEMODE TELNETOPTS.LEN .EQ *-TELNETOPTS @@ -350,7 +357,6 @@ ENV.TERM .AZ "TERM" .DUMMY .OR 0 DS.START -IAC.SB.DATA .BS IAC.BUF.MAX DS.END .ED MAN SAVE usr/src/sbin/getty.s diff --git a/SBIN/LOGIN.S.txt b/SBIN/LOGIN.S.txt index 11c1cec4..2b1dbe3e 100644 --- a/SBIN/LOGIN.S.txt +++ b/SBIN/LOGIN.S.txt @@ -33,8 +33,8 @@ ZPNewSession .BS 1 ZPOldSession .BS 1 ZPhFile .BS 1 -ZS.END - .ED + +ZS.END .ED *-------------------------------------- * File Header (16 Bytes) *-------------------------------------- @@ -56,23 +56,24 @@ CS.START cld .DA CS.RUN .DA CS.DOEVENT .DA CS.QUIT -L.MSG.NOAUTH .DA MSG.NOAUTH L.MSG.LOGIN .DA MSG.LOGIN L.MSG.PASSWORD .DA MSG.PASSWORD L.MSG.BAD .DA MSG.BAD -L.MSG.CRLF .DA MSG.CRLF L.MSG.BS .DA MSG.BS +L.MSG.CRLF .DA MSG.CRLF +L.ETCNOAUTH .DA ETCNOAUTH L.ETCISSUE .DA ETCISSUE L.ETCMOTD .DA ETCMOTD L.SHELL .DA SHELL .DA 0 *-------------------------------------- +CS.QUIT +*-------------------------------------- CS.INIT clc CS.INIT.RTS rts *-------------------------------------- CS.RUN >LDYA L.ETCISSUE jsr CS.RUN.DumpFile - bcs CS.INIT.RTS lda #0 >PUSHA ROOT user @@ -81,9 +82,8 @@ CS.RUN >LDYA L.ETCISSUE >SYSCALL GetPWUID bcc CS.RUN.AUTH *-------------------------------------- - >LDYA L.MSG.NOAUTH - jsr CS.RUN.StrOut - bcs CS.INIT.RTS + >LDYA L.ETCNOAUTH + jsr CS.RUN.DumpFile *-------------------------------------- CS.RUN.EXECPS >LDYA L.ETCMOTD jsr CS.RUN.DumpFile @@ -94,13 +94,14 @@ CS.RUN.EXECPS >LDYA L.ETCMOTD bcs .9 >SLEEP + .9 rts *-------------------------------------- CS.RUN.AUTH lda #3 sta ZPRetryCnt .1 >LDYA L.MSG.LOGIN - jsr CS.RUN.StrOut + jsr CS.RUN.printf bcs .9 >LEA.G Username @@ -110,7 +111,7 @@ CS.RUN.AUTH lda #3 bcs .9 >LDYA L.MSG.PASSWORD - jsr CS.RUN.StrOut + jsr CS.RUN.printf bcs .9 >LDYA pData >LEA.G Password @@ -120,7 +121,7 @@ CS.RUN.AUTH lda #3 bcs .9 >LDYA L.MSG.CRLF - jsr CS.RUN.StrOut + >SYSCALL Puts bcs .9 >PUSHW pData >PUSHEA.G Password @@ -256,7 +257,7 @@ CS.RUN.GetLine >STYA ZPGetLinePtr bmi .1 >LDYA L.MSG.BS - jsr CS.RUN.StrOut + jsr CS.RUN.printf bra .1 .8 ldy ZPGetLineLen @@ -265,9 +266,9 @@ CS.RUN.GetLine >STYA ZPGetLinePtr clc .9 rts *-------------------------------------- -CS.RUN.StrOut >PUSHYA +CS.RUN.printf >PUSHYA >PUSHBI 0 - >SYSCALL PrintF + >SYSCALL printf rts *-------------------------------------- CS.RUN.DumpFile >PUSHYA @@ -287,13 +288,13 @@ CS.RUN.DumpFile >PUSHYA stx ZPhBuf .1 >PUSHB ZPhFile - >PUSHW ZPBufPtr + jsr .7 >PUSHWI 255 >SYSCALL FGetS bcs .8 - >PUSHW ZPBufPtr - >PUSHW ZPBufPtr + jsr .7 + jsr .7 >SYSCALL Expand >LDYA ZPBufPtr @@ -303,7 +304,7 @@ CS.RUN.DumpFile >PUSHYA .8 lda ZPhBuf >SYSCALL FreeMem - clc +* clc .9 php pha @@ -312,22 +313,24 @@ CS.RUN.DumpFile >PUSHYA pla plp .99 rts + +.7 >PUSHW ZPBufPtr + rts *-------------------------------------- CS.DOEVENT sec rts *-------------------------------------- -CS.QUIT clc - rts -*-------------------------------------- CS.END *-------------------------------------- -MSG.NOAUTH .AS "\r\n\r\nA2osX-Login:No ETC/PASSWD file present, Logged as ROOT.\r\n" - .AS "Consider adding ROOT password with USERADD command.\r\n" -MSG.CRLF .AZ "\r\n" -MSG.LOGIN .AZ "\r\nlogin:" -MSG.PASSWORD .AZ "\r\npassword:" +MSG.LOGIN .DA #C.CR,#C.LF + .AZ "login:" +MSG.PASSWORD .DA #C.CR,#C.LF + .AZ "password:" +*-------------------------------------- MSG.BAD .AZ "Bad user or password" -MSG.BS .DA #C.BS,#C.SPACE,#C.BS,#0 +MSG.BS .DA #C.BS,#C.SPACE,#C.BS +MSG.CRLF .HS 00 +ETCNOAUTH .AZ "${ROOT}etc/noauth" ETCISSUE .AZ "${ROOT}etc/issue" ETCMOTD .AZ "${ROOT}etc/motd" SHELL .AZ "${SHELL}" diff --git a/SHARED/X.SSC.DRV.S.txt b/SHARED/X.SSC.DRV.S.txt index c783e163..5e4bf8d4 100644 --- a/SHARED/X.SSC.DRV.S.txt +++ b/SHARED/X.SSC.DRV.S.txt @@ -278,14 +278,14 @@ Dev.BaudT10pA pha >PUSHBI 0 >PUSHBI 0 >PUSHBI 10 - >FPU MUL32 + >FPU uMUL >PUSHBI 0 >PUSHBI 0 >PUSHBI 0 pla >PUSHA - >FPU ADD32 + >FPU uADD >PULLL DCB+S.DCB.COM.BAUD rts *-------------------------------------- @@ -873,5 +873,5 @@ DCB .DA #S.DCB.T.COM DRV.END MAN SAVE usr/src/shared/x.ssc.drv.s -LOAD usr/src/drv/ssc.drv.s +LOAD usr/src/drv/ssc.i.drv.s ASM diff --git a/SYS/KERNEL.S.BIN.txt b/SYS/KERNEL.S.BIN.txt index 1b7c1664..b109c5a2 100644 --- a/SYS/KERNEL.S.BIN.txt +++ b/SYS/KERNEL.S.BIN.txt @@ -275,22 +275,54 @@ K.InsDrv >STYA ZPPtr3 SRC PTR for move ldy #0 .1 inx bne .2 + pla inc beq .3 + pha .2 lda (ZPPtr3),y sta (ZPPtr4),y iny bne .1 + inc ZPPtr3+1 inc ZPPtr4+1 bra .1 + .3 jsr BIN.RelDrv Relocate at Ptr1 + .7 ldy #$ff SELF MODIFIED .8 lda #$ff SELF MODIFIED .9 rts *-------------------------------------- +MEM.GetKBuf pha + tya + clc + adc DevMgr.Free + tax + pla + adc DevMgr.Free+1 + bcs .99 we crossed $FFFF, out of mem + + cpx #DevMgr.HiMem + pha + sbc /DevMgr.HiMem + pla + bcs .99 No More Room... + + ldy DevMgr.Free + stx DevMgr.Free + ldx DevMgr.Free+1 + sta DevMgr.Free+1 + txa +* clc + rts + +.99 lda #E.OOM +* sec + rts +*-------------------------------------- BIN.RelExe ldy #H.BIN.T+1 lda (ZPPtr1),y cmp /H.BIN.T.BIN65 diff --git a/SYS/KERNEL.S.MEM.txt b/SYS/KERNEL.S.MEM.txt index 1553bed0..a8baa452 100644 --- a/SYS/KERNEL.S.MEM.txt +++ b/SYS/KERNEL.S.MEM.txt @@ -615,33 +615,6 @@ MEM.SetA1A2 jsr K.GetMemPtr rts *-------------------------------------- -MEM.GetKBuf pha - tya - clc - adc DevMgr.Free - tax - pla - adc DevMgr.Free+1 - bcs .99 we crossed $FFFF, out of mem - - cpx #DevMgr.HiMem - pha - sbc /DevMgr.HiMem - pla - bcs .99 No More Room... - - ldy DevMgr.Free - stx DevMgr.Free - ldx DevMgr.Free+1 - sta DevMgr.Free+1 - txa -* clc - rts - -.99 lda #E.OOM -* sec - rts -*-------------------------------------- MAN SAVE usr/src/sys/kernel.s.mem LOAD usr/src/sys/kernel.s diff --git a/SYS/KERNEL.S.txt b/SYS/KERNEL.S.txt index 7a1c364c..5d31ee32 100644 --- a/SYS/KERNEL.S.txt +++ b/SYS/KERNEL.S.txt @@ -38,7 +38,6 @@ MAIN.B .PH A2osX.EndTables .INB usr/src/sys/kernel.s.drv .INB usr/src/sys/kernel.s.pft .INB usr/src/sys/kernel.s.fs - .INB usr/src/sys/kernel.s.math16 .INB usr/src/sys/kernel.s.mathf Mem.MLoMem .EQ * .EP @@ -110,6 +109,7 @@ E0.B .PH $E000 .INB usr/src/sys/kernel.s.irq .INB usr/src/sys/kernel.s.shared .INB usr/src/sys/kernel.s.math + .INB usr/src/sys/kernel.s.math16 .INB usr/src/sys/kernel.s.math32 .INB usr/src/sys/kernel.s.term