├── LICENSE.md ├── README.md ├── beep.h ├── build-plan9port.sh ├── font.h ├── header ├── io.c ├── io.h ├── key.h ├── keyboard.c ├── keyboard.h ├── menu.c ├── menu.h ├── mkfile ├── plato_key.h ├── platoterm.c ├── protocol.c ├── protocol.h ├── screen.c ├── screen.h ├── splash.h ├── terminal.c ├── terminal.h ├── touch.c └── touch.h /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU General Public License 2 | ========================== 3 | 4 | _Version 3, 29 June 2007_ 5 | _Copyright © 2007 Free Software Foundation, Inc. <>_ 6 | 7 | Everyone is permitted to copy and distribute verbatim copies of this license 8 | document, but changing it is not allowed. 9 | 10 | ## Preamble 11 | 12 | The GNU General Public License is a free, copyleft license for software and other 13 | kinds of works. 14 | 15 | The licenses for most software and other practical works are designed to take away 16 | your freedom to share and change the works. By contrast, the GNU General Public 17 | License is intended to guarantee your freedom to share and change all versions of a 18 | program--to make sure it remains free software for all its users. We, the Free 19 | Software Foundation, use the GNU General Public License for most of our software; it 20 | applies also to any other work released this way by its authors. You can apply it to 21 | your programs, too. 22 | 23 | When we speak of free software, we are referring to freedom, not price. Our General 24 | Public Licenses are designed to make sure that you have the freedom to distribute 25 | copies of free software (and charge for them if you wish), that you receive source 26 | code or can get it if you want it, that you can change the software or use pieces of 27 | it in new free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you these rights or 30 | asking you to surrender the rights. Therefore, you have certain responsibilities if 31 | you distribute copies of the software, or if you modify it: responsibilities to 32 | respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether gratis or for a fee, 35 | you must pass on to the recipients the same freedoms that you received. You must make 36 | sure that they, too, receive or can get the source code. And you must show them these 37 | terms so they know their rights. 38 | 39 | Developers that use the GNU GPL protect your rights with two steps: **(1)** assert 40 | copyright on the software, and **(2)** offer you this License giving you legal permission 41 | to copy, distribute and/or modify it. 42 | 43 | For the developers' and authors' protection, the GPL clearly explains that there is 44 | no warranty for this free software. For both users' and authors' sake, the GPL 45 | requires that modified versions be marked as changed, so that their problems will not 46 | be attributed erroneously to authors of previous versions. 47 | 48 | Some devices are designed to deny users access to install or run modified versions of 49 | the software inside them, although the manufacturer can do so. This is fundamentally 50 | incompatible with the aim of protecting users' freedom to change the software. The 51 | systematic pattern of such abuse occurs in the area of products for individuals to 52 | use, which is precisely where it is most unacceptable. Therefore, we have designed 53 | this version of the GPL to prohibit the practice for those products. If such problems 54 | arise substantially in other domains, we stand ready to extend this provision to 55 | those domains in future versions of the GPL, as needed to protect the freedom of 56 | users. 57 | 58 | Finally, every program is threatened constantly by software patents. States should 59 | not allow patents to restrict development and use of software on general-purpose 60 | computers, but in those that do, we wish to avoid the special danger that patents 61 | applied to a free program could make it effectively proprietary. To prevent this, the 62 | GPL assures that patents cannot be used to render the program non-free. 63 | 64 | The precise terms and conditions for copying, distribution and modification follow. 65 | 66 | ## TERMS AND CONDITIONS 67 | 68 | ### 0. Definitions 69 | 70 | “This License” refers to version 3 of the GNU General Public License. 71 | 72 | “Copyright” also means copyright-like laws that apply to other kinds of 73 | works, such as semiconductor masks. 74 | 75 | “The Program” refers to any copyrightable work licensed under this 76 | License. Each licensee is addressed as “you”. “Licensees” and 77 | “recipients” may be individuals or organizations. 78 | 79 | To “modify” a work means to copy from or adapt all or part of the work in 80 | a fashion requiring copyright permission, other than the making of an exact copy. The 81 | resulting work is called a “modified version” of the earlier work or a 82 | work “based on” the earlier work. 83 | 84 | A “covered work” means either the unmodified Program or a work based on 85 | the Program. 86 | 87 | To “propagate” a work means to do anything with it that, without 88 | permission, would make you directly or secondarily liable for infringement under 89 | applicable copyright law, except executing it on a computer or modifying a private 90 | copy. Propagation includes copying, distribution (with or without modification), 91 | making available to the public, and in some countries other activities as well. 92 | 93 | To “convey” a work means any kind of propagation that enables other 94 | parties to make or receive copies. Mere interaction with a user through a computer 95 | network, with no transfer of a copy, is not conveying. 96 | 97 | An interactive user interface displays “Appropriate Legal Notices” to the 98 | extent that it includes a convenient and prominently visible feature that **(1)** 99 | displays an appropriate copyright notice, and **(2)** tells the user that there is no 100 | warranty for the work (except to the extent that warranties are provided), that 101 | licensees may convey the work under this License, and how to view a copy of this 102 | License. If the interface presents a list of user commands or options, such as a 103 | menu, a prominent item in the list meets this criterion. 104 | 105 | ### 1. Source Code 106 | 107 | The “source code” for a work means the preferred form of the work for 108 | making modifications to it. “Object code” means any non-source form of a 109 | work. 110 | 111 | A “Standard Interface” means an interface that either is an official 112 | standard defined by a recognized standards body, or, in the case of interfaces 113 | specified for a particular programming language, one that is widely used among 114 | developers working in that language. 115 | 116 | The “System Libraries” of an executable work include anything, other than 117 | the work as a whole, that **(a)** is included in the normal form of packaging a Major 118 | Component, but which is not part of that Major Component, and **(b)** serves only to 119 | enable use of the work with that Major Component, or to implement a Standard 120 | Interface for which an implementation is available to the public in source code form. 121 | A “Major Component”, in this context, means a major essential component 122 | (kernel, window system, and so on) of the specific operating system (if any) on which 123 | the executable work runs, or a compiler used to produce the work, or an object code 124 | interpreter used to run it. 125 | 126 | The “Corresponding Source” for a work in object code form means all the 127 | source code needed to generate, install, and (for an executable work) run the object 128 | code and to modify the work, including scripts to control those activities. However, 129 | it does not include the work's System Libraries, or general-purpose tools or 130 | generally available free programs which are used unmodified in performing those 131 | activities but which are not part of the work. For example, Corresponding Source 132 | includes interface definition files associated with source files for the work, and 133 | the source code for shared libraries and dynamically linked subprograms that the work 134 | is specifically designed to require, such as by intimate data communication or 135 | control flow between those subprograms and other parts of the work. 136 | 137 | The Corresponding Source need not include anything that users can regenerate 138 | automatically from other parts of the Corresponding Source. 139 | 140 | The Corresponding Source for a work in source code form is that same work. 141 | 142 | ### 2. Basic Permissions 143 | 144 | All rights granted under this License are granted for the term of copyright on the 145 | Program, and are irrevocable provided the stated conditions are met. This License 146 | explicitly affirms your unlimited permission to run the unmodified Program. The 147 | output from running a covered work is covered by this License only if the output, 148 | given its content, constitutes a covered work. This License acknowledges your rights 149 | of fair use or other equivalent, as provided by copyright law. 150 | 151 | You may make, run and propagate covered works that you do not convey, without 152 | conditions so long as your license otherwise remains in force. You may convey covered 153 | works to others for the sole purpose of having them make modifications exclusively 154 | for you, or provide you with facilities for running those works, provided that you 155 | comply with the terms of this License in conveying all material for which you do not 156 | control copyright. Those thus making or running the covered works for you must do so 157 | exclusively on your behalf, under your direction and control, on terms that prohibit 158 | them from making any copies of your copyrighted material outside their relationship 159 | with you. 160 | 161 | Conveying under any other circumstances is permitted solely under the conditions 162 | stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 163 | 164 | ### 3. Protecting Users' Legal Rights From Anti-Circumvention Law 165 | 166 | No covered work shall be deemed part of an effective technological measure under any 167 | applicable law fulfilling obligations under article 11 of the WIPO copyright treaty 168 | adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention 169 | of such measures. 170 | 171 | When you convey a covered work, you waive any legal power to forbid circumvention of 172 | technological measures to the extent such circumvention is effected by exercising 173 | rights under this License with respect to the covered work, and you disclaim any 174 | intention to limit operation or modification of the work as a means of enforcing, 175 | against the work's users, your or third parties' legal rights to forbid circumvention 176 | of technological measures. 177 | 178 | ### 4. Conveying Verbatim Copies 179 | 180 | You may convey verbatim copies of the Program's source code as you receive it, in any 181 | medium, provided that you conspicuously and appropriately publish on each copy an 182 | appropriate copyright notice; keep intact all notices stating that this License and 183 | any non-permissive terms added in accord with section 7 apply to the code; keep 184 | intact all notices of the absence of any warranty; and give all recipients a copy of 185 | this License along with the Program. 186 | 187 | You may charge any price or no price for each copy that you convey, and you may offer 188 | support or warranty protection for a fee. 189 | 190 | ### 5. Conveying Modified Source Versions 191 | 192 | You may convey a work based on the Program, or the modifications to produce it from 193 | the Program, in the form of source code under the terms of section 4, provided that 194 | you also meet all of these conditions: 195 | 196 | * **a)** The work must carry prominent notices stating that you modified it, and giving a 197 | relevant date. 198 | * **b)** The work must carry prominent notices stating that it is released under this 199 | License and any conditions added under section 7. This requirement modifies the 200 | requirement in section 4 to “keep intact all notices”. 201 | * **c)** You must license the entire work, as a whole, under this License to anyone who 202 | comes into possession of a copy. This License will therefore apply, along with any 203 | applicable section 7 additional terms, to the whole of the work, and all its parts, 204 | regardless of how they are packaged. This License gives no permission to license the 205 | work in any other way, but it does not invalidate such permission if you have 206 | separately received it. 207 | * **d)** If the work has interactive user interfaces, each must display Appropriate Legal 208 | Notices; however, if the Program has interactive interfaces that do not display 209 | Appropriate Legal Notices, your work need not make them do so. 210 | 211 | A compilation of a covered work with other separate and independent works, which are 212 | not by their nature extensions of the covered work, and which are not combined with 213 | it such as to form a larger program, in or on a volume of a storage or distribution 214 | medium, is called an “aggregate” if the compilation and its resulting 215 | copyright are not used to limit the access or legal rights of the compilation's users 216 | beyond what the individual works permit. Inclusion of a covered work in an aggregate 217 | does not cause this License to apply to the other parts of the aggregate. 218 | 219 | ### 6. Conveying Non-Source Forms 220 | 221 | You may convey a covered work in object code form under the terms of sections 4 and 222 | 5, provided that you also convey the machine-readable Corresponding Source under the 223 | terms of this License, in one of these ways: 224 | 225 | * **a)** Convey the object code in, or embodied in, a physical product (including a 226 | physical distribution medium), accompanied by the Corresponding Source fixed on a 227 | durable physical medium customarily used for software interchange. 228 | * **b)** Convey the object code in, or embodied in, a physical product (including a 229 | physical distribution medium), accompanied by a written offer, valid for at least 230 | three years and valid for as long as you offer spare parts or customer support for 231 | that product model, to give anyone who possesses the object code either **(1)** a copy of 232 | the Corresponding Source for all the software in the product that is covered by this 233 | License, on a durable physical medium customarily used for software interchange, for 234 | a price no more than your reasonable cost of physically performing this conveying of 235 | source, or **(2)** access to copy the Corresponding Source from a network server at no 236 | charge. 237 | * **c)** Convey individual copies of the object code with a copy of the written offer to 238 | provide the Corresponding Source. This alternative is allowed only occasionally and 239 | noncommercially, and only if you received the object code with such an offer, in 240 | accord with subsection 6b. 241 | * **d)** Convey the object code by offering access from a designated place (gratis or for 242 | a charge), and offer equivalent access to the Corresponding Source in the same way 243 | through the same place at no further charge. You need not require recipients to copy 244 | the Corresponding Source along with the object code. If the place to copy the object 245 | code is a network server, the Corresponding Source may be on a different server 246 | (operated by you or a third party) that supports equivalent copying facilities, 247 | provided you maintain clear directions next to the object code saying where to find 248 | the Corresponding Source. Regardless of what server hosts the Corresponding Source, 249 | you remain obligated to ensure that it is available for as long as needed to satisfy 250 | these requirements. 251 | * **e)** Convey the object code using peer-to-peer transmission, provided you inform 252 | other peers where the object code and Corresponding Source of the work are being 253 | offered to the general public at no charge under subsection 6d. 254 | 255 | A separable portion of the object code, whose source code is excluded from the 256 | Corresponding Source as a System Library, need not be included in conveying the 257 | object code work. 258 | 259 | A “User Product” is either **(1)** a “consumer product”, which 260 | means any tangible personal property which is normally used for personal, family, or 261 | household purposes, or **(2)** anything designed or sold for incorporation into a 262 | dwelling. In determining whether a product is a consumer product, doubtful cases 263 | shall be resolved in favor of coverage. For a particular product received by a 264 | particular user, “normally used” refers to a typical or common use of 265 | that class of product, regardless of the status of the particular user or of the way 266 | in which the particular user actually uses, or expects or is expected to use, the 267 | product. A product is a consumer product regardless of whether the product has 268 | substantial commercial, industrial or non-consumer uses, unless such uses represent 269 | the only significant mode of use of the product. 270 | 271 | “Installation Information” for a User Product means any methods, 272 | procedures, authorization keys, or other information required to install and execute 273 | modified versions of a covered work in that User Product from a modified version of 274 | its Corresponding Source. The information must suffice to ensure that the continued 275 | functioning of the modified object code is in no case prevented or interfered with 276 | solely because modification has been made. 277 | 278 | If you convey an object code work under this section in, or with, or specifically for 279 | use in, a User Product, and the conveying occurs as part of a transaction in which 280 | the right of possession and use of the User Product is transferred to the recipient 281 | in perpetuity or for a fixed term (regardless of how the transaction is 282 | characterized), the Corresponding Source conveyed under this section must be 283 | accompanied by the Installation Information. But this requirement does not apply if 284 | neither you nor any third party retains the ability to install modified object code 285 | on the User Product (for example, the work has been installed in ROM). 286 | 287 | The requirement to provide Installation Information does not include a requirement to 288 | continue to provide support service, warranty, or updates for a work that has been 289 | modified or installed by the recipient, or for the User Product in which it has been 290 | modified or installed. Access to a network may be denied when the modification itself 291 | materially and adversely affects the operation of the network or violates the rules 292 | and protocols for communication across the network. 293 | 294 | Corresponding Source conveyed, and Installation Information provided, in accord with 295 | this section must be in a format that is publicly documented (and with an 296 | implementation available to the public in source code form), and must require no 297 | special password or key for unpacking, reading or copying. 298 | 299 | ### 7. Additional Terms 300 | 301 | “Additional permissions” are terms that supplement the terms of this 302 | License by making exceptions from one or more of its conditions. Additional 303 | permissions that are applicable to the entire Program shall be treated as though they 304 | were included in this License, to the extent that they are valid under applicable 305 | law. If additional permissions apply only to part of the Program, that part may be 306 | used separately under those permissions, but the entire Program remains governed by 307 | this License without regard to the additional permissions. 308 | 309 | When you convey a copy of a covered work, you may at your option remove any 310 | additional permissions from that copy, or from any part of it. (Additional 311 | permissions may be written to require their own removal in certain cases when you 312 | modify the work.) You may place additional permissions on material, added by you to a 313 | covered work, for which you have or can give appropriate copyright permission. 314 | 315 | Notwithstanding any other provision of this License, for material you add to a 316 | covered work, you may (if authorized by the copyright holders of that material) 317 | supplement the terms of this License with terms: 318 | 319 | * **a)** Disclaiming warranty or limiting liability differently from the terms of 320 | sections 15 and 16 of this License; or 321 | * **b)** Requiring preservation of specified reasonable legal notices or author 322 | attributions in that material or in the Appropriate Legal Notices displayed by works 323 | containing it; or 324 | * **c)** Prohibiting misrepresentation of the origin of that material, or requiring that 325 | modified versions of such material be marked in reasonable ways as different from the 326 | original version; or 327 | * **d)** Limiting the use for publicity purposes of names of licensors or authors of the 328 | material; or 329 | * **e)** Declining to grant rights under trademark law for use of some trade names, 330 | trademarks, or service marks; or 331 | * **f)** Requiring indemnification of licensors and authors of that material by anyone 332 | who conveys the material (or modified versions of it) with contractual assumptions of 333 | liability to the recipient, for any liability that these contractual assumptions 334 | directly impose on those licensors and authors. 335 | 336 | All other non-permissive additional terms are considered “further 337 | restrictions” within the meaning of section 10. If the Program as you received 338 | it, or any part of it, contains a notice stating that it is governed by this License 339 | along with a term that is a further restriction, you may remove that term. If a 340 | license document contains a further restriction but permits relicensing or conveying 341 | under this License, you may add to a covered work material governed by the terms of 342 | that license document, provided that the further restriction does not survive such 343 | relicensing or conveying. 344 | 345 | If you add terms to a covered work in accord with this section, you must place, in 346 | the relevant source files, a statement of the additional terms that apply to those 347 | files, or a notice indicating where to find the applicable terms. 348 | 349 | Additional terms, permissive or non-permissive, may be stated in the form of a 350 | separately written license, or stated as exceptions; the above requirements apply 351 | either way. 352 | 353 | ### 8. Termination 354 | 355 | You may not propagate or modify a covered work except as expressly provided under 356 | this License. Any attempt otherwise to propagate or modify it is void, and will 357 | automatically terminate your rights under this License (including any patent licenses 358 | granted under the third paragraph of section 11). 359 | 360 | However, if you cease all violation of this License, then your license from a 361 | particular copyright holder is reinstated **(a)** provisionally, unless and until the 362 | copyright holder explicitly and finally terminates your license, and **(b)** permanently, 363 | if the copyright holder fails to notify you of the violation by some reasonable means 364 | prior to 60 days after the cessation. 365 | 366 | Moreover, your license from a particular copyright holder is reinstated permanently 367 | if the copyright holder notifies you of the violation by some reasonable means, this 368 | is the first time you have received notice of violation of this License (for any 369 | work) from that copyright holder, and you cure the violation prior to 30 days after 370 | your receipt of the notice. 371 | 372 | Termination of your rights under this section does not terminate the licenses of 373 | parties who have received copies or rights from you under this License. If your 374 | rights have been terminated and not permanently reinstated, you do not qualify to 375 | receive new licenses for the same material under section 10. 376 | 377 | ### 9. Acceptance Not Required for Having Copies 378 | 379 | You are not required to accept this License in order to receive or run a copy of the 380 | Program. Ancillary propagation of a covered work occurring solely as a consequence of 381 | using peer-to-peer transmission to receive a copy likewise does not require 382 | acceptance. However, nothing other than this License grants you permission to 383 | propagate or modify any covered work. These actions infringe copyright if you do not 384 | accept this License. Therefore, by modifying or propagating a covered work, you 385 | indicate your acceptance of this License to do so. 386 | 387 | ### 10. Automatic Licensing of Downstream Recipients 388 | 389 | Each time you convey a covered work, the recipient automatically receives a license 390 | from the original licensors, to run, modify and propagate that work, subject to this 391 | License. You are not responsible for enforcing compliance by third parties with this 392 | License. 393 | 394 | An “entity transaction” is a transaction transferring control of an 395 | organization, or substantially all assets of one, or subdividing an organization, or 396 | merging organizations. If propagation of a covered work results from an entity 397 | transaction, each party to that transaction who receives a copy of the work also 398 | receives whatever licenses to the work the party's predecessor in interest had or 399 | could give under the previous paragraph, plus a right to possession of the 400 | Corresponding Source of the work from the predecessor in interest, if the predecessor 401 | has it or can get it with reasonable efforts. 402 | 403 | You may not impose any further restrictions on the exercise of the rights granted or 404 | affirmed under this License. For example, you may not impose a license fee, royalty, 405 | or other charge for exercise of rights granted under this License, and you may not 406 | initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging 407 | that any patent claim is infringed by making, using, selling, offering for sale, or 408 | importing the Program or any portion of it. 409 | 410 | ### 11. Patents 411 | 412 | A “contributor” is a copyright holder who authorizes use under this 413 | License of the Program or a work on which the Program is based. The work thus 414 | licensed is called the contributor's “contributor version”. 415 | 416 | A contributor's “essential patent claims” are all patent claims owned or 417 | controlled by the contributor, whether already acquired or hereafter acquired, that 418 | would be infringed by some manner, permitted by this License, of making, using, or 419 | selling its contributor version, but do not include claims that would be infringed 420 | only as a consequence of further modification of the contributor version. For 421 | purposes of this definition, “control” includes the right to grant patent 422 | sublicenses in a manner consistent with the requirements of this License. 423 | 424 | Each contributor grants you a non-exclusive, worldwide, royalty-free patent license 425 | under the contributor's essential patent claims, to make, use, sell, offer for sale, 426 | import and otherwise run, modify and propagate the contents of its contributor 427 | version. 428 | 429 | In the following three paragraphs, a “patent license” is any express 430 | agreement or commitment, however denominated, not to enforce a patent (such as an 431 | express permission to practice a patent or covenant not to sue for patent 432 | infringement). To “grant” such a patent license to a party means to make 433 | such an agreement or commitment not to enforce a patent against the party. 434 | 435 | If you convey a covered work, knowingly relying on a patent license, and the 436 | Corresponding Source of the work is not available for anyone to copy, free of charge 437 | and under the terms of this License, through a publicly available network server or 438 | other readily accessible means, then you must either **(1)** cause the Corresponding 439 | Source to be so available, or **(2)** arrange to deprive yourself of the benefit of the 440 | patent license for this particular work, or **(3)** arrange, in a manner consistent with 441 | the requirements of this License, to extend the patent license to downstream 442 | recipients. “Knowingly relying” means you have actual knowledge that, but 443 | for the patent license, your conveying the covered work in a country, or your 444 | recipient's use of the covered work in a country, would infringe one or more 445 | identifiable patents in that country that you have reason to believe are valid. 446 | 447 | If, pursuant to or in connection with a single transaction or arrangement, you 448 | convey, or propagate by procuring conveyance of, a covered work, and grant a patent 449 | license to some of the parties receiving the covered work authorizing them to use, 450 | propagate, modify or convey a specific copy of the covered work, then the patent 451 | license you grant is automatically extended to all recipients of the covered work and 452 | works based on it. 453 | 454 | A patent license is “discriminatory” if it does not include within the 455 | scope of its coverage, prohibits the exercise of, or is conditioned on the 456 | non-exercise of one or more of the rights that are specifically granted under this 457 | License. You may not convey a covered work if you are a party to an arrangement with 458 | a third party that is in the business of distributing software, under which you make 459 | payment to the third party based on the extent of your activity of conveying the 460 | work, and under which the third party grants, to any of the parties who would receive 461 | the covered work from you, a discriminatory patent license **(a)** in connection with 462 | copies of the covered work conveyed by you (or copies made from those copies), or **(b)** 463 | primarily for and in connection with specific products or compilations that contain 464 | the covered work, unless you entered into that arrangement, or that patent license 465 | was granted, prior to 28 March 2007. 466 | 467 | Nothing in this License shall be construed as excluding or limiting any implied 468 | license or other defenses to infringement that may otherwise be available to you 469 | under applicable patent law. 470 | 471 | ### 12. No Surrender of Others' Freedom 472 | 473 | If conditions are imposed on you (whether by court order, agreement or otherwise) 474 | that contradict the conditions of this License, they do not excuse you from the 475 | conditions of this License. If you cannot convey a covered work so as to satisfy 476 | simultaneously your obligations under this License and any other pertinent 477 | obligations, then as a consequence you may not convey it at all. For example, if you 478 | agree to terms that obligate you to collect a royalty for further conveying from 479 | those to whom you convey the Program, the only way you could satisfy both those terms 480 | and this License would be to refrain entirely from conveying the Program. 481 | 482 | ### 13. Use with the GNU Affero General Public License 483 | 484 | Notwithstanding any other provision of this License, you have permission to link or 485 | combine any covered work with a work licensed under version 3 of the GNU Affero 486 | General Public License into a single combined work, and to convey the resulting work. 487 | The terms of this License will continue to apply to the part which is the covered 488 | work, but the special requirements of the GNU Affero General Public License, section 489 | 13, concerning interaction through a network will apply to the combination as such. 490 | 491 | ### 14. Revised Versions of this License 492 | 493 | The Free Software Foundation may publish revised and/or new versions of the GNU 494 | General Public License from time to time. Such new versions will be similar in spirit 495 | to the present version, but may differ in detail to address new problems or concerns. 496 | 497 | Each version is given a distinguishing version number. If the Program specifies that 498 | a certain numbered version of the GNU General Public License “or any later 499 | version” applies to it, you have the option of following the terms and 500 | conditions either of that numbered version or of any later version published by the 501 | Free Software Foundation. If the Program does not specify a version number of the GNU 502 | General Public License, you may choose any version ever published by the Free 503 | Software Foundation. 504 | 505 | If the Program specifies that a proxy can decide which future versions of the GNU 506 | General Public License can be used, that proxy's public statement of acceptance of a 507 | version permanently authorizes you to choose that version for the Program. 508 | 509 | Later license versions may give you additional or different permissions. However, no 510 | additional obligations are imposed on any author or copyright holder as a result of 511 | your choosing to follow a later version. 512 | 513 | ### 15. Disclaimer of Warranty 514 | 515 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 516 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 517 | PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER 518 | EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 519 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE 520 | QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE 521 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 522 | 523 | ### 16. Limitation of Liability 524 | 525 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY 526 | COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS 527 | PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, 528 | INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 529 | PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE 530 | OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE 531 | WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 532 | POSSIBILITY OF SUCH DAMAGES. 533 | 534 | ### 17. Interpretation of Sections 15 and 16 535 | 536 | If the disclaimer of warranty and limitation of liability provided above cannot be 537 | given local legal effect according to their terms, reviewing courts shall apply local 538 | law that most closely approximates an absolute waiver of all civil liability in 539 | connection with the Program, unless a warranty or assumption of liability accompanies 540 | a copy of the Program in return for a fee. 541 | 542 | _END OF TERMS AND CONDITIONS_ 543 | 544 | ## How to Apply These Terms to Your New Programs 545 | 546 | If you develop a new program, and you want it to be of the greatest possible use to 547 | the public, the best way to achieve this is to make it free software which everyone 548 | can redistribute and change under these terms. 549 | 550 | To do so, attach the following notices to the program. It is safest to attach them 551 | to the start of each source file to most effectively state the exclusion of warranty; 552 | and each file should have at least the “copyright” line and a pointer to 553 | where the full notice is found. 554 | 555 | 556 | Copyright (C) 557 | 558 | This program is free software: you can redistribute it and/or modify 559 | it under the terms of the GNU General Public License as published by 560 | the Free Software Foundation, either version 3 of the License, or 561 | (at your option) any later version. 562 | 563 | This program is distributed in the hope that it will be useful, 564 | but WITHOUT ANY WARRANTY; without even the implied warranty of 565 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 566 | GNU General Public License for more details. 567 | 568 | You should have received a copy of the GNU General Public License 569 | along with this program. If not, see . 570 | 571 | Also add information on how to contact you by electronic and paper mail. 572 | 573 | If the program does terminal interaction, make it output a short notice like this 574 | when it starts in an interactive mode: 575 | 576 | Copyright (C) 577 | This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. 578 | This is free software, and you are welcome to redistribute it 579 | under certain conditions; type 'show c' for details. 580 | 581 | The hypothetical commands `show w` and `show c` should show the appropriate parts of 582 | the General Public License. Of course, your program's commands might be different; 583 | for a GUI interface, you would use an “about box”. 584 | 585 | You should also get your employer (if you work as a programmer) or school, if any, to 586 | sign a “copyright disclaimer” for the program, if necessary. For more 587 | information on this, and how to apply and follow the GNU GPL, see 588 | <>. 589 | 590 | The GNU General Public License does not permit incorporating your program into 591 | proprietary programs. If your program is a subroutine library, you may consider it 592 | more useful to permit linking proprietary applications with the library. If this is 593 | what you want to do, use the GNU Lesser General Public License instead of this 594 | License. But first, please read 595 | <>. 596 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # platoterm-plan9 2 | 3 | PLATOTERM is a PLATO terminal emulator that has been ported to many platforms, as part of the [IRATA.ONLINE](https://irata.online/) project. 4 | 5 | ## Features 6 | 7 | * Native Plan 9 application. 8 | * 24-bit color terminal support 9 | * PLATO touch panel mapped as mouse device 10 | * Uses the [ASCII PLATO](https://irata.online/assets/s0ascers-045c83081e9ada2008378c3ae6aa62564b213a71decf9fe04608909b91d20ad1.html) protocol 11 | 12 | ## Missing features 13 | 14 | * The paint/fill function is currently stubbed, because it needs a flood fill function. (anyone want to help?) 15 | 16 | ## Compiling / Installation 17 | 18 | ``` 19 | % mk 20 | % mk install 21 | ``` 22 | 23 | ## Invoking platoterm 24 | 25 | ``` 26 | % platoterm -h [-p ] 27 | ``` 28 | 29 | If -p is not specified, then the port is assumed to be the default ASCII port of 8005. 30 | 31 | Upon starting, platoterm will resize the parent window to 520,520 (to accommodate the client area of 512,512), and immediately attempt the connection. 32 | 33 | ### PLATO hosts 34 | 35 | * [irata.online](https://irata.online/) 36 | * [cyberserv.org](http://cyber1.org/) 37 | 38 | ## Quitting platoterm 39 | 40 | The program stops whenever the connection is hung up, or the Quit option is selected from the right click menu. 41 | 42 | ## Touch screen 43 | 44 | The left mouse button will 45 | 46 | ## PLATO Keys 47 | 48 | The PLATO keyboard has a lot of special keys. These can be accessed via the middle and right click menus: 49 | 50 | | Right click menu keys 51 | |--- 52 | | ANS 53 | | BACK 54 | | COPY 55 | | DATA 56 | | EDIT 57 | | FONT 58 | | HELP 59 | | LAB 60 | | MICRO 61 | | NEXT 62 | | □ (access) 63 | | STOP 64 | | SUB 65 | | SUPER 66 | | TERM 67 | | × 68 | | ÷ 69 | | Σ 70 | | Δ 71 | | Quit 72 | 73 | | Middle click menu keys 74 | |--- 75 | | SHIFT-BACK (BACK1) 76 | | SHIFT-COPY (COPY1) 77 | | SHIFT-DATA (DATA1) 78 | | SHIFT-EDIT (EDIT1) 79 | | SHIFT-HELP (HELP1) 80 | | SHIFT-LAB (LAB1) 81 | | SHIFT-NEXT (NEXT1) 82 | | SHIFT-STOP (STOP1) 83 | | SHIFT-SUB (SUB1) 84 | | SHIFT-SUPER (SUPER1) 85 | 86 | ## Authors 87 | 88 | * Thomas Cherryhomes 89 | * Steve Peltz, who wrote the original pad.c state machine which became protocol.c in platoterm. 90 | 91 | 92 | -------------------------------------------------------------------------------- /build-plan9port.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 9c io.c 3 | 9c keyboard.c 4 | 9c menu.c 5 | 9c platoterm.c 6 | 9c protocol.c 7 | 9c screen.c 8 | 9c terminal.c 9 | 9c touch.c 10 | 9l -o platoterm io.o keyboard.o menu.o platoterm.o protocol.o screen.o terminal.o touch.o 11 | 12 | -------------------------------------------------------------------------------- /font.h: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * font.h - Bitmap font definition - 8x16 1-bit bitmap 13 | */ 14 | 15 | unsigned char plato_font[]={ 16 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x20 space */ 17 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 18 | 19 | 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10, /* 0x21 ! */ 20 | 0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00, 21 | 22 | 0x00,0x00,0x00,0x28,0x28,0x28,0x00,0x00, /* 0x22 " */ 23 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 24 | 25 | 0x00,0x00,0x00,0x28,0x28,0xfe,0x28,0xfe, /* 0x23 # */ 26 | 0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00, 27 | 28 | 0x00,0x00,0x00,0x10,0x7c,0x92,0x90,0x7c, /* 0x24 $ */ 29 | 0x12,0x92,0x7c,0x10,0x00,0x00,0x00,0x00, 30 | 31 | 0x00,0x00,0x00,0x40,0xa2,0xa4,0x48,0x10, /* 0x25 % */ 32 | 0x24,0x4a,0x8a,0x04,0x00,0x00,0x00,0x00, 33 | 34 | 0x00,0x00,0x00,0x20,0x50,0x50,0x20,0x62, /* 0x26 & */ 35 | 0x92,0x8c,0x8c,0x72,0x00,0x00,0x00,0x00, 36 | 37 | 0x00,0x00,0x00,0x10,0x10,0x10,0x00,0x00, /* 0x27 ' */ 38 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 39 | 40 | 0x00,0x00,0x00,0x02,0x04,0x08,0x08,0x08, /* 0x28 ( */ 41 | 0x08,0x08,0x08,0x04,0x02,0x00,0x00,0x00, 42 | 43 | 0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x20, /* 0x29 ) */ 44 | 0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00, 45 | 46 | 0x00,0x00,0x00,0x00,0x00,0x10,0x54,0x28, /* 0x2a * */ 47 | 0x28,0x54,0x10,0x00,0x00,0x00,0x00,0x00, 48 | 49 | 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10, /* 0x2b + */ 50 | 0x7c,0x10,0x10,0x00,0x00,0x00,0x00,0x00, 51 | 52 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x2c , */ 53 | 0x00,0x00,0x30,0x30,0x10,0x20,0x00,0x00, 54 | 55 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x2d - */ 56 | 0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 57 | 58 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x2e . */ 59 | 0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00, 60 | 61 | 0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x08, /* 0x2f / */ 62 | 0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00, 63 | 64 | 0x00,0x00,0x00,0x00,0x3a,0x44,0x4c,0x54, /* 0x30 0 */ 65 | 0x54,0x64,0x44,0xb8,0x00,0x00,0x00,0x00, 66 | 67 | 0x00,0x00,0x00,0x00,0x10,0x30,0x10,0x10, /* 0x31 1 */ 68 | 0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, 69 | 70 | 0x00,0x00,0x00,0x00,0x38,0x44,0x04,0x08, /* 0x32 2 */ 71 | 0x10,0x20,0x40,0x7c,0x00,0x00,0x00,0x00, 72 | 73 | 0x00,0x00,0x00,0x00,0x38,0x44,0x04,0x18, /* 0x33 3 */ 74 | 0x04,0x04,0x44,0x38,0x00,0x00,0x00,0x00, 75 | 76 | 0x00,0x00,0x00,0x00,0x04,0x0c,0x14,0x24, /* 0x34 4 */ 77 | 0x7e,0x04,0x04,0x04,0x00,0x00,0x00,0x00, 78 | 79 | 0x00,0x00,0x00,0x00,0x7c,0x40,0x40,0x78, /* 0x35 5 */ 80 | 0x04,0x04,0x08,0x70,0x00,0x00,0x00,0x00, 81 | 82 | 0x00,0x00,0x00,0x00,0x18,0x20,0x40,0x78, /* 0x36 6 */ 83 | 0x44,0x44,0x44,0x38,0x00,0x00,0x00,0x00, 84 | 85 | 0x00,0x00,0x00,0x00,0x7c,0x04,0x08,0x08, /* 0x37 7 */ 86 | 0x10,0x10,0x20,0x20,0x00,0x00,0x00,0x00, 87 | 88 | 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x38, /* 0x38 8 */ 89 | 0x44,0x44,0x44,0x38,0x00,0x00,0x00,0x00, 90 | 91 | 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x44, /* 0x39 9 */ 92 | 0x3c,0x04,0x08,0x30,0x00,0x00,0x00,0x00, 93 | 94 | 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30, /* 0x3a : */ 95 | 0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00, 96 | 97 | 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30, /* 0x3b ; */ 98 | 0x00,0x00,0x30,0x30,0x10,0x20,0x00,0x00, 99 | 100 | 0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x20, /* 0x3c < */ 101 | 0x40,0x20,0x10,0x08,0x00,0x00,0x00,0x00, 102 | 103 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c, /* 0x3d = */ 104 | 0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00, 105 | 106 | 0x00,0x00,0x00,0x00,0x00,0x20,0x10,0x08, /* 0x3e > */ 107 | 0x04,0x08,0x10,0x20,0x00,0x00,0x00,0x00, 108 | 109 | 0x00,0x00,0x00,0x38,0x44,0x44,0x04,0x08, /* 0x3f ? */ 110 | 0x10,0x10,0x00,0x10,0x00,0x00,0x00,0x00, 111 | 112 | 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x9a, /* 0x40 @ */ 113 | 0xaa,0xaa,0x9c,0x40,0x38,0x00,0x00,0x00, 114 | 115 | 0x00,0x00,0x00,0x38,0x44,0x82,0x82,0xfe, /* 0x41 A */ 116 | 0x82,0x82,0x82,0x82,0x00,0x00,0x00,0x00, 117 | 118 | 0x00,0x00,0x00,0xf8,0x84,0x84,0xfc,0x82, /* 0x42 B */ 119 | 0x82,0x82,0x82,0xfc,0x00,0x00,0x00,0x00, 120 | 121 | 0x00,0x00,0x00,0x3c,0x42,0x80,0x80,0x80, /* 0x43 C */ 122 | 0x80,0x80,0x42,0x3c,0x00,0x00,0x00,0x00, 123 | 124 | 0x00,0x00,0x00,0xf0,0x88,0x84,0x84,0x84, /* 0x44 D */ 125 | 0x84,0x84,0x88,0xf0,0x00,0x00,0x00,0x00, 126 | 127 | 0x00,0x00,0x00,0xfe,0x80,0x80,0x80,0xf8, /* 0x45 E */ 128 | 0x80,0x80,0x80,0xfe,0x00,0x00,0x00,0x00, 129 | 130 | 0x00,0x00,0x00,0xfe,0x80,0x80,0x80,0xf0, /* 0x46 F */ 131 | 0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00, 132 | 133 | 0x00,0x00,0x00,0x3c,0x42,0x80,0x80,0x80, /* 0x47 G */ 134 | 0x8e,0x82,0x42,0x3c,0x00,0x00,0x00,0x00, 135 | 136 | 0x00,0x00,0x00,0x82,0x82,0x82,0x82,0xfe, /* 0x48 H */ 137 | 0x82,0x82,0x82,0x82,0x00,0x00,0x00,0x00, 138 | 139 | 0x00,0x00,0x00,0x7c,0x10,0x10,0x10,0x10, /* 0x49 I */ 140 | 0x10,0x10,0x10,0x7c,0x00,0x00,0x00,0x00, 141 | 142 | 0x00,0x00,0x00,0x3e,0x08,0x08,0x08,0x08, /* 0x4a J */ 143 | 0x08,0x08,0x88,0x70,0x00,0x00,0x00,0x00, 144 | 145 | 0x00,0x00,0x00,0x82,0x84,0x88,0x90,0xa0, /* 0x4b K */ 146 | 0xd0,0x88,0x84,0x82,0x00,0x00,0x00,0x00, 147 | 148 | 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80, /* 0x4c L */ 149 | 0x80,0x80,0x80,0xfe,0x00,0x00,0x00,0x00, 150 | 151 | 0x00,0x00,0x00,0x82,0xc6,0xaa,0x92,0x82, /* 0x4d M */ 152 | 0x82,0x82,0x82,0x82,0x00,0x00,0x00,0x00, 153 | 154 | 0x00,0x00,0x00,0x82,0xc2,0xa2,0xa2,0x92, /* 0x4e N */ 155 | 0x8a,0x8a,0x86,0x82,0x00,0x00,0x00,0x00, 156 | 157 | 0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82, /* 0x4f O */ 158 | 0x82,0x82,0x44,0x38,0x00,0x00,0x00,0x00, 159 | 160 | 0x00,0x00,0x00,0xfc,0x82,0x82,0x82,0xfc, /* 0x50 P */ 161 | 0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00, 162 | 163 | 0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82, /* 0x51 Q */ 164 | 0x82,0x82,0x44,0x38,0x10,0x0c,0x00,0x00, 165 | 166 | 0x00,0x00,0x00,0xfc,0x82,0x82,0x82,0xfc, /* 0x52 R */ 167 | 0x90,0x88,0x84,0x82,0x00,0x00,0x00,0x00, 168 | 169 | 0x00,0x00,0x00,0x7c,0x82,0x80,0x80,0x7c, /* 0x53 S */ 170 | 0x02,0x02,0x82,0x7c,0x00,0x00,0x00,0x00, 171 | 172 | 0x00,0x00,0x00,0xfe,0x10,0x10,0x10,0x10, /* 0x54 T */ 173 | 0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, 174 | 175 | 0x00,0x00,0x00,0x82,0x82,0x82,0x82,0x82, /* 0x55 U */ 176 | 0x82,0x82,0x82,0x7c,0x00,0x00,0x00,0x00, 177 | 178 | 0x00,0x00,0x00,0x82,0x82,0x44,0x44,0x44, /* 0x56 V */ 179 | 0x28,0x28,0x10,0x10,0x00,0x00,0x00,0x00, 180 | 181 | 0x00,0x00,0x00,0x82,0x82,0x82,0x92,0x92, /* 0x57 W */ 182 | 0x92,0x92,0xaa,0x44,0x00,0x00,0x00,0x00, 183 | 184 | 0x00,0x00,0x00,0x82,0x82,0x44,0x28,0x10, /* 0x58 X */ 185 | 0x28,0x44,0x82,0x82,0x00,0x00,0x00,0x00, 186 | 187 | 0x00,0x00,0x00,0x82,0x82,0x44,0x28,0x10, /* 0x59 Y */ 188 | 0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, 189 | 190 | 0x00,0x00,0x00,0xfe,0x82,0x04,0x08,0x10, /* 0x5a Z */ 191 | 0x20,0x40,0x82,0xfe,0x00,0x00,0x00,0x00, 192 | 193 | 0x00,0x00,0x00,0x0e,0x08,0x08,0x08,0x08, /* 0x5b [ */ 194 | 0x08,0x08,0x08,0x08,0x0e,0x00,0x00,0x00, 195 | 196 | 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40, /* 0x5c \ */ 197 | 0x20,0x10,0x08,0x04,0x02,0x00,0x00,0x00, 198 | 199 | 0x00,0x00,0x00,0xe0,0x20,0x20,0x20,0x20, /* 0x5d ] */ 200 | 0x20,0x20,0x20,0x20,0xe0,0x00,0x00,0x00, 201 | 202 | 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00, /* 0x5e ^ */ 203 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 204 | 205 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x5f _ */ 206 | 0x00,0x00,0x00,0x00,0x00,0xfe,0x00,0x00, 207 | 208 | 0x00,0x40,0x20,0x10,0x00,0x00,0x00,0x00, /* 0x60 ` */ 209 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 210 | 211 | 0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x04, /* 0x61 a */ 212 | 0x7c,0x84,0x84,0x7a,0x00,0x00,0x00,0x00, 213 | 214 | 0x00,0x00,0x00,0x80,0x80,0x80,0xb8,0xc4, /* 0x62 b */ 215 | 0x82,0x82,0xc4,0xb8,0x00,0x00,0x00,0x00, 216 | 217 | 0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x42, /* 0x63 c */ 218 | 0x80,0x80,0x42,0x3c,0x00,0x00,0x00,0x00, 219 | 220 | 0x00,0x00,0x00,0x02,0x02,0x02,0x3a,0x46, /* 0x64 d */ 221 | 0x82,0x82,0x46,0x3a,0x00,0x00,0x00,0x00, 222 | 223 | 0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x42, /* 0x65 e */ 224 | 0xfe,0x80,0x40,0x3e,0x00,0x00,0x00,0x00, 225 | 226 | 0x00,0x00,0x00,0x0c,0x12,0x10,0x38,0x10, /* 0x66 f */ 227 | 0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, 228 | 229 | 0x00,0x00,0x00,0x00,0x00,0x00,0x7a,0x84, /* 0x67 g */ 230 | 0x84,0x78,0x80,0x7c,0x82,0x7c,0x00,0x00, 231 | 232 | 0x00,0x00,0x00,0xc0,0x40,0x40,0x5c,0x62, /* 0x68 h */ 233 | 0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00, 234 | 235 | 0x00,0x00,0x00,0x10,0x00,0x00,0x30,0x10, /* 0x69 i */ 236 | 0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, 237 | 238 | 0x00,0x00,0x00,0x10,0x00,0x00,0x30,0x10, /* 0x6a j */ 239 | 0x10,0x10,0x10,0x10,0x10,0x10,0x60,0x00, 240 | 241 | 0x00,0x00,0x00,0xc0,0x40,0x40,0x4c,0x50, /* 0x6b k */ 242 | 0x60,0x50,0x48,0xc6,0x00,0x00,0x00,0x00, 243 | 244 | 0x00,0x00,0x00,0x30,0x10,0x10,0x10,0x10, /* 0x6c l */ 245 | 0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, 246 | 247 | 0x00,0x00,0x00,0x00,0x00,0x00,0xec,0x92, /* 0x6d m */ 248 | 0x92,0x92,0x92,0x92,0x00,0x00,0x00,0x00, 249 | 250 | 0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0x62, /* 0x6e n */ 251 | 0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00, 252 | 253 | 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x44, /* 0x6f o */ 254 | 0x82,0x82,0x44,0x38,0x00,0x00,0x00,0x00, 255 | 256 | 0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0xc4, /* 0x70 p */ 257 | 0x82,0x82,0xc4,0xb8,0x80,0x80,0x80,0x00, 258 | 259 | 0x00,0x00,0x00,0x00,0x00,0x00,0x3a,0x46, /* 0x71 q */ 260 | 0x82,0x82,0x46,0x3a,0x02,0x02,0x02,0x00, 261 | 262 | 0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0x62, /* 0x72 r */ 263 | 0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00, 264 | 265 | 0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x80, /* 0x73 s */ 266 | 0x7c,0x02,0x82,0x7c,0x00,0x00,0x00,0x00, 267 | 268 | 0x00,0x00,0x00,0x20,0x20,0x20,0xfc,0x20, /* 0x74 t */ 269 | 0x20,0x20,0x20,0x1c,0x00,0x00,0x00,0x00, 270 | 271 | 0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x84, /* 0x75 u */ 272 | 0x84,0x84,0x84,0x7a,0x00,0x00,0x00,0x00, 273 | 274 | 0x00,0x00,0x00,0x00,0x00,0x00,0xc6,0x44, /* 0x76 v */ 275 | 0x28,0x28,0x10,0x10,0x00,0x00,0x00,0x00, 276 | 277 | 0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x92, /* 0x77 w */ 278 | 0x92,0x92,0xaa,0x44,0x00,0x00,0x00,0x00, 279 | 280 | 0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0x24, /* 0x78 x */ 281 | 0x18,0x18,0x24,0x42,0x00,0x00,0x00,0x00, 282 | 283 | 0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x82, /* 0x79 y */ 284 | 0x82,0x44,0x28,0x10,0x20,0x40,0x80,0x00, 285 | 286 | 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x88, /* 0x7a z */ 287 | 0x10,0x20,0x44,0xfc,0x00,0x00,0x00,0x00, 288 | 289 | 0x00,0x00,0x00,0x06,0x08,0x08,0x08,0x08, /* 0x7b { */ 290 | 0x10,0x08,0x08,0x08,0x08,0x06,0x00,0x00, 291 | 292 | 0x00,0x00,0x00,0x38,0x38,0x38,0x38,0x00, /* 0x7c | */ 293 | 0x38,0x38,0x38,0x38,0x00,0x00,0x00,0x00, 294 | 295 | 0x00,0x00,0x00,0xc0,0x20,0x20,0x20,0x20, /* 0x7d } */ 296 | 0x10,0x20,0x20,0x20,0x20,0xc0,0x00,0x00, 297 | 298 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x7e ~ */ 299 | 0x32,0x4c,0x00,0x00,0x00,0x00,0x00,0x00, 300 | 301 | 0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c, /* 0x7f box */ 302 | 0x7c,0x7c,0x00,0x00,0x00,0x00,0x00,0x00, 303 | 304 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xa0 space */ 305 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 306 | 307 | 0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x08, /* 0xa1 ! = slant */ 308 | 0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00, 309 | 310 | 0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x00, /* 0xa2 " = equivalent */ 311 | 0x7c,0x00,0x7c,0x00,0x00,0x00,0x00,0x00, 312 | 313 | 0x00,0x00,0x32,0x4c,0x00,0x00,0x00,0x00, /* 0xa3 # = tilde */ 314 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 315 | 316 | 0x00,0x00,0x00,0x00,0x00,0x10,0x30,0x5e, /* 0xa4 $ = assignment */ 317 | 0x80,0x5e,0x30,0x10,0x00,0x00,0x00,0x00, 318 | 319 | 0x00,0x00,0x00,0x00,0x00,0x02,0x04,0xfe, /* 0xa5 % = not equal */ 320 | 0x10,0xfe,0x40,0x80,0x00,0x00,0x00,0x00, 321 | 322 | 0x00,0x00,0x00,0x00,0x00,0x10,0x38,0x7c, /* 0xa6 & = up arrow */ 323 | 0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, 324 | 325 | 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x0c, /* 0xa7 ' = right arrow */ 326 | 0xfe,0x0c,0x08,0x00,0x00,0x00,0x00,0x00, 327 | 328 | 0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10, /* 0xa8 ( = down arrow */ 329 | 0x10,0x7c,0x38,0x10,0x00,0x00,0x00,0x00, 330 | 331 | 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x60, /* 0xa9 ) = left arrow */ 332 | 0xfe,0x60,0x20,0x00,0x00,0x00,0x00,0x00, 333 | 334 | 0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x18, /* 0xaa * = multiply */ 335 | 0x18,0x24,0x00,0x00,0x00,0x00,0x00,0x00, 336 | 337 | 0x00,0x00,0x00,0xfe,0x40,0x20,0x10,0x08, /* 0xab + = cap sigma */ 338 | 0x10,0x20,0x40,0xfe,0x00,0x00,0x00,0x00, 339 | 340 | 0x00,0x00,0x00,0x00,0x10,0x10,0x28,0x28, /* 0xac , = cap delta */ 341 | 0x44,0x44,0x82,0xfe,0x00,0x00,0x00,0x00, 342 | 343 | 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x44, /* 0xad - = union */ 344 | 0x44,0x38,0x00,0x00,0x00,0x00,0x00,0x00, 345 | 346 | 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x44, /* 0xae . = intersection */ 347 | 0x44,0x44,0x00,0x00,0x00,0x00,0x00,0x00, 348 | 349 | 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00, /* 0xaf / = divide */ 350 | 0x7c,0x00,0x10,0x00,0x00,0x00,0x00,0x00, 351 | 352 | 0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x92, /* 0xb0 0 = alpha */ 353 | 0x94,0x88,0x98,0x66,0x00,0x00,0x00,0x00, 354 | 355 | 0x00,0x00,0x00,0x00,0x18,0x24,0x44,0x78, /* 0xb1 1 = beta */ 356 | 0x44,0x42,0x42,0x7c,0x40,0x40,0x80,0x00, 357 | 358 | 0x00,0x00,0x00,0x30,0x48,0x44,0x20,0x30, /* 0xb2 2 = delta */ 359 | 0x48,0x44,0x44,0x38,0x00,0x00,0x00,0x00, 360 | 361 | 0x00,0x00,0x00,0x40,0x20,0x20,0x10,0x10, /* 0xb3 3 = lambda */ 362 | 0x28,0x28,0x44,0x44,0x00,0x00,0x00,0x00, 363 | 364 | 0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x24, /* 0xb4 4 = micro */ 365 | 0x24,0x24,0x24,0x3a,0x20,0x20,0xc0,0x00, 366 | 367 | 0x00,0x00,0x00,0x00,0x00,0x02,0x7c,0xa8, /* 0xb5 5 = pi */ 368 | 0x28,0x28,0x28,0x28,0x00,0x00,0x00,0x00, 369 | 370 | 0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x12, /* 0xb6 6 = rho */ 371 | 0x22,0x22,0x64,0x58,0x40,0x80,0x80,0x00, 372 | 373 | 0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x50, /* 0xb7 7 = sigma */ 374 | 0x88,0x88,0x88,0x70,0x00,0x00,0x00,0x00, 375 | 376 | 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x82, /* 0xb8 8 = omega */ 377 | 0x92,0x92,0x92,0x6c,0x00,0x00,0x00,0x00, 378 | 379 | 0x00,0x00,0x00,0x00,0x0c,0x30,0xc0,0x30, /* 0xb9 9 = less than or equal */ 380 | 0x0c,0x00,0xfc,0x00,0x00,0x00,0x00,0x00, 381 | 382 | 0x00,0x00,0x00,0x00,0x60,0x18,0x06,0x18, /* 0xba : = greater than or equal */ 383 | 0x60,0x00,0x7e,0x00,0x00,0x00,0x00,0x00, 384 | 385 | 0x00,0x00,0x00,0x38,0x44,0x82,0x82,0xfe, /* 0xbb ; = cap theta */ 386 | 0x82,0x82,0x44,0x38,0x00,0x00,0x00,0x00, 387 | 388 | 0x00,0x00,0x00,0x02,0x04,0x08,0x18,0x28, /* 0xbc < = left embed */ 389 | 0x48,0x28,0x18,0x0c,0x02,0x00,0x00,0x00, 390 | 391 | 0x00,0x00,0x00,0x30,0x48,0x48,0x30,0x00, /* 0xbd = = degree */ 392 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 393 | 394 | 0x00,0x00,0x00,0x80,0x40,0x20,0x30,0x28, /* 0xbe > = right embed */ 395 | 0x24,0x28,0x30,0x60,0x80,0x00,0x00,0x00, 396 | 397 | 0x00,0x00,0x00,0xc0,0xa0,0x90,0x48,0x24, /* 0xbf ? = arrow */ 398 | 0x12,0x24,0x48,0x90,0xa0,0xc0,0x00,0x00, 399 | 400 | 0x00,0x00,0xfe,0x00,0x00,0x3c,0x42,0x80, /* 0xc0 @ = center of copyright */ 401 | 0x80,0x42,0x3c,0x00,0x00,0xfe,0x00,0x00, 402 | 403 | 0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00, /* 0xc1 A = umlaut */ 404 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 405 | 406 | 0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x44, /* 0xc2 B = box */ 407 | 0x44,0x7c,0x00,0x00,0x00,0x00,0x00,0x00, 408 | 409 | 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x48, /* 0xc3 C = dot product */ 410 | 0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00, 411 | 412 | 0x00,0x00,0x00,0x00,0x00,0x10,0x38,0x7c, /* 0xc4 D = diamond */ 413 | 0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00, 414 | 415 | 0x00,0x00,0x00,0x00,0x00,0x82,0x44,0x28, /* 0xc5 E = cross product */ 416 | 0x10,0x28,0x44,0x82,0x00,0x00,0x00,0x00, 417 | 418 | 0x00,0x04,0x08,0x10,0x00,0x00,0x00,0x00, /* 0xc6 F = acute accent */ 419 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 420 | 421 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc7 G = cedilla */ 422 | 0x00,0x00,0x00,0x04,0x08,0x10,0x00,0x00, 423 | 424 | 0x00,0x44,0x28,0x10,0x00,0x00,0x00,0x00, /* 0xc8 H = hacek */ 425 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 426 | 427 | 0x00,0x00,0x00,0x00,0x00,0x10,0x38,0x7c, /* 0xc9 I = universal separator */ 428 | 0x10,0x7c,0x38,0x10,0x00,0x00,0x00,0x00, 429 | 430 | 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10, /* 0xca J = vertical bar */ 431 | 0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, 432 | 433 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcb K */ 434 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 435 | 436 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcc L */ 437 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 438 | 439 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcd M */ 440 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 441 | 442 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xce N */ 443 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 444 | 445 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcf O */ 446 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 447 | 448 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd0 P */ 449 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 450 | 451 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd1 Q */ 452 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 453 | 454 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd2 R */ 455 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 456 | 457 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd3 S */ 458 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 459 | 460 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd4 T */ 461 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 462 | 463 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd5 U */ 464 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 465 | 466 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd6 V */ 467 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 468 | 469 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd7 W */ 470 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 471 | 472 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd8 X */ 473 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 474 | 475 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd9 Y */ 476 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 477 | 478 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xda Z */ 479 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 480 | 481 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xdb [ */ 482 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 483 | 484 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xdc \ */ 485 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 486 | 487 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xdd ] */ 488 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 489 | 490 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xde ^ */ 491 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 492 | 493 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xdf _ */ 494 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 495 | }; 496 | 497 | #define FONTPTR(a) (a<<4) 498 | -------------------------------------------------------------------------------- /header: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * file.c - description 13 | */ 14 | -------------------------------------------------------------------------------- /io.c: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * io.c - I/O functions 13 | */ 14 | 15 | #include 16 | #include 17 | #include "io.h" 18 | #include "protocol.h" 19 | 20 | #define TRUE 1 21 | #define FALSE 0 22 | 23 | int buflen; 24 | 25 | int net; 26 | 27 | extern int done; 28 | 29 | /** 30 | * io_init() - Set-up the I/O 31 | */ 32 | void io_init(char* hostname, char* port) 33 | { 34 | net = dial(netmkaddr(hostname,"tcp",port),0,0,0); 35 | 36 | if (net < 0) 37 | done=TRUE; 38 | } 39 | 40 | /** 41 | * io_send_byte(b) - Send specified byte out 42 | */ 43 | void io_send_byte(unsigned char b) 44 | { 45 | write(net, &b, 1); 46 | } 47 | 48 | /** 49 | * io_main() - The IO event 50 | */ 51 | void io_main(uchar *data, int n) 52 | { 53 | ShowPLATO((padByte *)data,n); 54 | } 55 | 56 | /** 57 | * io_done() - Called to close I/O 58 | */ 59 | void io_done() 60 | { 61 | close(net); 62 | } 63 | -------------------------------------------------------------------------------- /io.h: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * io.h - I/O functions 13 | */ 14 | 15 | #ifndef IO_H 16 | #define IO_H 17 | 18 | #define XON 0x11 19 | #define XOFF 0x13 20 | 21 | /** 22 | * io_init() - Set-up the I/O 23 | */ 24 | void io_init(char* hostname, char* port); 25 | 26 | /** 27 | * io_send_byte(b) - Send specified byte out 28 | */ 29 | void io_send_byte(unsigned char b); 30 | 31 | /** 32 | * io_main() - The IO main loop 33 | */ 34 | void io_main(unsigned char *data, int n); 35 | 36 | /** 37 | * io_done() - Called to close I/O 38 | */ 39 | void io_done(void); 40 | 41 | #endif /* IO_H */ 42 | -------------------------------------------------------------------------------- /key.h: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * key.h - Generated key definitions 13 | */ 14 | 15 | #include "plato_key.h" 16 | 17 | -------------------------------------------------------------------------------- /keyboard.c: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * keyboard.c - Keyboard functions 13 | */ 14 | 15 | #include 16 | #include 17 | #include "keyboard.h" 18 | #include "protocol.h" 19 | #include "key.h" 20 | 21 | #define TRUE 1 22 | #define FALSE 0 23 | 24 | unsigned char ch; 25 | 26 | /* ACCESS Key combinations. */ 27 | unsigned char ACCESS_KEYS[] = { 28 | PKEY_a, /* 0x80 a ɑ alpha */ 29 | PKEY_B, /* 0x81 b ß beta */ 30 | PKEY_c, /* 0x82 c cedilla */ 31 | PKEY_d, /* 0x83 d δ delta */ 32 | PKEY_e, /* 0x84 e ' acute accent */ 33 | PKEY_g, /* 0x85 g æ ae */ 34 | PKEY_h, /* 0x86 h oe oe */ 35 | PKEY_j, /* 0x87 j å a with ring */ 36 | PKEY_k, /* 0x88 k ä a with diaeresis */ 37 | PKEY_l, /* 0x89 l ƛ lambda */ 38 | PKEY_m, /* 0x8A m μ mu */ 39 | PKEY_n, /* 0x8B n ~ tilde */ 40 | PKEY_o, /* 0x8C o ° degree */ 41 | PKEY_p, /* 0x8D p π pi */ 42 | 0x51, /* 0x8E q ` grave */ 43 | PKEY_r, /* 0x8F r ρ rho */ 44 | PKEY_s, /* 0x90 s σ sigma */ 45 | PKEY_t, /* 0x91 t θ theta */ 46 | PKEY_u, /* 0x92 u ¨ diaeresis */ 47 | PKEY_v, /* 0x93 v hacek (upside down circumflex) */ 48 | PKEY_w, /* 0x94 w ϖ capital pi */ 49 | PKEY_x, /* 0x95 x ^ circumflex */ 50 | PKEY_0, /* 0x96 0 l-embed */ 51 | PKEY_1, /* 0x97 1 r-embed */ 52 | PKEY_5, /* 0x98 5 @ */ 53 | PKEY_6, /* 0x99 6 arrow */ 54 | PKEY_PLUS, /* 0x9a + & */ 55 | 0x26, /* 0x9b & interpunct */ 56 | PKEY_COLON, /* 0x9c : ~ lower tilde */ 57 | 0x5f, /* 0x9d , delimiter */ 58 | PKEY_SLASH, /* 0x9e / \ */ 59 | PKEY_EQUALS, /* 0x9f = not equal */ 60 | PKEY_y, /* 0xA0 y ö */ 61 | 0x61, /* 0xA1 A left arrow */ 62 | 0x78, /* 0xA2 X down arrow */ 63 | 0x64, /* 0xA3 D right arrow */ 64 | 0x77, /* 0xA4 W up arrow */ 65 | 0x63, /* 0xA5 C © */ 66 | 0x66, /* 0xA6 F ♦ */ 67 | 0x67, /* 0xA7 G Æ */ 68 | 0x68, /* 0xA8 H OE */ 69 | 0x69, /* 0xA9 I | */ 70 | 0x6A, /* 0xAA J Å */ 71 | 0x6B, /* 0xAB K Ä */ 72 | 0x6F, /* 0xAC O SQUARE */ 73 | 0x79, /* 0xAD Y Ö */ 74 | 0x20, /* 0xAE < ≤ */ 75 | 0x21, /* 0xAF > ≥ */ 76 | 0x5B, /* 0xB0 [ { */ 77 | PKEY_SLASH, /* 0xB1 ] } */ 78 | 0x24, /* 0xB2 $ # */ 79 | 0x9a, /* 0xB3 & big cross */ 80 | 0x7B /* 0xB4 EQUIVALENT */ 81 | }; 82 | 83 | void keyboard_out(unsigned char platoKey) 84 | { 85 | if (platoKey==0xff) 86 | return; 87 | 88 | if (platoKey>0x7F) 89 | { 90 | Key(ACCESS); 91 | Key(ACCESS_KEYS[platoKey-0x80]); 92 | return; 93 | } 94 | Key(platoKey); 95 | } 96 | 97 | void keyboard_main(int k) 98 | { 99 | unsigned char outk=0xff; 100 | 101 | switch(k) 102 | { 103 | case 0x01: // ctrl-A 104 | outk=PKEY_ANS; 105 | break; 106 | case 0x02: // ctrl-B 107 | outk=PKEY_BACK; 108 | break; 109 | case 0x03: // ctrl-C 110 | outk=PKEY_COPY; 111 | break; 112 | case 0x04: // ctrl-D 113 | outk=PKEY_DATA; 114 | break; 115 | case 0x05: // ctrl-E 116 | outk=PKEY_EDIT; 117 | break; 118 | case 0x06: // ctrl-F 119 | outk=PKEY_FONT; 120 | break; 121 | case 0x07: // ctrl-G 122 | outk=PKEY_DIVIDE; 123 | break; 124 | case 0x08: // ctrl-H 125 | outk=PKEY_ERASE; 126 | break; 127 | case 0x09: // ctrl-I 128 | break; 129 | case 0x0a: // ctrl 130 | outk=PKEY_NEXT; 131 | break; 132 | case 0x0b: // ctrl-K 133 | break; 134 | case 0x0c: // ctrl-L 135 | outk=PKEY_LAB; 136 | break; 137 | case 0x0d: // ctrl-M 138 | outk=PKEY_NEXT; 139 | break; 140 | case 0x0e: // ctrl-N 141 | outk=PKEY_NEXT1; 142 | break; 143 | case 0x0f: // ctrl-O 144 | break; 145 | case 0x10: // ctrl-P 146 | outk=PKEY_SUPER; 147 | break; 148 | case 0x11: // ctrl-Q 149 | outk=PKEY_SQUARE; 150 | break; 151 | case 0x12: // ctrl-R 152 | outk=PKEY_ERASE; 153 | break; 154 | case 0x13: // ctrl-S 155 | outk=PKEY_STOP; 156 | break; 157 | case 0x14: // ctrl-T 158 | outk=PKEY_TERM; 159 | break; 160 | case 0x15: // ctrl-U 161 | break; 162 | case 0x16: // ctrl-V 163 | break; 164 | case 0x17: // ctrl-W 165 | break; 166 | case 0x18: // ctrl-X 167 | outk=PKEY_MULTIPLY; 168 | break; 169 | case 0x19: // ctrl-Y 170 | outk=PKEY_SUB; 171 | break; 172 | case 0x1a: // ctrl-Z 173 | break; 174 | case 0x1b: // ESC 175 | outk=PKEY_ASSIGN; 176 | break; 177 | case 0x1c: 178 | break; 179 | case 0x1d: 180 | break; 181 | case 0x1e: 182 | break; 183 | case 0x1f: 184 | break; 185 | case 0x20: 186 | outk=PKEY_SPACE; 187 | break; 188 | case 0x21: // ! 189 | outk=PKEY_EXCLAMATION; 190 | break; 191 | case 0x22: // " 192 | outk=PKEY_QUOTE; 193 | break; 194 | case 0x23: // # 195 | outk=PKEY_POUND; 196 | break; 197 | case 0x24: // $ 198 | outk=PKEY_DOLLAR; 199 | break; 200 | case 0x25: // % 201 | outk=PKEY_PERCENT; 202 | break; 203 | case 0x26: // & 204 | outk=PKEY_AMPERSAND; 205 | break; 206 | case 0x27: // ' 207 | outk=PKEY_APOSTROPHE; 208 | break; 209 | case 0x28: // ( 210 | outk=PKEY_PARENTHESIS_LEFT; 211 | break; 212 | case 0x29: // ) 213 | outk=PKEY_PARENTHESIS_RIGHT; 214 | break; 215 | case 0x2A: // * 216 | outk=PKEY_ASTERISK; 217 | break; 218 | case 0x2B: // + 219 | outk=PKEY_PLUS; 220 | break; 221 | case 0x2C: // , 222 | outk=PKEY_COMMA; 223 | break; 224 | case 0x2D: // - 225 | outk=PKEY_MINUS; 226 | break; 227 | case 0x2E: // . 228 | outk=PKEY_PERIOD; 229 | break; 230 | case 0x2F: // / 231 | outk=PKEY_SLASH; 232 | break; 233 | case 0x30: // 0 234 | outk=PKEY_0; 235 | break; 236 | case 0x31: // 1 237 | outk=PKEY_1; 238 | break; 239 | case 0x32: // 2 240 | outk=PKEY_2; 241 | break; 242 | case 0x33: // 3 243 | outk=PKEY_3; 244 | break; 245 | case 0x34: // 4 246 | outk=PKEY_4; 247 | break; 248 | case 0x35: // 5 249 | outk=PKEY_5; 250 | break; 251 | case 0x36: // 6 252 | outk=PKEY_6; 253 | break; 254 | case 0x37: // 7 255 | outk=PKEY_7; 256 | break; 257 | case 0x38: // 8 258 | outk=PKEY_8; 259 | break; 260 | case 0x39: // 9 261 | outk=PKEY_9; 262 | break; 263 | case 0x3A: // : 264 | outk=PKEY_COLON; 265 | break; 266 | case 0x3B: // ; 267 | outk=PKEY_SEMICOLON; 268 | break; 269 | case 0x3C: // < 270 | outk=PKEY_LESS_THAN; 271 | break; 272 | case 0x3D: // = 273 | outk=PKEY_EQUALS; 274 | break; 275 | case 0x3E: // > 276 | outk=PKEY_GREATER_THAN; 277 | break; 278 | case 0x3F: // ? 279 | outk=PKEY_QUESTION_MARK; 280 | break; 281 | case 0x40: // @ 282 | outk=PKEY_AT; 283 | break; 284 | case 'A': // A 285 | outk=PKEY_A; 286 | break; 287 | case 'B': // B 288 | outk=PKEY_B; 289 | break; 290 | case 'C': // C 291 | outk=PKEY_C; 292 | break; 293 | case 'D': // D 294 | outk=PKEY_D; 295 | break; 296 | case 'E': // E 297 | outk=PKEY_E; 298 | break; 299 | case 'F': // F 300 | outk=PKEY_F; 301 | break; 302 | case 'G': // G 303 | outk=PKEY_G; 304 | break; 305 | case 'H': // H 306 | outk=PKEY_H; 307 | break; 308 | case 'I': // I 309 | outk=PKEY_I; 310 | break; 311 | case 'J': // J 312 | outk=PKEY_J; 313 | break; 314 | case 'K': // K 315 | outk=PKEY_K; 316 | break; 317 | case 'L': // L 318 | outk=PKEY_L; 319 | break; 320 | case 'M': // M 321 | outk=PKEY_M; 322 | break; 323 | case 'N': // N 324 | outk=PKEY_N; 325 | break; 326 | case 'O': // O 327 | outk=PKEY_O; 328 | break; 329 | case 'P': // P 330 | outk=PKEY_P; 331 | break; 332 | case 'Q': // Q 333 | outk=PKEY_Q; 334 | break; 335 | case 'R': // R 336 | outk=PKEY_R; 337 | break; 338 | case 'S': // S 339 | outk=PKEY_S; 340 | break; 341 | case 'T': // T 342 | outk=PKEY_T; 343 | break; 344 | case 'U': // U 345 | outk=PKEY_U; 346 | break; 347 | case 'V': // V 348 | outk=PKEY_V; 349 | break; 350 | case 'W': // W 351 | outk=PKEY_W; 352 | break; 353 | case 'X': // X 354 | outk=PKEY_X; 355 | break; 356 | case 'Y': // Y 357 | outk=PKEY_Y; 358 | break; 359 | case 'Z': // Z 360 | outk=PKEY_Z; 361 | break; 362 | case '[': // [ 363 | outk=PKEY_BRACKET_LEFT; 364 | break; 365 | case 0x5C: // backslash 366 | outk=PKEY_BACKSLASH; 367 | break; 368 | case ']': // ] 369 | outk=PKEY_BRACKET_RIGHT; 370 | break; 371 | case '^': // ^ 372 | outk=PKEY_CIRCUMFLEX; 373 | break; 374 | case '_': // _ 375 | outk=PKEY_UNDERSCORE; 376 | break; 377 | case '`': // ` 378 | outk=PKEY_GRAVE; 379 | break; 380 | case 'a': 381 | outk=PKEY_a; 382 | break; 383 | case 'b': 384 | outk=PKEY_b; 385 | break; 386 | case 'c': 387 | outk=PKEY_c; 388 | break; 389 | case 'd': 390 | outk=PKEY_d; 391 | break; 392 | case 'e': 393 | outk=PKEY_e; 394 | break; 395 | case 'f': 396 | outk=PKEY_f; 397 | break; 398 | case 'g': 399 | outk=PKEY_g; 400 | break; 401 | case 'h': 402 | outk=PKEY_h; 403 | break; 404 | case 'i': 405 | outk=PKEY_i; 406 | break; 407 | case 'j': 408 | outk=PKEY_j; 409 | break; 410 | case 'k': 411 | outk=PKEY_k; 412 | break; 413 | case 'l': 414 | outk=PKEY_l; 415 | break; 416 | case 'm': 417 | outk=PKEY_m; 418 | break; 419 | case 'n': 420 | outk=PKEY_n; 421 | break; 422 | case 'o': 423 | outk=PKEY_o; 424 | break; 425 | case 'p': 426 | outk=PKEY_p; 427 | break; 428 | case 'q': 429 | outk=PKEY_q; 430 | break; 431 | case 'r': 432 | outk=PKEY_r; 433 | break; 434 | case 's': 435 | outk=PKEY_s; 436 | break; 437 | case 't': 438 | outk=PKEY_t; 439 | break; 440 | case 'u': 441 | outk=PKEY_u; 442 | break; 443 | case 'v': 444 | outk=PKEY_v; 445 | break; 446 | case 'w': 447 | outk=PKEY_w; 448 | break; 449 | case 'x': 450 | outk=PKEY_x; 451 | break; 452 | case 'y': 453 | outk=PKEY_y; 454 | break; 455 | case 'z': 456 | outk=PKEY_z; 457 | break; 458 | case 0x7B: 459 | outk=PKEY_LEFT_CURLY_BRACE; 460 | break; 461 | case 0x7C: 462 | outk=PKEY_BAR; 463 | break; 464 | case 0x7D: 465 | outk=PKEY_RIGHT_CURLY_BRACE; 466 | break; 467 | case 0x7E: 468 | outk=PKEY_TILDE; 469 | break; 470 | case 0x7F: 471 | outk=PKEY_ERASE1; 472 | break; 473 | 474 | } 475 | 476 | keyboard_out(outk); 477 | } 478 | 479 | -------------------------------------------------------------------------------- /keyboard.h: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * keyboard.h - Keyboard functions 13 | */ 14 | 15 | #ifndef KEYBOARD_H 16 | #define KEYBOARD_H 17 | 18 | void keyboard_main(int k); 19 | #endif 20 | -------------------------------------------------------------------------------- /menu.c: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * menu.c - Menu functions 13 | */ 14 | 15 | #include 16 | #include 17 | #include "menu.h" 18 | #include "protocol.h" 19 | #include "plato_key.h" 20 | 21 | extern int done; 22 | extern void keyboard_out(unsigned char platoKey); 23 | 24 | #define TRUE 1 25 | #define FALSE 0 26 | 27 | void menu_right(int item) 28 | { 29 | switch (item) 30 | { 31 | case 0: // ANS 32 | keyboard_out(PKEY_ANS); 33 | break; 34 | case 1: // BACK 35 | keyboard_out(PKEY_BACK); 36 | break; 37 | case 2: // COPY 38 | keyboard_out(PKEY_COPY); 39 | break; 40 | case 3: // DATA 41 | keyboard_out(PKEY_DATA); 42 | break; 43 | case 4: // EDIT 44 | keyboard_out(PKEY_EDIT); 45 | break; 46 | case 5: // FONT 47 | keyboard_out(PKEY_FONT); 48 | break; 49 | case 6: // HELP 50 | keyboard_out(PKEY_HELP); 51 | break; 52 | case 7: // LAB 53 | keyboard_out(PKEY_LAB); 54 | break; 55 | case 8: // MICRO 56 | keyboard_out(PKEY_MICRO); 57 | break; 58 | case 9: // NEXT 59 | keyboard_out(PKEY_NEXT); 60 | break; 61 | case 10: // SQUARE 62 | keyboard_out(PKEY_SQUARE); 63 | break; 64 | case 11: // STOP 65 | keyboard_out(PKEY_STOP); 66 | break; 67 | case 12: // SUB 68 | keyboard_out(PKEY_SUB); 69 | break; 70 | case 13: // SUPER 71 | keyboard_out(PKEY_SUPER); 72 | break; 73 | case 14: // TERM 74 | keyboard_out(PKEY_TERM); 75 | break; 76 | case 15: // Multiply 77 | keyboard_out(PKEY_MULTIPLY); 78 | break; 79 | case 16: // Divide 80 | keyboard_out(PKEY_DIVIDE); 81 | break; 82 | case 17: // Sigma 83 | keyboard_out(PKEY_SIGMA); 84 | break; 85 | case 18: // Delta 86 | keyboard_out(PKEY_DELTA); 87 | break; 88 | case 19: // Quit 89 | done=TRUE; 90 | break; 91 | 92 | } 93 | } 94 | 95 | void menu_middle(int item) 96 | { 97 | switch (item) 98 | { 99 | case 0: 100 | keyboard_out(PKEY_BACK1); 101 | break; 102 | case 1: 103 | keyboard_out(PKEY_COPY1); 104 | break; 105 | case 2: 106 | keyboard_out(PKEY_DATA1); 107 | break; 108 | case 3: 109 | keyboard_out(PKEY_EDIT1); 110 | break; 111 | case 4: 112 | keyboard_out(PKEY_HELP1); 113 | break; 114 | case 5: 115 | keyboard_out(PKEY_LAB1); 116 | break; 117 | case 6: 118 | keyboard_out(PKEY_NEXT1); 119 | break; 120 | case 7: 121 | keyboard_out(PKEY_STOP1); 122 | break; 123 | case 8: 124 | keyboard_out(PKEY_SUB1); 125 | break; 126 | case 9: 127 | keyboard_out(PKEY_SUPER1); 128 | break; 129 | } 130 | } -------------------------------------------------------------------------------- /menu.h: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * menu.h - Menu functions 13 | */ 14 | 15 | #ifndef MENU_H 16 | #define MENU_H 17 | 18 | void menu_middle(int item); 19 | void menu_right(int item); 20 | 21 | #endif /* MENU_H */ -------------------------------------------------------------------------------- /mkfile: -------------------------------------------------------------------------------- 1 | < /$objtype/mkfile 2 | 3 | TARG=platoterm 4 | OFILES=\ 5 | io.$O \ 6 | keyboard.$O \ 7 | menu.$O \ 8 | platoterm.$O \ 9 | protocol.$O \ 10 | screen.$O \ 11 | terminal.$O \ 12 | touch.$O 13 | 14 | HFILES=\ 15 | font.h \ 16 | io.h \ 17 | key.h \ 18 | keyboard.h \ 19 | menu.h \ 20 | plato_key.h \ 21 | protocol.h \ 22 | screen.h \ 23 | splash.h \ 24 | terminal.h \ 25 | touch.h 26 | 27 | BIN=/$objtype/bin 28 | 9 | * 10 | * License: GPL 3.0 11 | * 12 | * plato_key.h - PLATO keyboard mappings 13 | */ 14 | 15 | /** 16 | * plato_key.h 17 | * PLATO specific key mappings 18 | * used by key.h 19 | * this define table is ordered as in s0ascers document. 20 | */ 21 | 22 | #ifndef PLATO_KEY_H 23 | #define PLATO_KEY_H 24 | 25 | #define PKEY_a 0x41 26 | #define PKEY_A 0x61 27 | #define PKEY_b 0x42 28 | #define PKEY_B 0x62 29 | #define PKEY_c 0x43 30 | #define PKEY_C 0x63 31 | #define PKEY_d 0x44 32 | #define PKEY_D 0x64 33 | #define PKEY_e 0x45 34 | #define PKEY_E 0x65 35 | #define PKEY_f 0x46 36 | #define PKEY_F 0x66 37 | #define PKEY_g 0x47 38 | #define PKEY_G 0x67 39 | #define PKEY_h 0x48 40 | #define PKEY_H 0x68 41 | #define PKEY_i 0x49 42 | #define PKEY_I 0x69 43 | #define PKEY_j 0x4a 44 | #define PKEY_J 0x6a 45 | #define PKEY_k 0x4b 46 | #define PKEY_K 0x6b 47 | #define PKEY_l 0x4c 48 | #define PKEY_L 0x6C 49 | #define PKEY_m 0x4d 50 | #define PKEY_M 0x6d 51 | #define PKEY_n 0x4e 52 | #define PKEY_N 0x6e 53 | #define PKEY_o 0x4f 54 | #define PKEY_O 0x6f 55 | #define PKEY_p 0x50 56 | #define PKEY_P 0x70 57 | #define PKEY_q 0x51 58 | #define PKEY_Q 0x71 59 | #define PKEY_r 0x52 60 | #define PKEY_R 0x72 61 | #define PKEY_s 0x53 62 | #define PKEY_S 0x73 63 | #define PKEY_t 0x54 64 | #define PKEY_T 0x74 65 | #define PKEY_u 0x55 66 | #define PKEY_U 0x75 67 | #define PKEY_v 0x56 68 | #define PKEY_V 0x76 69 | #define PKEY_w 0x57 70 | #define PKEY_W 0x77 71 | #define PKEY_x 0x58 72 | #define PKEY_X 0x78 73 | #define PKEY_y 0x59 74 | #define PKEY_Y 0x79 75 | #define PKEY_z 0x5a 76 | #define PKEY_Z 0x7A 77 | #define PKEY_0 0x00 78 | #define PKEY_LESS_THAN 0x20 79 | #define PKEY_1 0x01 80 | #define PKEY_GREATER_THAN 0x21 81 | #define PKEY_2 0x02 82 | #define PKEY_BRACKET_LEFT 0x22 83 | #define PKEY_3 0x03 84 | #define PKEY_BRACKET_RIGHT 0x23 85 | #define PKEY_4 0x04 86 | #define PKEY_DOLLAR 0x24 87 | #define PKEY_5 0x05 88 | #define PKEY_PERCENT 0x25 89 | #define PKEY_6 0x06 90 | #define PKEY_UNDERSCORE 0x26 91 | #define PKEY_7 0x07 92 | #define PKEY_APOSTROPHE 0x27 93 | #define PKEY_8 0x08 94 | #define PKEY_ASTERISK 0x28 95 | #define PKEY_9 0x09 96 | #define PKEY_PARENTHESIS_LEFT 0x29 97 | #define PKEY_EQUALS 0x5B 98 | #define PKEY_PARENTHESIS_RIGHT 0x7B 99 | #define PKEY_PLUS 0x0E 100 | #define PKEY_SIGMA 0x2E 101 | #define PKEY_ASSIGN 0x0D 102 | #define PKEY_SHIFT 0x2D 103 | #define PKEY_MINUS 0x0F 104 | #define PKEY_DELTA 0x2F 105 | #define PKEY_DIVIDE 0x0B 106 | #define PKEY_INTERSECT 0x2B 107 | #define PKEY_MULTIPLY 0x0A 108 | #define PKEY_UNION 0x2A 109 | #define PKEY_SEMICOLON 0x5c 110 | #define PKEY_COLON 0x7c 111 | #define PKEY_PERIOD 0x5e 112 | #define PKEY_EXCLAMATION 0x7e 113 | #define PKEY_COMMA 0x5f 114 | #define PKEY_QUOTE 0x7f 115 | #define PKEY_SLASH 0x5d 116 | #define PKEY_QUESTION_MARK 0x7d 117 | #define PKEY_SUPER 0x10 118 | #define PKEY_SUPER1 0x30 119 | #define PKEY_SUB 0x11 120 | #define PKEY_SUB1 0x31 121 | #define PKEY_ANS 0x12 122 | #define PKEY_TERM 0x32 123 | #define PKEY_COPY 0x1B 124 | #define PKEY_COPY1 0x3B 125 | #define PKEY_TAB 0x0c 126 | #define PKEY_CR 0x2c 127 | #define PKEY_ERASE 0x13 128 | #define PKEY_ERASE1 0x33 129 | #define PKEY_MICRO 0x14 130 | #define PKEY_FONT 0x34 131 | #define PKEY_HELP 0x15 132 | #define PKEY_HELP1 0x35 133 | #define PKEY_SQUARE 0x1C 134 | #define PKEY_ACCESS 0x3C 135 | #define PKEY_NEXT 0x16 136 | #define PKEY_NEXT1 0x36 137 | #define PKEY_EDIT 0x17 138 | #define PKEY_EDIT1 0x37 139 | #define PKEY_BACK 0x18 140 | #define PKEY_BACK1 0x38 141 | #define PKEY_LAB 0x1D 142 | #define PKEY_LAB1 0x3D 143 | #define PKEY_DATA 0x19 144 | #define PKEY_DATA1 0x39 145 | #define PKEY_STOP 0x1a 146 | #define PKEY_STOP1 0x3a 147 | #define PKEY_SPACE 0x40 148 | #define PKEY_BACKSPACE 0x60 149 | #define PKEY_PRINT 0x1F 150 | #define PKEY_PRINT1 0x3F 151 | #define PKEY_NOKEY 0xFF /* no key mapping */ 152 | 153 | /* The following keys require an ACCESS key combination */ 154 | #define PKEY_ALPHA 0x80 155 | #define PKEY_BETA 0x81 156 | #define PKEY_CEDILLA 0x82 157 | #define PKEY_LOWERCASE_DELTA 0x83 158 | #define PKEY_ACUTE_ACCENT 0x84 159 | #define PKEY_LOWERCASE_AE 0x85 160 | #define PKEY_LOWERCASE_OE 0x86 161 | #define PKEY_LOWERCASE_A_WITH_RING 0x87 162 | #define PKEY_LOWERCASE_A_WITH_DIAERESIS 0x88 163 | #define PKEY_LAMBDA 0x89 164 | #define PKEY_MU 0x8A 165 | #define PKEY_TILDE 0x8B 166 | #define PKEY_DEGREE 0x8C 167 | #define PKEY_PI 0x8D 168 | #define PKEY_GRAVE 0x8E 169 | #define PKEY_RHO 0x8F 170 | #define PKEY_LOWERCASE_SIGMA 0x90 171 | #define PKEY_THETA 0x91 172 | #define PKEY_DIARESIS 0x92 173 | #define PKEY_HACEK 0x93 174 | #define PKEY_CAPITAL_PI 0x94 175 | #define PKEY_CIRCUMFLEX 0x95 176 | #define PKEY_LEFT_EMBED 0x96 177 | #define PKEY_RIGHT_EMBED 0x97 178 | #define PKEY_AT 0x98 179 | #define PKEY_ARROW 0x99 180 | #define PKEY_AMPERSAND 0x9A 181 | #define PKEY_INTERPUNCT 0x9B 182 | #define PKEY_LOWER_TILDE 0x9C 183 | #define PKEY_DELIMITER 0x9D 184 | #define PKEY_BACKSLASH 0x9E 185 | #define PKEY_NOT_EQUAL 0x9F 186 | #define PKEY_LOWERCASE_O_WITH_DIARESIS 0xA0 187 | #define PKEY_LEFT_ARROW 0xA1 188 | #define PKEY_DOWN_ARROW 0xA2 189 | #define PKEY_RIGHT_ARROW 0xA3 190 | #define PKEY_UP_ARROW 0xA4 191 | #define PKEY_COPYRIGHT 0xA5 192 | #define PKEY_DIAMOND 0xA6 193 | #define PKEY_UPPERCASE_AE 0xA7 194 | #define PKEY_UPPERCASE_OE 0xA8 195 | #define PKEY_BAR 0xA9 196 | #define PKEY_UPPERCASE_A_WITH_RING 0xAA 197 | #define PKEY_UPPERCASE_A_WITH_DIAERESIS 0xAB 198 | #define PKEY_ACCESS_SQUARE 0xAC 199 | #define PKEY_UPPERCASE_O_WITH_DIARESIS 0xAD 200 | #define PKEY_LESS_THAN_OR_EQUAL 0xAE 201 | #define PKEY_GREATER_THAN_OR_EQUAL 0xAF 202 | #define PKEY_LEFT_CURLY_BRACE 0xB0 203 | #define PKEY_RIGHT_CURLY_BRACE 0xB1 204 | #define PKEY_POUND 0xB2 205 | #define PKEY_BIG_CROSS 0xB3 206 | #define PKEY_EQUIVALENT 0xB4 207 | 208 | #endif /* PLATO_KEY_H */ 209 | 210 | -------------------------------------------------------------------------------- /platoterm.c: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * platoterm.c - Main/initialization functions. 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "protocol.h" 20 | #include "screen.h" 21 | #include "io.h" 22 | #include "terminal.h" 23 | #include "keyboard.h" 24 | #include "touch.h" 25 | #include "menu.h" 26 | 27 | #define TRUE 1 28 | #define FALSE 0 29 | 30 | char* options1[] = {"ANS","BACK","COPY","DATA","EDIT","FONT","HELP","LAB","MICRO","NEXT","□","STOP","SUB","SUPER","TERM","×","÷","Σ","Δ","Quit",0}; 31 | char* options2[] = {"SHIFT-BACK (BACK1)","SHIFT-COPY (COPY1)","SHIFT-DATA (DATA1)", "SHIFT-EDIT (EDIT)", "SHIFT-HELP (HELP1)", "SHIFT-LAB (LAB1)", "SHIFT-NEXT (NEXT1)", "SHIFT-STOP (STOP1)", "SHIFT-SUB (SUB1)", "SHIFT-SUPER (SUPER1)",0}; 32 | 33 | char* h; 34 | char* p="8005"; 35 | 36 | Menu rightmenu = {options1}; 37 | Menu midmenu = {options2}; 38 | 39 | unsigned char already_started=FALSE; 40 | int done = FALSE; 41 | 42 | Event ev; 43 | Mouse m; 44 | int key; 45 | int netev; 46 | 47 | extern int net; 48 | 49 | void usage(void) 50 | { 51 | print("platoterm -h [-p ]\n"); 52 | exits("invalid args"); 53 | } 54 | 55 | void main(int argc, char *argv[]) 56 | { 57 | unsigned char err=TRUE; 58 | 59 | ARGBEGIN 60 | { 61 | case 'h': 62 | h = ARGF(); 63 | err=FALSE; 64 | break; 65 | case 'p': 66 | p = ARGF(); 67 | break; 68 | default: 69 | usage(); 70 | } 71 | ARGEND; 72 | 73 | if (argc == 1 || err == TRUE) 74 | usage(); 75 | 76 | screen_init(); 77 | terminal_init(); 78 | touch_init(); 79 | io_init(h, p); 80 | 81 | netev = estart(0,net,EMAXMSG); 82 | 83 | while (done == FALSE) 84 | { 85 | key = event(&ev); 86 | 87 | if (key == Ekeyboard) 88 | keyboard_main(ev.kbdc); 89 | else if (key == Emouse) 90 | { 91 | if (ev.mouse.buttons & 1) 92 | touch_main(ev.mouse.xy.x - screen->r.min.x, ev.mouse.xy.y - screen->r.min.y); 93 | else if (ev.mouse.buttons & 2) 94 | menu_middle(emenuhit(2,&ev.mouse,&midmenu)); 95 | else if (ev.mouse.buttons & 4) 96 | menu_right(emenuhit(3,&ev.mouse,&rightmenu)); 97 | } 98 | else if (key == netev) 99 | { 100 | io_main(ev.data,ev.n); 101 | screen_update_view(); 102 | } 103 | } 104 | 105 | touch_done(); 106 | io_done(); 107 | screen_done(); 108 | } 109 | -------------------------------------------------------------------------------- /protocol.c: -------------------------------------------------------------------------------- 1 | /** 2 | /** 3 | * PLATOTERM for Plan 9 4 | * 5 | * A PLATO terminal for services such as 6 | * CYBER1.ORG and IRATA.ONLINE 7 | * 8 | * Author: Thomas Cherryhomes 9 | * 10 | * 11 | * License: GPL 3.0 12 | * 13 | * protocol.c - the PAD terminal state machine 14 | */ 15 | 16 | /** 17 | * This file written by Steve Peltz. Copyright notice preserved. 18 | * and this code has been used with permission, and can be considered 19 | * public domain. 20 | */ 21 | 22 | /* Copyright (c) 1990 by Steve Peltz */ 23 | 24 | #include "protocol.h" 25 | #include "terminal.h" 26 | #include "keyboard.h" 27 | #include "screen.h" 28 | #include "io.h" 29 | #include "touch.h" 30 | 31 | #define BSIZE 64 32 | #define TRUE 1 33 | #define FALSE 0 34 | 35 | static padBool EscFlag; /* Currently in an escape sequence */ 36 | static Mode PMode, /* Mode */ 37 | CMode; /* Command */ 38 | static unsigned short SubMode; /* Block/Line modes */ 39 | static DataType PType, /* Mode type */ 40 | CType; /* Current type */ 41 | static unsigned short Phase; /* Phase of current type */ 42 | static padWord theWord; /* Data received for various data types */ 43 | static padByte theChar; 44 | static padByte rawChar; 45 | static padByte lastChar; 46 | static padRGB theColor; 47 | static unsigned short LowX, /* Previous coordinates received */ 48 | HiX, LowY, HiY; 49 | static padPt CurCoord; /* Current coordinate */ 50 | static padWord Margin; /* Margin for CR */ 51 | static padWord MemAddr; /* Load address for program data */ 52 | static unsigned short CharCnt; /* Current count for loading chars */ 53 | static charData Char; /* Character data */ 54 | static padByte charBuff[BSIZE]; 55 | static unsigned short charCount; /* Count of characters currently buffered */ 56 | static padPt charCoord; 57 | 58 | static padByte PTAT0[128] = { /* PLATO to ASCII lookup table */ 59 | 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* original mapping */ 60 | 0x38, 0x39, 0x26, 0x60, 0x0a, 0x5e, 0x2b, 0x2d, 61 | 0x13, 0x04, 0x07, 0x08, 0x7b, 0x0b, 0x0d, 0x1a, 62 | 0x02, 0x12, 0x01, 0x03, 0x7d, 0x0c, 0x83, 0x85, 63 | 0x3c, 0x3e, 0x5b, 0x5d, 0x24, 0x25, 0x5f, 0x7c, 64 | 0x2a, 0x28, 0x40, 0x27, 0x1c, 0x5c, 0x23, 0x7e, 65 | 0x17, 0x05, 0x14, 0x19, 0x7f, 0x09, 0x1e, 0x18, 66 | 0x0e, 0x1d, 0x11, 0x16, 0x00, 0x0f, 0x87, 0x88, 67 | 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 68 | 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 69 | 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 70 | 0x78, 0x79, 0x7a, 0x3d, 0x3b, 0x2f, 0x2e, 0x2c, 71 | 0x1f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 72 | 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 73 | 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 74 | 0x58, 0x59, 0x5a, 0x29, 0x3a, 0x3f, 0x21, 0x22 75 | }; 76 | 77 | static padByte PTAT1[128] = { 78 | 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* flow control mapping */ 79 | 0x38, 0x39, 0x26, 0x60, 0x09, 0x5e, 0x2b, 0x2d, 80 | 0x17, 0x04, 0x07, 0x08, 0x7b, 0x0b, 0x0d, 0x1a, 81 | 0x02, 0x12, 0x01, 0x03, 0x7d, 0x0c, 0x83, 0x85, 82 | 0x3c, 0x3e, 0x5b, 0x5d, 0x24, 0x25, 0x5f, 0x27, 83 | 0x2a, 0x28, 0x40, 0x7c, 0x1c, 0x5c, 0x23, 0x7e, 84 | 0x97, 0x84, 0x14, 0x19, 0x7f, 0x0a, 0x1e, 0x18, 85 | 0x0e, 0x1d, 0x05, 0x16, 0x9d, 0x0f, 0x87, 0x88, 86 | 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 87 | 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 88 | 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 89 | 0x78, 0x79, 0x7a, 0x3d, 0x3b, 0x2f, 0x2e, 0x2c, 90 | 0x1f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 91 | 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 92 | 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 93 | 0x58, 0x59, 0x5a, 0x29, 0x3a, 0x3f, 0x21, 0x22 94 | }; 95 | 96 | /* externally referenced variables */ 97 | 98 | padPt PLATOSize={512,512}; /* Logical screen size */ 99 | CharMem CurMem; /* Font to plot in */ 100 | padBool TTY, /* TTY mode */ 101 | FlowControl, /* Flow control on */ 102 | ModeBold, /* Character plotting conditions */ 103 | Rotate, Reverse; 104 | DispMode CurMode; /* Current PLATO plotting mode */ 105 | padBool FastText; /* Indicate to main program if text optimizations can be done. */ 106 | 107 | 108 | /*----------------------------------------------* 109 | * InitPAD, InitTTY, InitPLATO * 110 | * * 111 | * Called to initialize PAD variables. * 112 | * Calls back to external routines to * 113 | * set up proper plotting conditions. * 114 | *----------------------------------------------*/ 115 | 116 | 117 | void InitPAD () 118 | { 119 | InitTTY (); 120 | } 121 | 122 | 123 | void InitTTY () 124 | { 125 | charCount = 0; 126 | EscFlag = FALSE; 127 | TTY = TRUE; 128 | FastText = TRUE; 129 | FlowControl = FALSE; 130 | terminal_set_tty(); 131 | } 132 | 133 | 134 | void InitPLATO () 135 | { 136 | if (TTY) 137 | InitPLATOx (); 138 | } 139 | 140 | 141 | void InitPLATOx () 142 | { 143 | charCount = 0; 144 | EscFlag = FALSE; 145 | TTY = FALSE; 146 | terminal_set_plato (); 147 | SetMode (mAlpha, tByte); 148 | LowX = 0; 149 | HiX = 0; 150 | LowY = 0; 151 | HiY = 0; 152 | CurCoord.x = 0; 153 | CurCoord.y = 0; 154 | MemAddr = 0; 155 | CharCnt = 0; 156 | Margin = 0; 157 | ModeBold = FALSE; 158 | Rotate = FALSE; 159 | Reverse = FALSE; 160 | FastText = TRUE; 161 | CurMem = M0; 162 | CurMode = ModeRewrite; 163 | } 164 | 165 | 166 | /*----------------------------------------------* 167 | * Key * 168 | * * 169 | * Send a 10-bit internal key. If a keyset * 170 | * key, translate, else send as escaped * 171 | * sequence. * 172 | *----------------------------------------------*/ 173 | 174 | 175 | void Key (padWord theKey) 176 | { 177 | if (theKey >> 7) 178 | { 179 | io_send_byte (0x1b); 180 | io_send_byte (0x40 | (theKey & 0x3f)); 181 | io_send_byte (0x60 | ((theKey >> 6) & 0x0f)); 182 | } 183 | else 184 | { 185 | 186 | if (FlowControl == 0) 187 | theKey = PTAT0[theKey]; 188 | else 189 | theKey = PTAT1[theKey]; 190 | 191 | if (theKey & 0x80) 192 | { 193 | io_send_byte (0x1b); 194 | io_send_byte (theKey & 0x7f); 195 | } 196 | else 197 | io_send_byte (theKey); 198 | } 199 | } 200 | 201 | /*----------------------------------------------* 202 | * Touch * 203 | * * 204 | * Send a touch key (01yyyyxxxx). * 205 | *----------------------------------------------*/ 206 | 207 | void Touch(padPt *where) 208 | { 209 | io_send_byte(0x1b); 210 | io_send_byte(0x1f); 211 | io_send_byte(0x40 + (where->x & 0x1f)); 212 | io_send_byte(0x40 + ((where->x >> 5) & 0x0f)); 213 | io_send_byte(0x40 + (where->y & 0x1f)); 214 | io_send_byte(0x40 + ((where->y >> 5) & 0x0f)); 215 | 216 | Key(0x100 | ((where->x >> 1) & 0xF0) | 217 | ((where->y >> 5) & 0x0F)); 218 | } 219 | 220 | /*----------------------------------------------* 221 | * Ext * 222 | * * 223 | * Send an external key (10xxxxxxxx). * 224 | *----------------------------------------------*/ 225 | 226 | 227 | void Ext (padWord theKey) 228 | { 229 | Key (0x200 | (theKey & 0xFF)); 230 | } 231 | 232 | 233 | /*----------------------------------------------* 234 | * Echo * 235 | * * 236 | * Send an echo key (001xxxxxx). * 237 | *----------------------------------------------*/ 238 | 239 | 240 | void Echo (padWord theKey) 241 | { 242 | Key (0x080 | theKey); 243 | } 244 | 245 | 246 | 247 | /*----------------------------------------------* 248 | * SetCommand, SetMode * 249 | * * 250 | * Set state machine variables. * 251 | *----------------------------------------------*/ 252 | 253 | 254 | void SetCommand (Mode theMode, DataType theType) 255 | { 256 | CMode = theMode; 257 | CType = theType; 258 | Phase = 0; 259 | } 260 | 261 | 262 | void SetMode (Mode theMode, DataType theType) 263 | { 264 | PMode = theMode; 265 | PType = theType; 266 | SubMode = 0; 267 | SetCommand (theMode, theType); 268 | } 269 | 270 | 271 | /*----------------------------------------------* 272 | * FixXY * 273 | * * 274 | * Move location by offset, then make sure * 275 | * it is still on the screen. * 276 | *----------------------------------------------*/ 277 | 278 | 279 | void FixXY (short DX, short DY) 280 | { 281 | if (ModeBold) 282 | { 283 | DX = DX * 2; 284 | DY = DY * 2; 285 | } 286 | if (Reverse) 287 | DX = -DX; 288 | if (Rotate) 289 | { 290 | CurCoord.x = CurCoord.x + DY; 291 | CurCoord.y = CurCoord.y + DX; 292 | } 293 | else 294 | { 295 | CurCoord.x = CurCoord.x + DX; 296 | CurCoord.y = CurCoord.y + DY; 297 | } 298 | 299 | if (CurCoord.x < 0) 300 | CurCoord.x += PLATOSize.x; 301 | else if (CurCoord.x >= PLATOSize.x) 302 | CurCoord.x -= PLATOSize.x; 303 | 304 | if (CurCoord.y < 0) 305 | CurCoord.y += PLATOSize.y; 306 | else if (CurCoord.y >= PLATOSize.y) 307 | CurCoord.y -= PLATOSize.y; 308 | } 309 | 310 | 311 | /*----------------------------------------------* 312 | * Superx, Subx, etc. * 313 | * * 314 | * Various character positioning commands. * 315 | *----------------------------------------------*/ 316 | 317 | 318 | void Superx () 319 | { 320 | FixXY (0, 5); 321 | } 322 | 323 | 324 | void Subx () 325 | { 326 | FixXY (0, -5); 327 | } 328 | 329 | 330 | void Marginx () 331 | { 332 | if (Rotate) 333 | Margin = CurCoord.y; 334 | else 335 | Margin = CurCoord.x; 336 | } 337 | 338 | 339 | void BSx () 340 | { 341 | FixXY (-8, 0); 342 | } 343 | 344 | 345 | void HTx () 346 | { 347 | FixXY (8, 0); 348 | } 349 | 350 | 351 | void LFx () 352 | { 353 | FixXY (0, -16); 354 | } 355 | 356 | 357 | void VTx () 358 | { 359 | FixXY (0, 16); 360 | } 361 | 362 | 363 | void FFx () 364 | { 365 | CurCoord.y = 0; 366 | CurCoord.x = 0; 367 | LFx (); 368 | } 369 | 370 | 371 | void CRx () 372 | { 373 | if (Rotate) 374 | CurCoord.y = Margin; 375 | else 376 | CurCoord.x = Margin; 377 | LFx (); 378 | } 379 | 380 | 381 | /*----------------------------------------------* 382 | * LoadCoordx * 383 | * * 384 | * Assemble completed coordinate. * 385 | *----------------------------------------------*/ 386 | 387 | 388 | void LoadCoordx (padPt *SetCoord) 389 | { 390 | SetCoord->x = (HiX << 5) + LowX; 391 | SetCoord->y = (HiY << 5) + LowY; 392 | } 393 | 394 | 395 | /*----------------------------------------------* 396 | * Blockx, Pointx, Linex, Alphax * 397 | * * 398 | * Plot the specified item at the * 399 | * current location. * 400 | *----------------------------------------------*/ 401 | 402 | 403 | void Blockx () 404 | { 405 | padPt NewCoord; 406 | 407 | if (SubMode == 0) 408 | { 409 | LoadCoordx (&CurCoord); 410 | SubMode = 1; 411 | } 412 | else 413 | { 414 | LoadCoordx (&NewCoord); 415 | screen_block_draw (&CurCoord, &NewCoord); 416 | SubMode = 0; 417 | CurCoord.y-=15; 418 | CurCoord.x+=16; 419 | } 420 | } 421 | 422 | 423 | void Pointx () 424 | { 425 | LoadCoordx (&CurCoord); 426 | screen_dot_draw (&CurCoord); 427 | } 428 | 429 | 430 | void Linex () 431 | { 432 | padPt OldCoord; 433 | 434 | if (SubMode == 0) 435 | { 436 | LoadCoordx (&CurCoord); 437 | SubMode = 1; 438 | } 439 | else 440 | { 441 | OldCoord.y = CurCoord.y; 442 | OldCoord.x = CurCoord.x; 443 | LoadCoordx (&CurCoord); 444 | screen_line_draw (&OldCoord, &CurCoord); 445 | } 446 | } 447 | 448 | 449 | void Alphax () 450 | { 451 | if (charCount == 0) 452 | charCoord = CurCoord; 453 | charBuff[charCount++] = theChar; 454 | HTx (); 455 | if (charCount >= BSIZE) 456 | { 457 | screen_char_draw (&charCoord, charBuff, charCount); 458 | charCount = 0; 459 | } 460 | } 461 | 462 | 463 | /*----------------------------------------------* 464 | * LoadEchox * 465 | * * 466 | * Echo responses to system. * 467 | *----------------------------------------------*/ 468 | 469 | 470 | void LoadEchox () 471 | { 472 | theWord &= 0x7f; 473 | switch (theWord) 474 | { 475 | 476 | case 0x52: 477 | FlowControl=TRUE; 478 | if (FlowControl) 479 | Echo (0x53); /* flow control on */ 480 | else 481 | Echo (0x52); /* flow control not on */ 482 | break; 483 | case 0x60: /* Inquire about ascii specific features. */ 484 | Echo (terminal_get_features()); 485 | break; 486 | case 0x70: 487 | Echo (terminal_get_type ()); /* terminal type */ 488 | break; 489 | 490 | case 0x71: 491 | Echo (terminal_get_subtype()); /* subtype */ 492 | break; 493 | 494 | case 0x72: 495 | Echo (terminal_get_load_file ()); /* load file */ 496 | break; 497 | 498 | case 0x73: 499 | Echo (terminal_get_configuration ()); /* configuration */ 500 | break; 501 | 502 | case 0x7A: 503 | Key (0x3FF); /* send backout */ 504 | break; 505 | 506 | case 0x7B: 507 | screen_beep (); 508 | break; /* beep */ 509 | 510 | case 0x7D: 511 | Echo (terminal_mem_read (MemAddr) & 0x7F); 512 | break; 513 | 514 | default: 515 | Echo (theWord); /* normal echo */ 516 | break; 517 | } 518 | } 519 | 520 | 521 | void LoadAddrx () 522 | { 523 | MemAddr = theWord; 524 | CharCnt = 0; 525 | } 526 | 527 | 528 | void LoadCharx () 529 | { 530 | Char[CharCnt] = theWord; 531 | if (CharCnt < 7) 532 | CharCnt++; 533 | else 534 | { 535 | terminal_char_load ((((MemAddr - terminal_get_char_address ()) >> 4) & 0x7f), Char); 536 | CharCnt = 0; 537 | MemAddr += 16; 538 | } 539 | } 540 | 541 | 542 | void LoadMemx () 543 | { 544 | terminal_mem_load (MemAddr, theWord); 545 | MemAddr += 2; 546 | } 547 | 548 | 549 | void SSFx () 550 | { 551 | padByte device; 552 | 553 | device = (theWord >> 10) & 0xFF; 554 | if (device == 1) 555 | { 556 | terminal_ext_allow ((theWord >> 3) & 1); 557 | touch_allow ((theWord >> 5) & 1); 558 | } 559 | else if ((theWord >> 9) & 1) 560 | { 561 | terminal_set_ext_in (device); 562 | if (!((theWord >> 8) & 1)) 563 | Ext (terminal_ext_in ()); 564 | } 565 | else 566 | { 567 | terminal_set_ext_out (device); 568 | if (!((theWord >> 8) & 1)) 569 | terminal_ext_out (theWord & 0xFF); 570 | } 571 | } 572 | 573 | 574 | void Externalx () 575 | { 576 | terminal_ext_out ((theWord >> 8) & 0xFF); 577 | terminal_ext_out (theWord & 0xFF); 578 | } 579 | 580 | 581 | void GoMode () 582 | { 583 | switch (CMode) 584 | { 585 | case mBlock: 586 | Blockx (); 587 | break; 588 | case mPoint: 589 | Pointx (); 590 | break; 591 | case mLine: 592 | Linex (); 593 | break; 594 | case mAlpha: 595 | Alphax (); 596 | break; 597 | case mLoadCoord: 598 | LoadCoordx (&CurCoord); 599 | break; 600 | case mLoadAddr: 601 | LoadAddrx (); 602 | break; 603 | case mSSF: 604 | SSFx (); 605 | break; 606 | case mExternal: 607 | Externalx (); 608 | break; 609 | case mLoadEcho: 610 | LoadEchox (); 611 | break; 612 | case mLoadChar: 613 | LoadCharx (); 614 | break; 615 | case mLoadMem: 616 | LoadMemx (); 617 | break; 618 | case mMode5: 619 | terminal_mode_5 (theWord); 620 | break; 621 | case mMode6: 622 | terminal_mode_6 (theWord); 623 | break; 624 | case mMode7: 625 | terminal_mode_7 (theWord); 626 | break; 627 | case mFore: 628 | screen_foreground(&theColor); 629 | break; 630 | case mBack: 631 | screen_background(&theColor); 632 | break; 633 | case mPaint: 634 | screen_paint(&CurCoord); 635 | break; 636 | } 637 | CMode = PMode; 638 | CType = PType; 639 | Phase = 0; 640 | } 641 | 642 | 643 | void GoWord () 644 | { 645 | switch (Phase) 646 | { 647 | case 0: 648 | theWord = theChar & 0x3F; 649 | Phase = 1; 650 | break; 651 | case 1: 652 | theWord |= ((theChar & 0x3F) << 6); 653 | Phase = 2; 654 | break; 655 | case 2: 656 | theWord |= ((theChar & 0x3F) << 12); 657 | GoMode (); 658 | break; 659 | } 660 | } 661 | 662 | 663 | void GoCoord () 664 | { 665 | unsigned short CoordType, CoordValue; 666 | 667 | CoordValue = theChar & 0x1F; 668 | CoordType = ((theChar >> 5) & 3); 669 | switch (CoordType) 670 | { 671 | case 1: 672 | switch (Phase) 673 | { 674 | case 0: 675 | HiY = CoordValue; 676 | break; 677 | case 1: 678 | HiX = CoordValue; 679 | break; 680 | } 681 | Phase = 1; 682 | break; 683 | case 2: 684 | LowX = CoordValue; 685 | GoMode (); 686 | break; 687 | case 3: 688 | LowY = CoordValue; 689 | Phase = 1; 690 | break; 691 | } 692 | } 693 | 694 | 695 | void GoColor () 696 | { 697 | switch (Phase) 698 | { 699 | case 0: 700 | theColor.blue = (theChar & 0x3f); 701 | break; 702 | case 1: 703 | theColor.blue |= (theChar & 0x03) << 6; 704 | theColor.green = (theChar & 0x3c) >> 2; 705 | break; 706 | case 2: 707 | theColor.green |= (theChar & 0x0f) << 4; 708 | theColor.red = (theChar & 0x30) >> 4; 709 | break; 710 | case 3: 711 | theColor.red |= (theChar & 0x3f) << 2; 712 | break; 713 | } 714 | if (Phase < 3) 715 | Phase++; 716 | else 717 | GoMode (); 718 | } 719 | 720 | 721 | void GoPaint () 722 | { 723 | if (Phase == 0) 724 | Phase = 1; 725 | else 726 | GoMode (); 727 | 728 | } 729 | 730 | 731 | void DataChar () 732 | { 733 | switch (CType) 734 | { 735 | case tByte: 736 | Alphax (); 737 | break; 738 | case tWord: 739 | GoWord (); 740 | break; 741 | case tCoord: 742 | GoCoord (); 743 | break; 744 | case tColor: 745 | GoColor (); 746 | break; 747 | case tPaint: 748 | GoPaint (); 749 | break; 750 | } 751 | } 752 | 753 | 754 | void ShowPLATO (padByte *buff, unsigned short count) 755 | { 756 | while (count--) 757 | { 758 | theChar = *buff++; 759 | if (lastChar==0xFF && theChar==0xFF) 760 | { 761 | lastChar=0; 762 | } 763 | else 764 | { 765 | rawChar=theChar; 766 | theChar &=0x7F; 767 | if (TTY) 768 | { 769 | if (!EscFlag) 770 | screen_tty_char (theChar); 771 | else if (theChar == 0x02) 772 | InitPLATOx (); 773 | } 774 | else if (EscFlag) 775 | { 776 | switch (theChar) 777 | { 778 | case 0x03: 779 | InitTTY (); 780 | break; 781 | 782 | case 0x0C: 783 | screen_clear (); 784 | break; 785 | 786 | case 0x11: 787 | CurMode = ModeInverse; 788 | SetFast(); 789 | break; 790 | case 0x12: 791 | CurMode = ModeWrite; 792 | SetFast(); 793 | break; 794 | case 0x13: 795 | CurMode = ModeErase; 796 | SetFast(); 797 | break; 798 | case 0x14: 799 | CurMode = ModeRewrite; 800 | SetFast(); 801 | break; 802 | 803 | case 0x32: 804 | SetCommand (mLoadCoord, tCoord); 805 | break; 806 | 807 | case 0x40: 808 | Superx (); 809 | break; 810 | case 0x41: 811 | Subx (); 812 | break; 813 | 814 | case 0x42: 815 | CurMem = M0; 816 | break; 817 | case 0x43: 818 | CurMem = M1; 819 | break; 820 | case 0x44: 821 | CurMem = M2; 822 | break; 823 | case 0x45: 824 | CurMem = M3; 825 | break; 826 | 827 | case 0x4A: 828 | Rotate = FALSE; 829 | SetFast(); 830 | break; 831 | case 0x4B: 832 | Rotate = TRUE; 833 | SetFast(); 834 | break; 835 | case 0x4C: 836 | Reverse = FALSE; 837 | SetFast(); 838 | break; 839 | case 0x4D: 840 | Reverse = TRUE; 841 | SetFast(); 842 | break; 843 | case 0x4E: 844 | ModeBold = FALSE; 845 | SetFast(); 846 | break; 847 | case 0x4F: 848 | ModeBold = TRUE; 849 | SetFast(); 850 | break; 851 | 852 | case 0x50: 853 | SetMode (mLoadChar, tWord); 854 | break; 855 | case 0x51: 856 | SetCommand (mSSF, tWord); 857 | break; 858 | case 0x52: 859 | SetCommand (mExternal, tWord); 860 | break; 861 | case 0x53: 862 | SetMode (mLoadMem, tWord); 863 | break; 864 | case 0x54: 865 | SetMode (mMode5, tWord); 866 | break; 867 | case 0x55: 868 | SetMode (mMode6, tWord); 869 | break; 870 | case 0x56: 871 | SetMode (mMode7, tWord); 872 | break; 873 | case 0x57: 874 | SetCommand (mLoadAddr, tWord); 875 | break; 876 | case 0x59: 877 | SetCommand (mLoadEcho, tWord); 878 | break; 879 | 880 | case 0x5A: 881 | Marginx (); 882 | break; 883 | 884 | case 0x61: 885 | SetCommand (mFore, tColor); 886 | break; 887 | case 0x62: 888 | SetCommand (mBack, tColor); 889 | break; 890 | case 0x63: 891 | SetCommand (mPaint, tPaint); 892 | break; 893 | } 894 | } 895 | else if (theChar < 0x20) 896 | { 897 | if (charCount > 0) 898 | { 899 | screen_char_draw (&charCoord, charBuff, charCount); 900 | charCount = 0; 901 | } 902 | switch (theChar) 903 | { 904 | case 0x00: 905 | screen_wait(); 906 | case 0x08: 907 | BSx (); 908 | break; 909 | case 0x09: 910 | HTx (); 911 | break; 912 | case 0x0A: 913 | LFx (); 914 | break; 915 | case 0x0B: 916 | VTx (); 917 | break; 918 | case 0x0C: 919 | FFx (); 920 | break; 921 | case 0x0D: 922 | CRx (); 923 | break; 924 | 925 | case 0x19: 926 | SetMode (mBlock, tCoord); 927 | break; 928 | case 0x1C: 929 | SetMode (mPoint, tCoord); 930 | break; 931 | case 0x1D: 932 | SetMode (mLine, tCoord); 933 | break; 934 | case 0x1F: 935 | SetMode (mAlpha, tByte); 936 | break; 937 | } 938 | } 939 | else 940 | DataChar (); 941 | 942 | EscFlag = (theChar == 0x1B); 943 | lastChar=rawChar; 944 | } 945 | } 946 | if (charCount > 0) 947 | { 948 | screen_char_draw (&charCoord, charBuff, charCount); 949 | charCount = 0; 950 | } 951 | } 952 | 953 | /** 954 | * SetFast() 955 | * Toggle fast text output if mode = write or erase, and no rotate or bold 956 | */ 957 | void SetFast() 958 | { 959 | FastText = (((CurMode == ModeWrite) || (CurMode == ModeErase)) && ((Rotate == padF) && (ModeBold == padF))); 960 | } 961 | -------------------------------------------------------------------------------- /protocol.h: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * protocol.h - The PAD protocol state machine 13 | */ 14 | 15 | /* Copyright (c) 1990 by Steve Peltz */ 16 | 17 | #ifndef PROTOCOL_H 18 | #define PROTOCOL_H 19 | 20 | #define ACCESS 0x3c 21 | 22 | typedef unsigned char padByte; 23 | typedef enum {padF, padT} padBool; 24 | typedef unsigned char padChar; 25 | typedef short padWord; 26 | typedef padWord charData[8]; 27 | typedef struct { 28 | padByte red, 29 | green, 30 | blue; 31 | } padRGB; 32 | 33 | typedef struct { 34 | padWord x, 35 | y; 36 | } padPt; 37 | 38 | typedef enum {ModeWrite, ModeErase, ModeRewrite, ModeInverse} DispMode; 39 | typedef enum {M0, M1, M2, M3} CharMem; 40 | 41 | typedef enum { mBlock, mPoint, mLine, mAlpha, mLoadCoord, mLoadChar, mSSF, 42 | mExternal, mLoadMem, mMode5, mMode6, mMode7, mLoadAddr, 43 | mLoadEcho, mFore, mBack, mPaint } Mode; 44 | 45 | typedef enum { tByte, tWord, tCoord, tColor, tPaint } DataType; 46 | 47 | extern padPt PLATOSize; 48 | extern CharMem CurMem; 49 | extern padBool TTY, 50 | FlowControl, 51 | ModeBold, 52 | Rotate, 53 | Reverse; 54 | extern DispMode CurMode; 55 | 56 | void InitPAD(void); 57 | void InitTTY(void); 58 | void InitPLATO(void); 59 | void InitPLATOx(void); 60 | void Key(padWord theKey); 61 | void Touch(padPt* where); 62 | void Ext(padWord theKey); 63 | void Echo(padWord theKey); 64 | void SetCommand(Mode theMode, DataType theType); 65 | void SetMode(Mode theMode, DataType theType); 66 | void FixXY(short DX, short DY); 67 | void Superx(void); 68 | void Subx(void); 69 | void Marginx(void); 70 | void BSx(void); 71 | void HTx(void); 72 | void LFx(void); 73 | void VTx(void); 74 | void FFx(void); 75 | void CRx(void); 76 | void LoadCoordx(padPt* SetCoord); 77 | void Blockx(void); 78 | void Pointx(void); 79 | void Linex(void); 80 | void Alphax(void); 81 | void LoadEchox(void); 82 | void LoadAddrx(void); 83 | void LoadCharx(void); 84 | void LoadMemx(void); 85 | void SSFx(void); 86 | void Externalx(void); 87 | void GoMode(void); 88 | void GoWord(void); 89 | void GoCoord(void); 90 | void GoColor(void); 91 | void GoPaint(void); 92 | void DataChar(void); 93 | void ShowPLATO(padByte* buff, unsigned short count); 94 | void SetFast(void); 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /screen.c: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * screen.c - Screen drawing functions 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "screen.h" 20 | #include "protocol.h" 21 | #include "font.h" 22 | #include "keyboard.h" 23 | #include "touch.h" 24 | #include "beep.h" 25 | #include "splash.h" 26 | 27 | unsigned char CharHigh=16; 28 | unsigned char CharWide=8; 29 | padPt TTYLoc; 30 | 31 | extern int done; 32 | 33 | unsigned char fontm23[2048]; 34 | padRGB backgroundPLATO={0,0,0}; 35 | padRGB foregroundPLATO={255,255,255}; 36 | 37 | #define TRUE 1 38 | #define FALSE 0 39 | 40 | short max(short a, short b) { return ( a > b ) ? a : b; } 41 | short min(short a, short b) { return ( a < b ) ? a : b; } 42 | 43 | extern padBool FastText; 44 | 45 | Image *view; 46 | 47 | unsigned long backgroundColor, foregroundColor; 48 | 49 | void screen_setup(void) 50 | { 51 | Point size = subpt(screen->r.max, screen->r.min); 52 | Rectangle frame = (Rectangle){Pt(0,0),size}; 53 | 54 | view = allocimage(display,frame,screen->chan,1,backgroundColor); 55 | } 56 | 57 | void eresized(int new) 58 | { 59 | if (new && getwindow(display, Refnone) < 0) 60 | sysfatal("can't reattach to window"); 61 | screen_update_view(); 62 | } 63 | 64 | /** 65 | * screen_init() - Set up the screen 66 | */ 67 | void screen_init(void) 68 | { 69 | int fd; 70 | 71 | backgroundColor = 0x000000FF; 72 | foregroundColor = 0xFFFFFFFF; 73 | 74 | if (initdraw(nil, nil, "platoterm") < 0) 75 | sysfatal("initdraw failed: %r"); 76 | 77 | einit(Emouse|Ekeyboard); 78 | 79 | fd = open("/dev/wctl",OWRITE); 80 | 81 | if (fd >= 0) 82 | { 83 | fprint(fd,"resize -dx 520 -dy 520"); // gives 512x512 client area. 84 | flushimage(display,1); 85 | close(fd); 86 | } 87 | 88 | eresized(0); 89 | screen_setup(); 90 | ShowPLATO(splash,sizeof(splash)); 91 | screen_update_view(); 92 | } 93 | 94 | /** 95 | * screen_update_view() Update vioew 96 | */ 97 | void screen_update_view(void) 98 | { 99 | draw(screen,screen->r,view,nil,ZP); 100 | flushimage(display,1); 101 | } 102 | 103 | /** 104 | * screen_main() - render/preserve screen 105 | */ 106 | void screen_main(void) 107 | { 108 | } 109 | 110 | /** 111 | * screen_wait() - Sleep for approx 16.67ms 112 | */ 113 | void screen_wait(void) 114 | { 115 | } 116 | 117 | /** 118 | * screen_beep() - Beep the terminal 119 | */ 120 | void screen_beep(void) 121 | { 122 | int fd; 123 | 124 | fd = open("/dev/audio", OWRITE); 125 | if (fd >= 0) 126 | { 127 | write(fd,beep_raw,beep_raw_len); 128 | close(fd); 129 | } 130 | } 131 | 132 | /** 133 | * screen_clear - Clear the screen 134 | */ 135 | void screen_clear(void) 136 | { 137 | Image *bkg = allocimagemix(display, backgroundColor, backgroundColor); 138 | draw(view,view->r,bkg,nil,ZP); 139 | freeimage(bkg); 140 | } 141 | 142 | /** 143 | * screen_block_draw(Coord1, Coord2) - Perform a block fill from Coord1 to Coord2 144 | */ 145 | void screen_block_draw(padPt *Coord1, padPt *Coord2) 146 | { 147 | Rectangle r; 148 | Image *c; 149 | 150 | r.min.x = min(Coord1->x,Coord2->x); 151 | r.max.x = max(Coord1->x,Coord2->x); 152 | r.min.y = min(Coord1->y^0x1FF,Coord2->y^0x1FF); 153 | r.max.y = max(Coord1->y^0x1FF,Coord2->y^0x1FF); 154 | 155 | if (CurMode == ModeErase || CurMode == ModeInverse) 156 | { 157 | c = allocimagemix(display,backgroundColor,backgroundColor); 158 | } 159 | else 160 | { 161 | c = allocimagemix(display,foregroundColor,foregroundColor); 162 | } 163 | 164 | draw(view,r,c,nil,ZP); 165 | 166 | freeimage(c); 167 | } 168 | 169 | /** 170 | * screen_dot_draw(Coord) - Plot a mode 0 pixel 171 | */ 172 | void screen_dot_draw(padPt *Coord) 173 | { 174 | Rectangle r; 175 | Image *c; 176 | 177 | r.min.x=r.max.x=Coord->x; 178 | r.min.y=r.max.y=Coord->y^0x1FF; 179 | r.max.x++; 180 | r.max.y++; 181 | 182 | if (CurMode == ModeErase || CurMode == ModeInverse) 183 | { 184 | c = allocimagemix(display,backgroundColor,backgroundColor); 185 | } 186 | else 187 | { 188 | c = allocimagemix(display,foregroundColor,foregroundColor); 189 | } 190 | 191 | draw(view,r,c,nil,ZP); 192 | freeimage(c); 193 | } 194 | 195 | /** 196 | * screen_line_draw(Coord1, Coord2) - Draw a mode 1 line 197 | */ 198 | void screen_line_draw(padPt *Coord1, padPt *Coord2) 199 | { 200 | Point beg,end; 201 | Image *c; 202 | 203 | beg.x = Coord1->x; 204 | end.x = Coord2->x; 205 | 206 | beg.y = Coord1->y^0x1FF; 207 | end.y = Coord2->y^0x1FF; 208 | 209 | if ((CurMode == ModeErase) || (CurMode == ModeInverse)) 210 | { 211 | c = allocimagemix(display,backgroundColor,backgroundColor); 212 | } 213 | else 214 | { 215 | c = allocimagemix(display,backgroundColor,foregroundColor); 216 | } 217 | 218 | line(view,beg,end,Endsquare,Endsquare,0,c,ZP); 219 | 220 | freeimage(c); 221 | } 222 | 223 | /** 224 | * screen_char_draw(Coord, ch, count) - Output buffer from ch* of length count as PLATO characters 225 | */ 226 | void screen_char_draw(padPt *Coord, unsigned char *ch, unsigned char count) 227 | { 228 | short offset; /* due to negative offsets */ 229 | unsigned short x; /* Current X and Y coordinates */ 230 | unsigned short y; 231 | unsigned short* px; /* Pointers to X and Y coordinates used for actual plotting */ 232 | unsigned short* py; 233 | unsigned char i; /* current character counter */ 234 | unsigned char a; /* current character byte */ 235 | unsigned char j,k; /* loop counters */ 236 | char b; /* current character row bit signed */ 237 | char width=8; 238 | char height=16; 239 | short deltaX=1; 240 | short deltaY=1; 241 | unsigned char *p; 242 | unsigned char* curfont; 243 | Image *mainColor; 244 | Image *altColor; 245 | 246 | curfont = plato_font; 247 | offset = 0; 248 | 249 | if (CurMode==ModeInverse) 250 | { 251 | altColor = allocimagemix(display,foregroundColor,foregroundColor); 252 | } 253 | else 254 | { 255 | altColor = allocimagemix(display,backgroundColor,backgroundColor); 256 | } 257 | 258 | if (CurMode==ModeErase || CurMode==ModeInverse) 259 | { 260 | mainColor = allocimagemix(display,backgroundColor,backgroundColor); 261 | } 262 | else 263 | { 264 | mainColor = allocimagemix(display,foregroundColor,foregroundColor); 265 | } 266 | 267 | switch(CurMem) 268 | { 269 | case M0: 270 | curfont=plato_font; 271 | offset=-32; 272 | break; 273 | case M1: 274 | curfont=plato_font; 275 | offset=64; 276 | break; 277 | case M2: 278 | curfont=fontm23; 279 | offset=-32; 280 | break; 281 | case M3: 282 | curfont=fontm23; 283 | offset=32; 284 | break; 285 | } 286 | 287 | x=Coord->x; 288 | 289 | if (ModeBold) 290 | y=((Coord->y+30)^0x1FF)&0x1FF; 291 | else 292 | y=((Coord->y+15)^0x1FF)&0x1FF; 293 | 294 | if (FastText==padF) 295 | { 296 | goto chardraw_with_fries; 297 | } 298 | 299 | px=&x; 300 | py=&y; 301 | 302 | USED(px); 303 | USED(py); 304 | 305 | /* the diet chardraw routine - fast text output. */ 306 | 307 | for (i=0;ix+=width; 411 | x+=width; 412 | y-=height; 413 | } 414 | 415 | freeimage(mainColor); 416 | freeimage(altColor); 417 | 418 | return; 419 | } 420 | 421 | /** 422 | * screen_tty_char - Called to plot chars when in tty mode 423 | */ 424 | void screen_tty_char(padByte theChar) 425 | { 426 | if ((theChar >= 0x20) && (theChar < 0x7F)) { 427 | screen_char_draw(&TTYLoc, &theChar, 1); 428 | TTYLoc.x += CharWide; 429 | } 430 | else if (theChar == 0x0b) /* Vertical Tab */ 431 | { 432 | TTYLoc.y += CharHigh; 433 | } 434 | else if ((theChar == 0x08) && (TTYLoc.x > 7))/* backspace */ 435 | { 436 | TTYLoc.x -= CharWide; 437 | } 438 | else if (theChar == 0x0A)/* line feed */ 439 | TTYLoc.y -= CharHigh; 440 | else if (theChar == 0x0D)/* carriage return */ 441 | TTYLoc.x = 0; 442 | 443 | if (TTYLoc.x + CharWide > 511) {/* wrap at right side */ 444 | TTYLoc.x = 0; 445 | TTYLoc.y -= CharHigh; 446 | } 447 | 448 | if (TTYLoc.y < 0) { 449 | TTYLoc.y=495; 450 | } 451 | } 452 | 453 | /** 454 | * screen_foreground - Called to set foreground color. 455 | */ 456 | void screen_foreground(padRGB* theColor) 457 | { 458 | foregroundColor = ((theColor->red & 0xff) << 24) + ((theColor->green & 0xff) << 16) + ((theColor->blue & 0xff) << 8) + 0xFF; 459 | } 460 | 461 | /** 462 | * screen_background - Called to set foreground color. 463 | */ 464 | void screen_background(padRGB* theColor) 465 | { 466 | backgroundColor = ((theColor->red & 0xff) << 24) + ((theColor->green & 0xff) << 16) + ((theColor->blue & 0xff) << 8) + 0xFF; 467 | } 468 | 469 | /** 470 | * screen_get_pixel - Get pixel from view. 471 | * This routine assumes an image type of RGB24. The alpha channel doesn't get stored, 472 | * but is premultiplied in the color components. Since PLATOTERM does not use any alpha except 0xFF, 473 | * we can simply shift everything over by 8, and OR in the alpha value of 0xFF, so that colors will match. 474 | */ 475 | unsigned long screen_get_pixel(int x, int y) 476 | { 477 | /* Union to make manipulation easier. */ 478 | union 479 | { 480 | unsigned char data[4]; 481 | unsigned long color; 482 | } _px; 483 | 484 | /* Retrieve color data for single pixel from image */ 485 | unloadimage(view,Rect(x,y,x+1,y+1),_px.data,sizeof(_px.data)); 486 | 487 | /* correct for missing alpha value. */ 488 | _px.color <<= 8; 489 | _px.color |= 0xFF; 490 | 491 | return _px.color; 492 | } 493 | 494 | /** 495 | * Recursive flood fill 496 | */ 497 | void _screen_paint(int x,int y,unsigned long oldpixel,unsigned long newpixel) 498 | { 499 | unsigned long p = screen_get_pixel(x,y); 500 | Image* c = allocimagemix(display, newpixel, newpixel); 501 | Rectangle r; 502 | 503 | r.min.x=r.max.x=x; 504 | r.min.y=r.max.y=y; 505 | r.max.x++; 506 | r.max.y++; 507 | 508 | if (p != oldpixel) 509 | return; 510 | if (p == newpixel) 511 | return; 512 | if (p == oldpixel) 513 | draw(view,r,c,nil,ZP); 514 | 515 | freeimage(c); 516 | screen_update_view(); 517 | 518 | _screen_paint(x-1,y,oldpixel,newpixel); 519 | _screen_paint(x+1,y,oldpixel,newpixel); 520 | _screen_paint(x,y-1,oldpixel,newpixel); 521 | _screen_paint(x,y+1,oldpixel,newpixel); 522 | } 523 | 524 | void screen_paint(padPt *Coord) 525 | { 526 | int x = Coord->x; 527 | int y = Coord->y^0x1FF; 528 | unsigned long oldpixel; 529 | 530 | /* oldpixel = screen_get_pixel(x,y); 531 | _screen_paint(x,y,oldpixel,foregroundColor); */ 532 | } 533 | 534 | /** 535 | * screen_done() 536 | * Close down TGI 537 | */ 538 | void screen_done(void) 539 | { 540 | if (view != nil) 541 | freeimage(view); 542 | 543 | closedisplay(display); 544 | } 545 | -------------------------------------------------------------------------------- /screen.h: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * screen.c - Screen drawing functions 13 | */ 14 | 15 | #ifndef SCREEN_H 16 | #define SCREEN_H 17 | 18 | #include "protocol.h" 19 | 20 | void screen_init(void); 21 | void screen_update_view(void); 22 | void screen_main(void); 23 | void screen_wait(void); 24 | void screen_beep(void); 25 | void screen_clear(void); 26 | void screen_set_pen_mode(void); 27 | void screen_block_draw(padPt *Coord1, padPt *Coord2); 28 | void screen_dot_draw(padPt* Coord); 29 | void screen_line_draw(padPt *Coord1, padPt *Coord2); 30 | void screen_char_draw(padPt *Coord, unsigned char *ch, unsigned char count); 31 | void screen_tty_char(padByte theChar); 32 | unsigned long screen_color_match(padRGB *platocolor); 33 | void screen_foreground(padRGB* theColor); 34 | void screen_background(padRGB* theColor); 35 | void screen_paint(padPt *Coord); 36 | void screen_done(void); 37 | 38 | #endif /* SCREEN_H */ 39 | -------------------------------------------------------------------------------- /splash.h: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * splash.h - PLATOTERM splash data 13 | */ 14 | 15 | #ifndef SPLASH_H 16 | #define SPLASH_H 17 | 18 | #include "protocol.h" 19 | padByte splash[] = 20 | { 21 | 0x1b, 22 | 0x02, 23 | 0x1b, 24 | 0x0c, 25 | 0x1b, 26 | 0x12, 27 | 0x1b, 28 | 0xd1, 29 | 0xc0, 30 | 0x50, 31 | 0xc0, 32 | 0x1b, 33 | 0xe1, 34 | 0xff, 35 | 0xff, 36 | 0xff, 37 | 0xff, 38 | 0xff, 39 | 0xff, 40 | 0xff, 41 | 0xff, 42 | 0x1b, 43 | 0xe2, 44 | 0xc0, 45 | 0xc0, 46 | 0xc0, 47 | 0xc0, 48 | 0x1b, 49 | 0x0c, 50 | 0x1b, 51 | 0x12, 52 | 0x1d, 53 | 0xaf, 54 | 0xf0, 55 | 0xc0, 56 | 0x1b, 57 | 0x5a, 58 | 0x1b, 59 | 0xd1, 60 | 0xc0, 61 | 0x44, 62 | 0x41, 63 | 0x1b, 64 | 0xd1, 65 | 0xc0, 66 | 0x50, 67 | 0xc0, 68 | 0x1b, 69 | 0x0c, 70 | 0x1b, 71 | 0x12, 72 | 0x1b, 73 | 0xd1, 74 | 0xc0, 75 | 0x50, 76 | 0xc0, 77 | 0x1b, 78 | 0x5a, 79 | 0x1b, 80 | 0xe1, 81 | 0xff, 82 | 0xff, 83 | 0xff, 84 | 0xff, 85 | 0xff, 86 | 0xff, 87 | 0xff, 88 | 0xff, 89 | 0x1b, 90 | 0xe2, 91 | 0xeb, 92 | 0x44, 93 | 0x59, 94 | 0x41, 95 | 0x1b, 96 | 0xd1, 97 | 0xc0, 98 | 0x50, 99 | 0xc0, 100 | 0x1b, 101 | 0x0c, 102 | 0x1b, 103 | 0x12, 104 | 0x1d, 105 | 0x28, 106 | 0x7e, 107 | 0xa5, 108 | 0xc0, 109 | 0x1b, 110 | 0x5a, 111 | 0x1b, 112 | 0xd1, 113 | 0xc0, 114 | 0x50, 115 | 0xc0, 116 | 0x1d, 117 | 0xa6, 118 | 0x6c, 119 | 0x24, 120 | 0xcc, 121 | 0x2b, 122 | 0xfa, 123 | 0xcc, 124 | 0xfa, 125 | 0xa5, 126 | 0x50, 127 | 0xa6, 128 | 0x6c, 129 | 0x50, 130 | 0x6c, 131 | 0x24, 132 | 0xcc, 133 | 0x1d, 134 | 0x6c, 135 | 0x28, 136 | 0x4e, 137 | 0xee, 138 | 0x27, 139 | 0x5a, 140 | 0xf0, 141 | 0x50, 142 | 0x74, 143 | 0x48, 144 | 0xfc, 145 | 0xa6, 146 | 0xde, 147 | 0x27, 148 | 0xe2, 149 | 0xd8, 150 | 0x6c, 151 | 0x50, 152 | 0x74, 153 | 0xca, 154 | 0xfa, 155 | 0x48, 156 | 0x28, 157 | 0xe2, 158 | 0x44, 159 | 0xf0, 160 | 0xc0, 161 | 0xa9, 162 | 0x60, 163 | 0xa5, 164 | 0x5c, 165 | 0x66, 166 | 0x5c, 167 | 0xee, 168 | 0x5c, 169 | 0x78, 170 | 0xde, 171 | 0xaa, 172 | 0x60, 173 | 0xa6, 174 | 0xc0, 175 | 0xe8, 176 | 0x44, 177 | 0xf0, 178 | 0x48, 179 | 0x78, 180 | 0x4e, 181 | 0x7e, 182 | 0xd2, 183 | 0x2b, 184 | 0xe2, 185 | 0x56, 186 | 0xe8, 187 | 0x5c, 188 | 0x6c, 189 | 0x27, 190 | 0x42, 191 | 0xf0, 192 | 0x48, 193 | 0x74, 194 | 0x4e, 195 | 0x78, 196 | 0xd8, 197 | 0xfc, 198 | 0x28, 199 | 0xc6, 200 | 0x7e, 201 | 0x56, 202 | 0x5c, 203 | 0xfc, 204 | 0xa9, 205 | 0x48, 206 | 0xfa, 207 | 0xd4, 208 | 0xf6, 209 | 0xaa, 210 | 0xc0, 211 | 0x72, 212 | 0xc6, 213 | 0xee, 214 | 0xca, 215 | 0x6a, 216 | 0x50, 217 | 0xe4, 218 | 0x56, 219 | 0xaa, 220 | 0x7e, 221 | 0x5c, 222 | 0x74, 223 | 0x2b, 224 | 0x42, 225 | 0x6a, 226 | 0x48, 227 | 0x60, 228 | 0xcc, 229 | 0xa9, 230 | 0x74, 231 | 0x50, 232 | 0xf0, 233 | 0x50, 234 | 0x66, 235 | 0x50, 236 | 0x28, 237 | 0xfc, 238 | 0x50, 239 | 0xf0, 240 | 0x4e, 241 | 0xe8, 242 | 0xcc, 243 | 0x27, 244 | 0x7e, 245 | 0x48, 246 | 0xf6, 247 | 0x44, 248 | 0xee, 249 | 0xaa, 250 | 0xde, 251 | 0x66, 252 | 0xd8, 253 | 0xa6, 254 | 0x7e, 255 | 0x50, 256 | 0x78, 257 | 0xca, 258 | 0x72, 259 | 0xc0, 260 | 0xee, 261 | 0xa9, 262 | 0xd8, 263 | 0x6c, 264 | 0x4e, 265 | 0x6c, 266 | 0x28, 267 | 0x4e, 268 | 0x1d, 269 | 0xaa, 270 | 0x78, 271 | 0x4e, 272 | 0x5a, 273 | 0xf6, 274 | 0xa9, 275 | 0x44, 276 | 0x74, 277 | 0xcc, 278 | 0xee, 279 | 0x56, 280 | 0xe8, 281 | 0x5c, 282 | 0x60, 283 | 0xaa, 284 | 0x42, 285 | 0xa9, 286 | 0x78, 287 | 0xc6, 288 | 0xf0, 289 | 0x48, 290 | 0xe8, 291 | 0xca, 292 | 0x28, 293 | 0x7e, 294 | 0xca, 295 | 0x72, 296 | 0x48, 297 | 0x6a, 298 | 0x44, 299 | 0xe4, 300 | 0xc0, 301 | 0x27, 302 | 0x7e, 303 | 0xa9, 304 | 0x5c, 305 | 0xfa, 306 | 0x56, 307 | 0xf6, 308 | 0xd2, 309 | 0x72, 310 | 0x48, 311 | 0xf0, 312 | 0xc0, 313 | 0xee, 314 | 0x28, 315 | 0xd8, 316 | 0x50, 317 | 0xf0, 318 | 0xc6, 319 | 0x74, 320 | 0x27, 321 | 0xde, 322 | 0x78, 323 | 0xd8, 324 | 0xfc, 325 | 0xd2, 326 | 0x28, 327 | 0xe2, 328 | 0xcc, 329 | 0xe8, 330 | 0x48, 331 | 0x6c, 332 | 0xc6, 333 | 0xf0, 334 | 0x44, 335 | 0x78, 336 | 0x42, 337 | 0xa9, 338 | 0x60, 339 | 0x42, 340 | 0x6c, 341 | 0x42, 342 | 0x78, 343 | 0xc6, 344 | 0xaa, 345 | 0x60, 346 | 0xca, 347 | 0x66, 348 | 0x50, 349 | 0x6a, 350 | 0xd4, 351 | 0xee, 352 | 0xd8, 353 | 0xf0, 354 | 0x5a, 355 | 0x72, 356 | 0x5c, 357 | 0x74, 358 | 0x28, 359 | 0xc0, 360 | 0xf6, 361 | 0xc6, 362 | 0x78, 363 | 0x4e, 364 | 0x1d, 365 | 0x28, 366 | 0x7e, 367 | 0xac, 368 | 0x50, 369 | 0x1d, 370 | 0xa5, 371 | 0xee, 372 | 0xa3, 373 | 0x50, 374 | 0xee, 375 | 0xac, 376 | 0x41, 377 | 0xac, 378 | 0x41, 379 | 0xee, 380 | 0xa3, 381 | 0x50, 382 | 0xa5, 383 | 0x50, 384 | 0x1d, 385 | 0xed, 386 | 0xcf, 387 | 0xed, 388 | 0xac, 389 | 0x42, 390 | 0xac, 391 | 0x6f, 392 | 0x42, 393 | 0x6f, 394 | 0xa3, 395 | 0xcf, 396 | 0xa5, 397 | 0xed, 398 | 0xcf, 399 | 0x1d, 400 | 0x6c, 401 | 0x4e, 402 | 0x6c, 403 | 0xac, 404 | 0xc3, 405 | 0xac, 406 | 0xf0, 407 | 0xc3, 408 | 0xf0, 409 | 0xa3, 410 | 0x4e, 411 | 0xa5, 412 | 0x6c, 413 | 0x4e, 414 | 0x1d, 415 | 0xeb, 416 | 0x4d, 417 | 0xeb, 418 | 0xac, 419 | 0x44, 420 | 0xac, 421 | 0x71, 422 | 0x44, 423 | 0x71, 424 | 0xa3, 425 | 0x4d, 426 | 0xa5, 427 | 0xeb, 428 | 0x4d, 429 | 0x1d, 430 | 0x6a, 431 | 0xcc, 432 | 0x6a, 433 | 0xac, 434 | 0xc5, 435 | 0xac, 436 | 0x72, 437 | 0xc5, 438 | 0x72, 439 | 0xa3, 440 | 0xcc, 441 | 0xa5, 442 | 0x6a, 443 | 0xcc, 444 | 0x1d, 445 | 0x69, 446 | 0x4b, 447 | 0x69, 448 | 0xac, 449 | 0xc6, 450 | 0xac, 451 | 0xf3, 452 | 0xc6, 453 | 0xf3, 454 | 0xa3, 455 | 0x4b, 456 | 0xa5, 457 | 0x69, 458 | 0x4b, 459 | 0x1b, 460 | 0xe1, 461 | 0xff, 462 | 0xff, 463 | 0xff, 464 | 0xff, 465 | 0xff, 466 | 0xff, 467 | 0xff, 468 | 0xff, 469 | 0x1b, 470 | 0xe2, 471 | 0xff, 472 | 0xff, 473 | 0xff, 474 | 0xff, 475 | 0xff, 476 | 0xff, 477 | 0xff, 478 | 0xff, 479 | 0x1d, 480 | 0x28, 481 | 0xe4, 482 | 0x24, 483 | 0xde, 484 | 0x1b, 485 | 0x63, 486 | 0xc0, 487 | 0xc0, 488 | 0x1d, 489 | 0x65, 490 | 0xa6, 491 | 0x4d, 492 | 0x1b, 493 | 0x63, 494 | 0xc0, 495 | 0xc0, 496 | 0x1b, 497 | 0xe1, 498 | 0xff, 499 | 0xff, 500 | 0xff, 501 | 0xff, 502 | 0xff, 503 | 0xff, 504 | 0xff, 505 | 0xff, 506 | 0x1b, 507 | 0xe2, 508 | 0xeb, 509 | 0x44, 510 | 0x59, 511 | 0x41, 512 | 0x1b, 513 | 0xd1, 514 | 0xc0, 515 | 0x50, 516 | 0xc0, 517 | 0x1d, 518 | 0xa3, 519 | 0x7e, 520 | 0xa3, 521 | 0x50, 522 | 0x1b, 523 | 0x5a, 524 | 0x1b, 525 | 0x12, 526 | 0x1d, 527 | 0x6f, 528 | 0xcc, 529 | 0x24, 530 | 0xf6, 531 | 0xcc, 532 | 0x53, 533 | 0xa3, 534 | 0x6f, 535 | 0x53, 536 | 0xcc, 537 | 0x1d, 538 | 0x5a, 539 | 0x24, 540 | 0x71, 541 | 0x5a, 542 | 0xf3, 543 | 0x5a, 544 | 0x5a, 545 | 0x74, 546 | 0xdb, 547 | 0xdb, 548 | 0xf5, 549 | 0x5c, 550 | 0x5c, 551 | 0xf6, 552 | 0xdd, 553 | 0xf6, 554 | 0x24, 555 | 0x47, 556 | 0x48, 557 | 0xf5, 558 | 0xca, 559 | 0x4b, 560 | 0x74, 561 | 0xcc, 562 | 0x4d, 563 | 0xf3, 564 | 0x4e, 565 | 0x4e, 566 | 0x72, 567 | 0xcf, 568 | 0x71, 569 | 0x50, 570 | 0x50, 571 | 0xf0, 572 | 0x50, 573 | 0x6f, 574 | 0xd1, 575 | 0xee, 576 | 0xd1, 577 | 0xed, 578 | 0xd2, 579 | 0x6c, 580 | 0xd2, 581 | 0xeb, 582 | 0xd2, 583 | 0x69, 584 | 0xd2, 585 | 0xe7, 586 | 0xd1, 587 | 0x66, 588 | 0xd1, 589 | 0x65, 590 | 0x50, 591 | 0xe4, 592 | 0x50, 593 | 0x63, 594 | 0xcf, 595 | 0xe2, 596 | 0x4e, 597 | 0x4d, 598 | 0x4b, 599 | 0xe1, 600 | 0x4b, 601 | 0xca, 602 | 0xa3, 603 | 0x6f, 604 | 0x55, 605 | 0xca, 606 | 0x24, 607 | 0x60, 608 | 0xc3, 609 | 0xe1, 610 | 0x42, 611 | 0xe2, 612 | 0x42, 613 | 0x63, 614 | 0xc3, 615 | 0xe4, 616 | 0x44, 617 | 0x65, 618 | 0xc5, 619 | 0xc5, 620 | 0x66, 621 | 0xc5, 622 | 0xc6, 623 | 0xe7, 624 | 0x48, 625 | 0xe8, 626 | 0xc9, 627 | 0x69, 628 | 0xc9, 629 | 0xeb, 630 | 0xc9, 631 | 0xed, 632 | 0x48, 633 | 0x47, 634 | 0xee, 635 | 0xc6, 636 | 0x42, 637 | 0xa3, 638 | 0x6f, 639 | 0x42, 640 | 0x6f, 641 | 0xa3, 642 | 0x5a, 643 | 0x1d, 644 | 0x6f, 645 | 0x24, 646 | 0x55, 647 | 0x24, 648 | 0xf3, 649 | 0xa5, 650 | 0xc0, 651 | 0xc0, 652 | 0x74, 653 | 0x41, 654 | 0xf5, 655 | 0x42, 656 | 0xf6, 657 | 0x42, 658 | 0x44, 659 | 0x77, 660 | 0xc5, 661 | 0xc5, 662 | 0xf6, 663 | 0x47, 664 | 0xf5, 665 | 0x48, 666 | 0x74, 667 | 0xc9, 668 | 0xf3, 669 | 0xca, 670 | 0xa3, 671 | 0x6f, 672 | 0x55, 673 | 0xcc, 674 | 0x77, 675 | 0xca, 676 | 0xc0, 677 | 0x6f, 678 | 0x24, 679 | 0xdd, 680 | 0x55, 681 | 0x1d, 682 | 0x7e, 683 | 0xa5, 684 | 0x42, 685 | 0x24, 686 | 0xee, 687 | 0xc5, 688 | 0xa3, 689 | 0x7e, 690 | 0x48, 691 | 0x42, 692 | 0x1d, 693 | 0x6f, 694 | 0x59, 695 | 0x24, 696 | 0xee, 697 | 0x59, 698 | 0xd2, 699 | 0xf6, 700 | 0xd2, 701 | 0xf6, 702 | 0xa6, 703 | 0x48, 704 | 0xee, 705 | 0x48, 706 | 0x41, 707 | 0xa3, 708 | 0x6f, 709 | 0x41, 710 | 0x6f, 711 | 0xa5, 712 | 0x59, 713 | 0x1d, 714 | 0x7e, 715 | 0xa6, 716 | 0xd1, 717 | 0x1d, 718 | 0x6f, 719 | 0x44, 720 | 0x24, 721 | 0xf3, 722 | 0xcf, 723 | 0xcf, 724 | 0x74, 725 | 0x50, 726 | 0xf5, 727 | 0xd1, 728 | 0xf6, 729 | 0xd1, 730 | 0x53, 731 | 0x77, 732 | 0xd4, 733 | 0xd4, 734 | 0xf6, 735 | 0x56, 736 | 0xf5, 737 | 0xd7, 738 | 0x74, 739 | 0xd8, 740 | 0xf3, 741 | 0x59, 742 | 0xa3, 743 | 0x6f, 744 | 0x27, 745 | 0x44, 746 | 0x6f, 747 | 0xa6, 748 | 0xdb, 749 | 0x77, 750 | 0x59, 751 | 0xcf, 752 | 0x6f, 753 | 0xcc, 754 | 0x44, 755 | 0x1d, 756 | 0x7e, 757 | 0xd1, 758 | 0x24, 759 | 0xee, 760 | 0xd4, 761 | 0xa3, 762 | 0x7e, 763 | 0xd7, 764 | 0xd1, 765 | 0x1d, 766 | 0x6f, 767 | 0x27, 768 | 0x5c, 769 | 0xd8, 770 | 0xf0, 771 | 0x55, 772 | 0x71, 773 | 0x53, 774 | 0x72, 775 | 0xd1, 776 | 0x74, 777 | 0x50, 778 | 0xf6, 779 | 0x4e, 780 | 0x78, 781 | 0x4d, 782 | 0xf9, 783 | 0xcc, 784 | 0x7b, 785 | 0x4b, 786 | 0x7e, 787 | 0xca, 788 | 0x24, 789 | 0xe2, 790 | 0xc9, 791 | 0xc9, 792 | 0xe4, 793 | 0xc9, 794 | 0xe7, 795 | 0xca, 796 | 0xe8, 797 | 0xca, 798 | 0x6a, 799 | 0x4b, 800 | 0x6c, 801 | 0xcc, 802 | 0xee, 803 | 0x4d, 804 | 0x6f, 805 | 0x4e, 806 | 0xf0, 807 | 0xcf, 808 | 0x72, 809 | 0xd1, 810 | 0xf3, 811 | 0xd2, 812 | 0x53, 813 | 0x74, 814 | 0x55, 815 | 0xf5, 816 | 0xd7, 817 | 0xf6, 818 | 0x5a, 819 | 0x77, 820 | 0xde, 821 | 0xde, 822 | 0xf6, 823 | 0x28, 824 | 0x41, 825 | 0x44, 826 | 0xf5, 827 | 0x47, 828 | 0x74, 829 | 0x48, 830 | 0xf3, 831 | 0xc9, 832 | 0x72, 833 | 0xca, 834 | 0x71, 835 | 0xcc, 836 | 0x6f, 837 | 0x4d, 838 | 0xed, 839 | 0xcf, 840 | 0xeb, 841 | 0x50, 842 | 0xe8, 843 | 0xd1, 844 | 0x66, 845 | 0xd2, 846 | 0x65, 847 | 0xd2, 848 | 0xe2, 849 | 0xd2, 850 | 0xe1, 851 | 0xd2, 852 | 0xa3, 853 | 0x7e, 854 | 0xd1, 855 | 0x7d, 856 | 0xd1, 857 | 0xfa, 858 | 0x50, 859 | 0x78, 860 | 0xcf, 861 | 0x77, 862 | 0x4e, 863 | 0xf5, 864 | 0xcc, 865 | 0xf3, 866 | 0xca, 867 | 0x71, 868 | 0xc9, 869 | 0xf0, 870 | 0x47, 871 | 0x6f, 872 | 0xc5, 873 | 0xc3, 874 | 0x6f, 875 | 0x27, 876 | 0x5c, 877 | 0x1d, 878 | 0x24, 879 | 0xee, 880 | 0x5c, 881 | 0xde, 882 | 0xed, 883 | 0x28, 884 | 0xc0, 885 | 0x42, 886 | 0x6c, 887 | 0x44, 888 | 0x6a, 889 | 0xc6, 890 | 0xe8, 891 | 0x47, 892 | 0xe7, 893 | 0x48, 894 | 0x65, 895 | 0xc9, 896 | 0x63, 897 | 0xc9, 898 | 0xe2, 899 | 0xc9, 900 | 0xa3, 901 | 0xff, 902 | 0xff, 903 | 0xc9, 904 | 0x7d, 905 | 0x48, 906 | 0xfc, 907 | 0x47, 908 | 0xfa, 909 | 0xc6, 910 | 0xf9, 911 | 0x44, 912 | 0x78, 913 | 0xc3, 914 | 0x77, 915 | 0x41, 916 | 0x77, 917 | 0x27, 918 | 0x5f, 919 | 0xde, 920 | 0xdd, 921 | 0x5a, 922 | 0x78, 923 | 0x59, 924 | 0xf9, 925 | 0xd7, 926 | 0xfa, 927 | 0x56, 928 | 0x7b, 929 | 0xd4, 930 | 0x7d, 931 | 0x53, 932 | 0x53, 933 | 0x7e, 934 | 0x53, 935 | 0x24, 936 | 0x60, 937 | 0xd2, 938 | 0xe2, 939 | 0xd2, 940 | 0xe4, 941 | 0xd2, 942 | 0xe7, 943 | 0x53, 944 | 0xe8, 945 | 0xd4, 946 | 0x6a, 947 | 0x55, 948 | 0xeb, 949 | 0x56, 950 | 0x6c, 951 | 0xd7, 952 | 0xd8, 953 | 0xed, 954 | 0xd8, 955 | 0x59, 956 | 0x5a, 957 | 0xee, 958 | 0x5c, 959 | 0x1d, 960 | 0xa3, 961 | 0x7e, 962 | 0x28, 963 | 0x5c, 964 | 0x1b, 965 | 0x59, 966 | 0x50, 967 | 0x41, 968 | 0xc0, 969 | 0x1d, 970 | 0x6f, 971 | 0x55, 972 | 0x24, 973 | 0xf3, 974 | 0x55, 975 | 0x74, 976 | 0x55, 977 | 0x56, 978 | 0xf5, 979 | 0x56, 980 | 0xf6, 981 | 0xd7, 982 | 0xd8, 983 | 0x77, 984 | 0x5a, 985 | 0xdb, 986 | 0xf6, 987 | 0x5c, 988 | 0xdd, 989 | 0xf5, 990 | 0xde, 991 | 0x74, 992 | 0xde, 993 | 0xa3, 994 | 0x7b, 995 | 0xa9, 996 | 0x48, 997 | 0xc9, 998 | 0x24, 999 | 0xf6, 1000 | 0xc9, 1001 | 0xd1, 1002 | 0xa3, 1003 | 0xf3, 1004 | 0xd1, 1005 | 0x72, 1006 | 0x50, 1007 | 0x71, 1008 | 0x50, 1009 | 0xf0, 1010 | 0xcf, 1011 | 0x6f, 1012 | 0x4e, 1013 | 0x4d, 1014 | 0x48, 1015 | 0xf0, 1016 | 0x47, 1017 | 0x71, 1018 | 0xc6, 1019 | 0x24, 1020 | 0x69, 1021 | 0x28, 1022 | 0xdd, 1023 | 0x5c, 1024 | 0xa3, 1025 | 0x6f, 1026 | 0x5c, 1027 | 0x55, 1028 | 0x1d, 1029 | 0xf3, 1030 | 0xa9, 1031 | 0x53, 1032 | 0x24, 1033 | 0xf5, 1034 | 0x53, 1035 | 0xdb, 1036 | 0xa3, 1037 | 0xf6, 1038 | 0xdb, 1039 | 0xf6, 1040 | 0xaa, 1041 | 0xc6, 1042 | 0x6f, 1043 | 0xc6, 1044 | 0x6f, 1045 | 0xa9, 1046 | 0xd8, 1047 | 0x56, 1048 | 0xf0, 1049 | 0x55, 1050 | 0x71, 1051 | 0xd4, 1052 | 0xf3, 1053 | 0x53, 1054 | 0x1d, 1055 | 0x6f, 1056 | 0xaa, 1057 | 0x4b, 1058 | 0x24, 1059 | 0xf6, 1060 | 0x4b, 1061 | 0xd2, 1062 | 0xa3, 1063 | 0x6f, 1064 | 0xd2, 1065 | 0x4b, 1066 | 0x1d, 1067 | 0xd4, 1068 | 0x24, 1069 | 0xf3, 1070 | 0xd4, 1071 | 0x74, 1072 | 0xd4, 1073 | 0x55, 1074 | 0xf5, 1075 | 0x55, 1076 | 0xf6, 1077 | 0x56, 1078 | 0xd7, 1079 | 0x77, 1080 | 0x59, 1081 | 0x5a, 1082 | 0xf6, 1083 | 0xdb, 1084 | 0x5c, 1085 | 0xf5, 1086 | 0xdd, 1087 | 0x74, 1088 | 0xdd, 1089 | 0xa3, 1090 | 0x7b, 1091 | 0x2b, 1092 | 0x47, 1093 | 0x48, 1094 | 0x24, 1095 | 0xf6, 1096 | 0x48, 1097 | 0x50, 1098 | 0xa3, 1099 | 0xf3, 1100 | 0x50, 1101 | 0x72, 1102 | 0xcf, 1103 | 0x71, 1104 | 0xcf, 1105 | 0xf0, 1106 | 0x4e, 1107 | 0x6f, 1108 | 0x4d, 1109 | 0xcc, 1110 | 0x47, 1111 | 0xf0, 1112 | 0xc6, 1113 | 0x71, 1114 | 0xc5, 1115 | 0x24, 1116 | 0x69, 1117 | 0xaa, 1118 | 0x5c, 1119 | 0xdb, 1120 | 0xa3, 1121 | 0x6f, 1122 | 0xdb, 1123 | 0xd4, 1124 | 0x1d, 1125 | 0x7e, 1126 | 0x2b, 1127 | 0xd8, 1128 | 0x1d, 1129 | 0xf6, 1130 | 0x53, 1131 | 0x24, 1132 | 0x71, 1133 | 0x53, 1134 | 0x72, 1135 | 0x53, 1136 | 0xf3, 1137 | 0xd4, 1138 | 0x74, 1139 | 0xd4, 1140 | 0xf5, 1141 | 0x55, 1142 | 0x55, 1143 | 0xf6, 1144 | 0x56, 1145 | 0xd8, 1146 | 0xf6, 1147 | 0xac, 1148 | 0xc6, 1149 | 0xee, 1150 | 0xc6, 1151 | 0xee, 1152 | 0x2b, 1153 | 0x5a, 1154 | 0xe7, 1155 | 0x5a, 1156 | 0xe7, 1157 | 0xac, 1158 | 0xc6, 1159 | 0x60, 1160 | 0xc6, 1161 | 0x60, 1162 | 0x2b, 1163 | 0x5a, 1164 | 0xa3, 1165 | 0x77, 1166 | 0x5a, 1167 | 0x77, 1168 | 0xac, 1169 | 0xc6, 1170 | 0x6f, 1171 | 0xc6, 1172 | 0x6f, 1173 | 0x2b, 1174 | 0xd8, 1175 | 0xd7, 1176 | 0xf0, 1177 | 0x56, 1178 | 0x55, 1179 | 0x71, 1180 | 0xd4, 1181 | 0x72, 1182 | 0x53, 1183 | 0xf3, 1184 | 0x53, 1185 | 0xf6, 1186 | 0x53, 1187 | 0x1d, 1188 | 0x7e, 1189 | 0xac, 1190 | 0x53, 1191 | 0x1b, 1192 | 0xe1, 1193 | 0xff, 1194 | 0xff, 1195 | 0xff, 1196 | 0xff, 1197 | 0xff, 1198 | 0xff, 1199 | 0xff, 1200 | 0xff, 1201 | 0x1b, 1202 | 0xe2, 1203 | 0xff, 1204 | 0xff, 1205 | 0xff, 1206 | 0xff, 1207 | 0xff, 1208 | 0xff, 1209 | 0xff, 1210 | 0xff, 1211 | 0x1d, 1212 | 0x7d, 1213 | 0xa3, 1214 | 0x50, 1215 | 0x1b, 1216 | 0x63, 1217 | 0xc0, 1218 | 0xc0, 1219 | 0x1d, 1220 | 0x77, 1221 | 0x24, 1222 | 0xcc, 1223 | 0x1b, 1224 | 0x63, 1225 | 0xc0, 1226 | 0xc0, 1227 | 0x1d, 1228 | 0x7b, 1229 | 0xde, 1230 | 0x1b, 1231 | 0x63, 1232 | 0xc0, 1233 | 0xc0, 1234 | 0x1d, 1235 | 0x78, 1236 | 0xa5, 1237 | 0xdd, 1238 | 0x1b, 1239 | 0x63, 1240 | 0xc0, 1241 | 0xc0, 1242 | 0x1d, 1243 | 0xfa, 1244 | 0xa6, 1245 | 0x4d, 1246 | 0x1b, 1247 | 0x63, 1248 | 0xc0, 1249 | 0xc0, 1250 | 0x1d, 1251 | 0x72, 1252 | 0x27, 1253 | 0xde, 1254 | 0x1b, 1255 | 0x63, 1256 | 0xc0, 1257 | 0xc0, 1258 | 0x1d, 1259 | 0xf5, 1260 | 0xa9, 1261 | 0xcc, 1262 | 0x1b, 1263 | 0x63, 1264 | 0xc0, 1265 | 0xc0, 1266 | 0x1d, 1267 | 0xf3, 1268 | 0xd8, 1269 | 0x1b, 1270 | 0x63, 1271 | 0xc0, 1272 | 0xc0, 1273 | 0x1d, 1274 | 0x7b, 1275 | 0xaa, 1276 | 0xcf, 1277 | 0x1b, 1278 | 0x63, 1279 | 0xc0, 1280 | 0xc0, 1281 | 0x1d, 1282 | 0xf3, 1283 | 0x2b, 1284 | 0x4b, 1285 | 0x1b, 1286 | 0x63, 1287 | 0xc0, 1288 | 0xc0, 1289 | 0x1d, 1290 | 0x24, 1291 | 0x63, 1292 | 0xd8, 1293 | 0x1b, 1294 | 0x63, 1295 | 0xc0, 1296 | 0xc0, 1297 | 0x1d, 1298 | 0x22, 1299 | 0xf0, 1300 | 0xa6, 1301 | 0xd8, 1302 | 0x1b, 1303 | 0x5a, 1304 | 0x1b, 1305 | 0xd1, 1306 | 0xc0, 1307 | 0x50, 1308 | 0xc0, 1309 | 0x1b, 1310 | 0xe1, 1311 | 0xff, 1312 | 0xff, 1313 | 0xff, 1314 | 0xff, 1315 | 0xff, 1316 | 0xff, 1317 | 0xff, 1318 | 0xff, 1319 | 0x1b, 1320 | 0xe2, 1321 | 0xeb, 1322 | 0x44, 1323 | 0x59, 1324 | 0x41, 1325 | 0x9f, 1326 | 0x1b, 1327 | 0x12, 1328 | 0x41, 1329 | 0xee, 1330 | 0xa0, 1331 | 0x6f, 1332 | 0xee, 1333 | 0x2d, 1334 | 0x6c, 1335 | 0x69, 1336 | 0xee, 1337 | 0x65, 1338 | 0xa0, 1339 | 0xf3, 1340 | 0x65, 1341 | 0x72, 1342 | 0xf6, 1343 | 0x69, 1344 | 0x63, 1345 | 0x65, 1346 | 0xa0, 1347 | 0x66, 1348 | 0x6f, 1349 | 0x72, 1350 | 0x8d, 1351 | 0xd2, 1352 | 0x65, 1353 | 0x74, 1354 | 0x72, 1355 | 0x6f, 1356 | 0x2d, 1357 | 0xc3, 1358 | 0x6f, 1359 | 0xed, 1360 | 0xf0, 1361 | 0xf5, 1362 | 0x74, 1363 | 0x69, 1364 | 0xee, 1365 | 0xe7, 1366 | 0xa0, 1367 | 0xc5, 1368 | 0xee, 1369 | 0x74, 1370 | 0xe8, 1371 | 0xf5, 1372 | 0xf3, 1373 | 0x69, 1374 | 0xe1, 1375 | 0xf3, 1376 | 0x74, 1377 | 0xf3, 1378 | 0x1d, 1379 | 0xaf, 1380 | 0xf0, 1381 | 0xa0, 1382 | 0xc0, 1383 | 0x1b, 1384 | 0x5a, 1385 | 0x1b, 1386 | 0x59, 1387 | 0x50, 1388 | 0x41, 1389 | 0xc0, 1390 | 0x1b, 1391 | 0x03 1392 | }; 1393 | 1394 | #endif /* SPLASH_H*/ 1395 | -------------------------------------------------------------------------------- /terminal.c: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * terminal.c - Terminal state machine functions 13 | */ 14 | 15 | /* Some functions are intentionally stubbed. */ 16 | 17 | #include 18 | #include 19 | #include "terminal.h" 20 | #include "screen.h" 21 | 22 | #define TRUE 1 23 | #define FALSE 0 24 | 25 | /** 26 | * ASCII Features to return in Features 27 | */ 28 | #define ASC_ZFGT 0x01 29 | #define ASC_ZPCKEYS 0x02 30 | #define ASC_ZKERMIT 0x04 31 | #define ASC_ZWINDOW 0x08 32 | 33 | /** 34 | * protocol.c externals 35 | */ 36 | extern CharMem CurMem; 37 | extern padBool TTY; 38 | extern padBool ModeBold; 39 | extern padBool Rotate; 40 | extern padBool Reverse; 41 | extern DispMode CurMode; 42 | extern padBool FlowControl; 43 | 44 | /** 45 | * screen.c externals 46 | */ 47 | extern unsigned char CharWide; 48 | extern unsigned char CharHigh; 49 | extern padPt TTYLoc; 50 | 51 | extern unsigned char already_started; 52 | extern unsigned char fontm23[2048]; 53 | 54 | static unsigned char BTAB[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; 55 | static unsigned char u; 56 | static unsigned char curr_word; 57 | 58 | #define FONTPTR(a) (a<<4) 59 | 60 | /** 61 | * terminal_init() 62 | * Initialize terminal state 63 | */ 64 | void terminal_init() 65 | { 66 | terminal_set_tty(); 67 | } 68 | 69 | /** 70 | * terminal_initial_position() 71 | * Set terminal initial position after splash screen. 72 | */ 73 | void terminal_initial_position() 74 | { 75 | TTYLoc.x=0; 76 | TTYLoc.y=495; 77 | } 78 | 79 | /** 80 | * terminal_set_tty() - Switch to TTY mode 81 | */ 82 | void terminal_set_tty() 83 | { 84 | if (already_started) 85 | screen_clear(); 86 | TTY=TRUE; 87 | ModeBold=padF; 88 | Rotate=padF; 89 | Reverse=padF; 90 | CurMem=M0; 91 | CurMode=ModeRewrite; 92 | CharWide=8; 93 | CharHigh=16; 94 | TTYLoc.x = 0; 95 | TTYLoc.y = 495; 96 | } 97 | 98 | /** 99 | * terminal_set_plato() - Switch to PLATO mode 100 | */ 101 | void terminal_set_plato() 102 | { 103 | TTY=FALSE; 104 | screen_clear(); 105 | } 106 | 107 | /** 108 | * terminal_get_features() - Inquire about terminal ASCII features 109 | */ 110 | unsigned char terminal_get_features() 111 | { 112 | return ASC_ZFGT; /* This terminal can do Fine Grained Touch (FGT) */ 113 | } 114 | 115 | /** 116 | * terminal_get_type() - Return the appropriate terminal type 117 | */ 118 | unsigned char terminal_get_type() 119 | { 120 | return 12; /* ASCII terminal type */ 121 | } 122 | 123 | /** 124 | * terminal_get_subtype() - Return the appropriate terminal subtype 125 | */ 126 | unsigned char terminal_get_subtype() 127 | { 128 | return 1; /* ASCII terminal subtype IST-III */ 129 | } 130 | 131 | /** 132 | * terminal_get_load_file() - Return the appropriate terminal loadfile (should just be 0) 133 | */ 134 | unsigned char terminal_get_load_file() 135 | { 136 | return 0; /* This terminal does not load its resident from the PLATO system. */ 137 | } 138 | 139 | /** 140 | * terminal_get_configuration() - Return the terminal configuration 141 | */ 142 | unsigned char terminal_get_configuration() 143 | { 144 | return 0x40; /* Touch panel is present. */ 145 | } 146 | 147 | /** 148 | * terminal_get_char_address() - Return the base address of the character set. 149 | */ 150 | unsigned short terminal_get_char_address() 151 | { 152 | return 0x3000; /* What the? Shouldn't this be 0x3800? */ 153 | } 154 | 155 | /** 156 | * terminal_mem_read - Read a byte of program memory. 157 | * not needed for our terminal, but must 158 | * be decoded. 159 | */ 160 | padByte terminal_mem_read(padWord addr) 161 | { 162 | USED(addr); 163 | return (0xFF); 164 | } 165 | 166 | /** 167 | * terminal_mem_load - Write a byte to non-character memory. 168 | * not needed for our terminal, but must be decoded. 169 | */ 170 | void terminal_mem_load(padWord addr, padWord value) 171 | { 172 | USED(addr); 173 | USED(value); 174 | /* Not Implemented */ 175 | } 176 | 177 | /** 178 | * Mode5, 6, and 7 are basically stubbed. 179 | */ 180 | void terminal_mode_5(padWord value) 181 | { 182 | USED(value); 183 | } 184 | 185 | void terminal_mode_6(padWord value) 186 | { 187 | USED(value); 188 | } 189 | 190 | void terminal_mode_7(padWord value) 191 | { 192 | USED(value); 193 | } 194 | 195 | /** 196 | * terminal_ext_allow - External Input allowed. Not implemented. 197 | */ 198 | void terminal_ext_allow(padBool allow) 199 | { 200 | /* Not Implemented */ 201 | USED(allow); 202 | } 203 | 204 | /** 205 | * terminal_set_ext_in - Set which device to get input from. 206 | * Not implemented 207 | */ 208 | void terminal_set_ext_in(padWord device) 209 | { 210 | USED(device); 211 | } 212 | 213 | /** 214 | * terminal_set_ext_out - Set which device to send external data to. 215 | * Not implemented 216 | */ 217 | void terminal_set_ext_out(padWord device) 218 | { 219 | USED(device); 220 | } 221 | 222 | /** 223 | * terminal_ext_in - get an external input from selected device. 224 | * Not implemented. 225 | */ 226 | padByte terminal_ext_in() 227 | { 228 | return 0; 229 | } 230 | 231 | /** 232 | * terminal_ext_out - Send an external output to selected device 233 | * Not implemented. 234 | */ 235 | void terminal_ext_out(padByte value) 236 | { 237 | USED(value); 238 | } 239 | 240 | /** 241 | * terminal_char_load - Store a character into the user definable 242 | * character set. 243 | */ 244 | void terminal_char_load(padWord charnum, charData theChar) 245 | { 246 | memset(&fontm23[(charnum*16)],0,16); 247 | for (curr_word=0;curr_word<8;curr_word++) 248 | { 249 | for (u=16; u-->0; ) 250 | { 251 | if (theChar[curr_word] & 1< 9 | * 10 | * License: GPL 3.0 11 | * 12 | * terminal.h - Terminal state machine functions 13 | */ 14 | 15 | #ifndef TERMINAL_H 16 | #define TERMINAL_H 17 | 18 | #include "protocol.h" 19 | 20 | /** 21 | * terminal_init() 22 | * Initialize terminal state 23 | */ 24 | void terminal_init(void); 25 | 26 | /** 27 | * terminal_initial_position() 28 | * Set terminal initial position after splash screen. 29 | */ 30 | void terminal_initial_position(void); 31 | 32 | /** 33 | * terminal_set_tty(void) - Switch to TTY mode 34 | */ 35 | void terminal_set_tty(void); 36 | 37 | /** 38 | * terminal_set_plato(void) - Switch to PLATO mode 39 | */ 40 | void terminal_set_plato(void); 41 | 42 | /** 43 | * terminal_get_features(void) - Inquire about terminal ASCII features 44 | */ 45 | unsigned char terminal_get_features(void); 46 | 47 | /** 48 | * terminal_get_type(void) - Return the appropriate terminal type 49 | */ 50 | unsigned char terminal_get_type(void); 51 | 52 | /** 53 | * terminal_get_subtype(void) - Return the appropriate terminal subtype 54 | */ 55 | unsigned char terminal_get_subtype(void); 56 | 57 | /** 58 | * terminal_get_load_file(void) - Return the appropriate terminal loadfile (should just be 0) 59 | */ 60 | unsigned char terminal_get_load_file(void); 61 | 62 | /** 63 | * terminal_get_configuration(void) - Return the terminal configuration 64 | */ 65 | unsigned char terminal_get_configuration(void); 66 | 67 | /** 68 | * terminal_get_char_address(void) - Return the base address of the character set. 69 | */ 70 | unsigned short terminal_get_char_address(void); 71 | 72 | /** 73 | * terminal_mem_read - Read a byte of program memory. 74 | * not needed for our terminal, but must 75 | * be decoded. 76 | */ 77 | padByte terminal_mem_read(padWord addr); 78 | 79 | /** 80 | * terminal_mem_load - Write a byte to non-character memory. 81 | * not needed for our terminal, but must be decoded. 82 | */ 83 | void terminal_mem_load(padWord addr, padWord value); 84 | 85 | /** 86 | * terminal_char_load - Store a character into the user definable 87 | * character set. 88 | */ 89 | void terminal_char_load(padWord charnum, charData theChar); 90 | 91 | /** 92 | * terminal_mode_5, 6, and 7 are basically stubbed. 93 | */ 94 | void terminal_mode_5(padWord value); 95 | void terminal_mode_6(padWord value); 96 | void terminal_mode_7(padWord value); 97 | 98 | /** 99 | * terminal_ext_allow - External Input allowed. Not implemented. 100 | */ 101 | void terminal_ext_allow(padBool allow); 102 | 103 | /** 104 | * terminal_set_ext_in - Set which device to get input from. 105 | * Not implemented 106 | */ 107 | void terminal_set_ext_in(padWord device); 108 | 109 | /** 110 | * terminal_set_ext_out - Set which device to send external data to. 111 | * Not implemented 112 | */ 113 | void terminal_set_ext_out(padWord device); 114 | 115 | /** 116 | * terminal_ext_in - get an external input from selected device. 117 | * Not implemented. 118 | */ 119 | padByte terminal_ext_in(void); 120 | 121 | /** 122 | * terminal_ext_out - Send an external output to selected device 123 | * Not implemented. 124 | */ 125 | void terminal_ext_out(padByte value); 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /touch.c: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * touch.c - Touch screen (mouse) functions 13 | */ 14 | #include 15 | #include 16 | #include "touch.h" 17 | #include "protocol.h" 18 | 19 | /** 20 | * void touch_init() - Set up touch screen 21 | */ 22 | void touch_init(void) 23 | { 24 | } 25 | 26 | void touch_allow(padBool allow) 27 | { 28 | USED(allow); 29 | } 30 | 31 | /** 32 | * void touch_main() - Main loop for touch screen 33 | */ 34 | void touch_main(int x,int y) 35 | { 36 | padPt Coord = {x, y^0x1FF}; 37 | Touch(&Coord); 38 | } 39 | 40 | /** 41 | * void touch_done() - Stop the mouse driver 42 | */ 43 | void touch_done(void) 44 | { 45 | } 46 | 47 | -------------------------------------------------------------------------------- /touch.h: -------------------------------------------------------------------------------- 1 | /** 2 | * PLATOTERM for Plan 9 3 | * 4 | * A PLATO terminal for services such as 5 | * CYBER1.ORG and IRATA.ONLINE 6 | * 7 | * Author: Thomas Cherryhomes 8 | * 9 | * 10 | * License: GPL 3.0 11 | * 12 | * touch.h - Touch (mouse) functions 13 | */ 14 | 15 | #ifndef TOUCH_H 16 | #define TOUCH_H 17 | 18 | #include "protocol.h" 19 | 20 | void touch_init(void); 21 | void touch_main(int x,int y); 22 | void touch_allow(padBool allow); 23 | void handle_mouse(void); 24 | void touch_hide(void); 25 | void touch_done(void); 26 | 27 | #endif /* TOUCH_H */ 28 | --------------------------------------------------------------------------------