├── LICENSE
├── README.md
├── build
├── rt-232.prg
├── rt-p4.prg
├── rt-sl.prg
├── rt-u.prg
├── rt-ulti.prg
├── rt232.com
├── rt38k.com
├── rt56k.com
└── rt_ulti_v0.20.prg
├── docs
├── turbo56k.md
└── turbo56k.png
├── makefile
├── retroterm_u014.prg
└── source
├── chrset.bin
├── intro_sc.asm
├── intro_sc.petmate
├── retrologo.mseq
├── retroterm_univ.asm
├── retrotermm1.asm
├── retrotermp4.asm
├── version.asm
└── version.txt
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2022 Jorge Castillo & Pablo Roldán
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Retroterm
4 | ### VERSION 0.21 Beta
5 |
6 | Jorge Castillo & Pablo Roldán
7 |
8 |
9 |     
10 |
11 | ---
12 |
13 |
14 | ## Table of contents:
15 |
16 | 1. [Introduction](#1-introduction)
17 | 1. [Release history](#11-release-history)
18 | 2. [The *Turbo56K* protocol](#12-the-turbo56k-protocol)
19 | 3. [Features](#13-features)
20 | 4. [Requirements](#14-requirements)
21 | 2. [Usage](#2-usage)
22 | 3. [Building](#3-building-retroterm)
23 | 1. [Symbols](#31-symbols)
24 | 2. [Intro screen](#32-the-intro-screen)
25 | 3. [Customizing](#33-customizing)
26 | 4. [Known bugs](#4-known-bugs)
27 | 5. [To-do](#5-to-do)
28 | 6. [Acknowledgments](#6-acknowledgments)
29 |
30 | ---
31 |
32 |
33 | ## 1 Introduction
34 |
35 | *Retroterm* is a small, minimal *PETSCII* terminal for the *Commodore 64 / 128 (in 64 mode)*, *Commodore Plus/4* and *MSX1 (in development)*.
36 |
37 | **ATTENTION THE MSX PORT IS CURRENTLY IN ALPHA STATE**
38 |
39 | It implements the *[Turbo56k](docs/turbo56k.md)* protocol for high speed data transfer & streaming when connecting to a BBS supporting the protocol, such as [_RetroBBS_](https://github.com/retrocomputacion/retrobbs).
40 |
41 | Data rate is fixed at the following speeds:
42 |
43 | - 57600bps for Retroterm 64 for userport and Turbo232**
44 | - 57600bps for Retroterm MSX for parallel port (very alpha state - candidate for deprecation)
45 | - 38400bps for Retroterm 64 for Swiftlink**
46 | - 38400bps for Retroterm MSX for parallel port (alpha state - mostly stable)
47 | - 19200bps for Retroterm Plus/4** and Retroterm MSX for RS232
48 |
49 | *(**)The full data throughput while using the turbo transfer / streaming can only be achieved with the screen disabled.*
50 |
51 | The effective throughput for text is *1500 / 1800bps* depending on *PAL/NTSC* timings respectively.
52 |
53 | *Retroterm* is optimized for use with **Wi-Fi** modems using the *Zimodem* firmware.
54 |
55 | *It also runs on the latest **VICE**/**Z64K** emulators.*
56 |
57 | Separate *Commodore 64* versions of the executable are provided for cartridges featuring an ACIA 6551 such as *SwiftLink* (limited to **38400bps**) and *Turbo232*.
58 | The *Commodore Plus/4* version is limited to the maximum speed for the built in ACIA: **19200bps**
59 |
60 | The *MSX 1 RS-232* version (rt232.com) is also at this moment limited to **19200bps**, and only supports RS-232 interfaces that adhere to the MSX standard (ie: SVI-738 and HX-22 built-in ports, SVI-737 and Sony HB-232, or any other interface implemented with the i8251 + i8253 USART and Timer combo)
61 |
62 | ## 1.1 Release history
63 |
64 | ### v0.21 (??/??/????):
65 | - New shortcut key for the Plus/4 port: `CBM+,` disables/enables the FLASH-ON control code. Improves compatibility with BBSs running Centipede 128 software.
66 | - Bugfix for the Commodore 64 ports: No more extraneous beep after streaming PCM audio.
67 |
68 | ### v0.20 (02/01/2024):
69 | - Turbo56K v0.7
70 | - New _Commodore Plus/4_ port. _Turbo56K v0.7_ commands implemented, except for the ones regarding SID tune streaming.
71 | - Fixed bug in command $A3 which caused the parameter to be misread, or the terminal to hang
72 | - New command `$86` to initiate a download to disk.
73 | - New command `$B6` to scroll the text window up or down X number of rows.
74 | - SID streaming now better supports tunes using _hardrestart_, a special version of _SIDdump_ and updated version of _RetroBBS_ is required.
75 | - New compile target `ultimate` compiles with timings compatible with the Swiftlink emulation in the Ultimate1541-II/II+ and Ultimate64.
76 | - Basic configuration screen by pressing `C= + F7`, terminal screen is not preserved.
77 | - ACIA based versions now allow selection of the interface base address ($DE00 or $DF00).
78 | - Connected disk drives are scanned on first run, and can be selected when downloading a file with command `$86`.
79 |
80 | ### v0.14 (13/04/2022):
81 | - Source code liberated
82 | - Turbo56K v0.6
83 | - Fixed small visual glitch when using the split screen mode
84 | - Better, more robust exit to BASIC
85 | - Disabled interrupts on command `$A2`, prevents crashes if (re)connecting to a BBS while the split screen mode is active
86 | - Fixed severe bug affecting the text output in early Commodore 64 Kernal revisions
87 | - Full digi-boost for 8580 SID
88 | - Intro screen exits automatically after ~2 seconds by default
89 | - Other small bugfixes.
90 | ### v0.13 (16/08/2021):
91 | - Initial release
92 | - Turbo56K v0.5
93 |
94 |
95 | ## 1.2 The Turbo56K protocol
96 | *[Turbo56k](docs/turbo56k.md)* was created by Jorge Castillo as a simple protocol to provide high-speed file transfer functionality to his bit-banging 57600bps RS232 routine for the C64.
97 | Over time, the protocol has been extended to include 4-bit PCM audio streaming, bitmap graphics transfer and display, SID music streaming and more.
98 |
99 | ## 1.3 Features
100 |
101 | *Implements all commands of the __[Turbo56k](docs/turbo56k.md)__ v0.7 protocol.*
102 |
103 | - Full duplex PETSCII (Commodore versions)/ASCII (MSX versions) color terminal
104 | - Turbo data transfers to custom/preset memory locations
105 | - Split Screen | Hi-res or Multicolor+Text
106 | - Up to 11520Hz 4-bit PCM audio streaming
107 | - Bitmap display | Hi-res + Multicolor (Commodore) | Screen 2 (MSX)
108 | - Consumes less than 5KB of memory (For the Commodore versions)
109 | - 1x speed SID music streaming (C64 versions only)
110 | - PSG music streaming (MSX versions)
111 | - Scrolling Text Windows
112 | - Set Cursor Position
113 | - Text Line Fill
114 | - Bidirectional scrolling
115 | - Download files to disk
116 |
117 | ## 1.4 Requirements
118 |
119 | - A Commodore 64, 128 or Plus/4 computer, or an emulator such as VICE or Z64K
120 | - Either an userport Wi-Fi modem with the Zimodem firmware or...
121 | - A *SwiftLink* or *Turbo232* compatible cartridge connected to a Wi-Fi modem with the Zimodem firmware.
122 | - A MSX1 or superior computer with 64K of RAM. With either a built-in RS-232 port or an MSX standard RS-232 interface cartridge. Or openMSX 20.0RC1
123 | - ACME and PASMO crossassemblers for building the programs.
124 |
125 | ## 2 Usage
126 | *Retroterm* is very simple to use, most of its functionality being controlled externally from a *[Turbo56k](docs/turbo56k.md)* enabled BBS.
127 |
128 | *Retroterm* comes in five variants:
129 |
130 | - **rt-u.prg** Userport version 57600bps
131 | - **rt-sl.prg** SwiftLink version 38400bps
132 | - **rt-232.prg** Turbo232 version 57600bps
133 | - **rt-p4.prg** Plus/4 version 19200bps
134 | - **rt232.com** MSX RS-232 version 19200bps
135 | - **rt38k.com** MSX parallel port version 38400bps
136 | - **rt56k.com** MSX parallel port version 57600bps
137 |
138 | *Retroterm* lacks classic file transfer functions, when used to communicate with a normal PETSCII/ASCII BBS, file transfers are not available.
139 |
140 | After LOADing and RUNning *Retroterm*, you can dial to your favorite BBS using your Modem commands as usual.
141 |
142 | **The modem should be setup to the correct baud rate before running _Retroterm_.**
143 |
144 | To exit *Retroterm*, just press `RUN/STOP` (Commodore) or `CTRL-C` (MSX), it will remain in memory, and you can recall it with `SYS49152` (Commodore 64), or `SYS28672` (Commodore Plus/4).
145 |
146 | If you downloaded a program into memory from a BBS you can also `RUN` it (Commodore versions only).
147 |
148 | On MSX pressing `CTRL-U` will reset the computer, if a ROM file was downloaded to RAM the system will try to execute it. ROMs that expect mirroring are not supported.
149 |
150 | *Retroterm* beeps for every received character by default, you can toggle the sound by pressing `CBM + M` (Commodore) or `CTRL-W` (MSX).
151 |
152 | ## 2.1 Setup screen
153 |
154 | A simple setup screen can be accessed by pressing `CBM + F7` (Commodore) or `CTRL-F5` (MSX), pressing `F1` will exit back to the terminal.
155 |
156 | The first setting, common to all _Retroterm_ variants sets the **RTS** pulse width. Current values are known to work under VICE, or on real hardware with an userport modem using Zimodem firmware, and with the Ultimate Swiftlink emulation.
157 | Use the `+` and `-` keys to adjust.
158 |
159 | For the ACIA versions there's a couple more settings.
160 |
161 | The first one sets the base address for the Swiftlink or Turbo232 cartridge, press `1` for $D700 or `2` for $DE00 or `3` for $DF00. Switching addresses will drop any current connection.
162 |
163 | The second setting available for ACIA versions is the ability to keep the screen visible while transferring at turbo speeds. Turbo transfers are slightly slower with the screen enabled. Press `B` to toggle.
164 |
165 | **Important**: Upon exiting the setup screen, _Retroterm_ will default to full screen text mode. Only previous background and border colors will be restored.
166 |
167 | ## 3 Building Retroterm
168 | The Commodore versions of *Retroterm* is written for the *ACME* cross-assembler, while *PASMO* is used for the MSX port, to compile use:
169 |
170 | ```
171 | make
172 | ```
173 | to compile all versions.
174 |
175 | Or you can specify which version you want to compile, either `userport`, `swiflink`, `turbo232`, `plus4`, `msx232` or `msx56k`.
176 |
177 | ie:
178 | ```
179 | make userport
180 | ```
181 | All executables will be stored in the `build` directory.
182 |
183 | You can also manually compile with:
184 | ```
185 | acme retroterm_univ.asm
186 | ```
187 |
188 | or:
189 | ```
190 | pasmo -E IFACE=0 retrotermm1.asm rt232.com
191 | pasmo -E IFACE=56 retrotermmm1.asm rt56k.com
192 | ```
193 |
194 | from the `source` directory.
195 | This will compile the default userport version of *Retroterm* with an intro screen that last a couple of seconds. In this case the resulting executable will be written to the `source` directory
196 |
197 | ## 3.1 Symbols
198 | A number of compile time symbols are defined to customize the resulting executable. Specially if you're running the compiler directly instead of using the Makefile
199 |
200 | ### `_HARDTYPE_`:
201 | `38`: Compile for *SwiftLink/Turbo232* cartridges at **38400bps**
202 |
203 | `56`: Compile for userport at **57600bps** -- **_Default_**
204 |
205 | `232`: Compile for *Turbo232* cartridges at **57600bps**
206 |
207 | `1541`: Compile for the *Ultimate 1541-II* or *Ultimate 64* Swiftlink emulation, same code as for `38` but different timing.
208 |
209 | ### `_INTRO_`:
210 | `0`: No intro screen
211 |
212 | `1`: Include the intro screen -- **_Default_**
213 |
214 | ### `_SPACE_`:
215 | If defined wait for the user to press the space bar at the intro screen. Otherwise, the intro screen only last a couple of seconds.
216 |
217 | **_Not defined by default_**
218 |
219 | ### `IFACE`:
220 | `0`: Compile for standard MSX RS232 ports
221 | `56`: Compile for the MSX parallel port
222 |
223 | ### Example:
224 |
225 | ```
226 | acme -D_HARDTYPE_=232 -D_INTRO_=0 retroterm_univ.asm
227 | ```
228 | Compiles _Retroterm_ for the _Turbo232_ cartridge with no intro screen.
229 |
230 | ## 3.2 The intro screen
231 | The intro screen is a `screencode + colorRAM` dump found in `source/intro_sc.asm`
232 |
233 | This file is generated by exporting `source/intro_sc.petmate` to ACME format from [Petmate](https://nurpax.github.io/petmate/).
234 |
235 | ## 3.3 Customizing
236 |
237 | If you want to release a modified version of _Retroterm_ which differs in functionality from the official release we recommend you use a custom _ID string_, respecting the maximum 22 character length and always starting in uppercase `RT`
238 |
239 | IE, the normal ID string is:
240 | ```
241 | IDstring:
242 | !text "RTRETROTERM 0.20 "
243 | ```
244 | but the string when compiling for the *SwiftLink* cartridge is:
245 |
246 | ```
247 | IDstring:
248 | !text "RTRETROTERM-SL 0.20 "
249 | ```
250 |
251 | **Note: The actual version number string is sourced from the file `source/version.txt` when using the *makefile*, or from `source/version.asm` when running the compiler directly**
252 |
253 |
254 | For compatibility reasons we ask you not to modify the behavior of existing Turbo56K commands, but you're welcomed to add new commands, or remove unwanted ones, as long as command `$A3` correctly reports the existence or not of all queried commands.
255 |
256 | In any case the *[Turbo56k](docs/turbo56k.md)* version bytes that follow the ID string should remain the correct ones for the official version your modified code support.
257 |
258 |
259 | ## 4 Known bugs
260 |
261 | - Losing connection while streaming data or audio will hang the program
262 | - Exiting `Retroterm`, restarting it with `SYS49152`, exiting again and causing a BASIC error will crash the computer.
263 |
264 | ## 5 To-do
265 | - Extend the command parameter space to support more than 8 parameters per command.
266 | - Faster throughput when using any of the ACIA cartridges.
267 |
268 | ## 6 Acknowledgments
269 | ### Beta Testers
270 |
271 | - **Ezequiel Filgueiras**
272 | - **Thierry Kurt**
273 | - **Diego di Franceschi**
274 | - **ChrisKewl**
275 | - **Roberto Mandracchia**
276 | - **x1pepe**
277 |
278 | ### Thanks To
279 |
280 | - **Willy Manilly** for adding support to the *Z64K emulator*
281 |
282 | - [**ElectronicsArchiver**](https://github.com/ElectronicsArchiver) for initial documentation rework
283 |
--------------------------------------------------------------------------------
/build/rt-232.prg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/build/rt-232.prg
--------------------------------------------------------------------------------
/build/rt-p4.prg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/build/rt-p4.prg
--------------------------------------------------------------------------------
/build/rt-sl.prg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/build/rt-sl.prg
--------------------------------------------------------------------------------
/build/rt-u.prg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/build/rt-u.prg
--------------------------------------------------------------------------------
/build/rt-ulti.prg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/build/rt-ulti.prg
--------------------------------------------------------------------------------
/build/rt232.com:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/build/rt232.com
--------------------------------------------------------------------------------
/build/rt38k.com:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/build/rt38k.com
--------------------------------------------------------------------------------
/build/rt56k.com:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/build/rt56k.com
--------------------------------------------------------------------------------
/build/rt_ulti_v0.20.prg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/build/rt_ulti_v0.20.prg
--------------------------------------------------------------------------------
/docs/turbo56k.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 
5 |
6 |
7 |
8 | # Turbo56K v0.7
9 |
10 |
11 | **Turbo56K** was created by **Jorge Castillo** as a simple protocol to provide high speed file transfer functionality to his bit-banging `57600bps` **RS232** routine for the **Commodore 64**.
12 |
13 | Over time, the protocol has been extended to include `4-bit` **PCM** audio streaming, bitmap graphics transfer and display, **SID** and **PSG** music streaming and more.
14 |
15 | A typical **Turbo56K** command sequence consists of a command start character ( **CMDON** : `$FF` ) followed by the command itself (a character with it's 7th bit set) and the parameters it requires.
16 |
17 | The sequence ends with the command end character ( **CMDOFF** : `$FE` )
18 |
19 | Some commands will exit *command mode* automatically without needing a `CMDOFF` character, but is good practice to include it anyway.
20 |
21 | For example the following byte sequence enters command mode, sets the screen to Hires mode on page 0 with blue border and then exits command mode:
22 |
23 | $FF $90 $00 $06 $FE
24 |
25 |
26 | ---
27 |
28 |
29 |
30 | ## Reserved Characters
31 |
32 | | Hex | Dec | Description
33 | |:---:|:---:|------------
34 | | `$FF` | `255` |Enters command node
35 | | `$FE` | `254` |Exits command node
36 |
37 |
38 |
39 | ## Commands
40 |
41 |
42 |
43 | ### Data Transfer
44 |
45 | | Hex | Dec | Description
46 | |:---:|:---:|------------
47 | | `$80` | `128` | Sets the memory pointer for the next transfer **Parameters**
- Destination Address : 2 bytes : low \| high
48 | | `$81` | `129` | Selects preset address for the next transfer
**Parameters**
- Preset Number : 1 byte
49 | | `$82` | `130` | Start a memory transfer
**Parameters**
- Transfer Size : 2 bytes : low \| high
50 | | `$83` | `131` | Starts audio streaming until receiving a `$00` character
51 | | `$84` | `132` | Starts chiptune streaming until receiving a data block with size `0`, or interrupted by the user
52 | | `$85` | `133` | `New v0.6`
Sets the stream and write order of the registers for SID streaming
**Parameters**
- Stream : 25 bytes
53 | | `$86` | `134` | `New v0.7`
Starts a file transfer (to be saved on a storage device client side)
54 |
55 |
56 |
57 | ### Graphics Mode
58 |
59 | | Hex | Dec | Description
60 | |:---:|:---:|------------
61 | | `$90` | `144` | Returns to the default text mode
**Parameters**
- Page Number : 1 byte
- Border Color : 1 byte
- Background Color : 1 byte
62 | | `$91` | `145` | Switches to hi-res bitmap mode
**Parameters**
- Page Number : 1 byte
- Border Color : 1 byte
63 | | `$92` | `146` | Switches to multicolor bitmap mode
**Parameters**
- Page Number : 1 byte
- Border Color : 1 byte
- Background Color : 1 byte
**Only for Plus/4:**
- Multicolor 3 color : 1 byte
64 |
65 |
66 |
67 | ### Drawing Primitives
68 |
69 | | Hex | Dec | Description
70 | |:---:|:---:|------------
71 | | `$98` | `152` | `New v0.8` Clears graphic screen
72 | | `$99` | `153` | `New v0.8` Set pen color
**Parameters**
- Pen Number: 1 byte
- Color index: 1 byte
73 | | `$9A` | `154` | `New v0.8` Plot point
**Parameters**
- Pen Number: 1 byte
- X coordinate: 2 bytes
- Y coordinate: 2 bytes
74 | | `$9B` | `155` | `New v0.8` Line
**Parameters**
- Pen Number: 1 byte
- X1: 2 bytes
- Y1: 2 bytes
- X2: 2 bytes
- Y2: 2 bytes
75 | | `$9C` | `156` | `New v0.8` Box
**Parameters**
- Pen Number: 1 byte
- X1: 2 bytes
- Y1: 2 bytes
- X2: 2 bytes
- Y2: 2 bytes
- Fill: 1 byte
76 | | `$9D` | `157` | `New v0.8` Circle/Ellipse
**Parameters**
- Pen Number: 1 byte
- X: 2 bytes
- Y: 2 bytes
- rX: 2 bytes
- rY: 2bytes
77 | | `$9E` | `158` | `New v0.8` Fill
**Parameters**
- Pen Number: 1 byte
- X: 2 bytes
- Y: 2 bytes
78 |
79 |
80 |
81 | ### Connection Management
82 |
83 | | Hex | Dec | Description
84 | |:---:|:---:|------------
85 | | `$A0` | `160` | Selects the screen as the output for the received characters, exits command mode
86 | | `$A1` | `161` | Selects the optional hardware voice synthesizer as the output for the received characters, exits command mode.
(*Valid only for the microsint + rs232 / Wi-Fi board*)
87 | | `$A2` | `162` | Request terminal ID and version
88 | | `$A3` | `163` | `New v0.6`
Query if the command passed as parameter is implemented in the terminal. If the returned value has its 7th bit clear then the value is the number of parameters required by the command.
(*Max 8 in the current Retroterm implementation*)
If the 7th bit is set the command is not implemented.
89 | | `$A4` | `164` | `New v0.8`
Query the client's setup. The single byte parameter indicates which 'subsystem' is being queried. Client must reply with at least 1 byte indicating the reply length. Zero meaning not implemented. See below for the subsystem parameters.
90 |
91 |
92 |
93 | ### Screen Management
94 |
95 | | Hex | Dec | Description
96 | |:---:|:---:|------------
97 | | `$B0` | `176` | Moves the text cursor
**Parameters**
- Column : 1 byte
- Row : 1 byte
Exits command mode
98 | | `$B1` | `177` | Fills a text screen row with a given
character, text cursor is not moved
**Parameters**
- Screen Row : 1 byte
- Fill Character : 1 byte : *C64 Screen Code*
99 | | `$B2` | `178` | Enables or disables the text cursor
**Parameters**
- Enable : 1 byte
100 | | `$B3` | `179` | Screen split
**Parameters**
- Modes : 1 byte
`Bit 0 - 4` : Split Row `1 - 24`
`Bit 7` : Bitmap Graphics Mode in top section
`0` : Hires
`1` : Multicolor
- Background Color : 1 byte
`Bit 0 - 3` : Top Section
`Bit 4 - 7` : Bottom Section
101 | | `$B4` | `180` | `New v0.7`
Get text cursor position, returns 2 characters, column and row.
102 | | `$B5` | `181` | Set text window
**Parameters**
- Top Row : 1 byte : `0 - 23`
- Bottom Row : 1 byte : `1 - 24`
103 | | `$B6` | `182` | `New v0.7`
Scroll the text window up or down x rows
**Parameters**
- Row count: 1 byte -128/+127
104 | | `$B7` | `183` | `New v0.7`
Set ink color
**Parameters**
- Color index: 1 byte
105 |
106 |
107 | ### Preset Addresses
108 |
109 | *For command `$81`*
110 |
111 | #### Commodore 64 & Plus/4
112 | | Hex | Dec | Description
113 | |:---:|:---:|:------------
114 | | `$00` | `0` | Text page `0`
115 | | `$10` | `16` | Bitmap page `0`
116 | | `$20` | `32` | Color RAM
117 |
118 | *The current versions of **Retroterm** supports only a single text / bitmap page.*
*Values other than `0` for bits `0 - 3` will be ignored.*
119 |
120 | #### MSX1
121 |
122 | | Hex | Dec | Description
123 | |:---:|:---:|:------------
124 | | `$00` | `0` | Text/name table page `0`
125 | | `$10` | `16` | Pattern table page `0`
126 | | `$20` | `32` | Color table
127 |
128 | *Any other value will set the address to $4000 (RAM Page 1) -Subject to changes-*
129 |
130 | ### "Subsystems"
131 |
132 | *For command `$A4`*
133 |
134 | ##### `$00`: Platform/Refresh rate
135 |
136 | Reply length: 2 bytes
137 |
138 | | Position | Value
139 | |:---:|:---
140 | | 0 | 1
141 | | 1 | bits 0-6: platform
bit 7: Refresh rate
142 |
143 | ###### Platform:
144 |
145 | | Value | Platform
146 | |:---:|:---
147 | | 0 | C64
148 | | 1 | Plus/4
149 | | 2 | MSX
150 | | 3 | `reserved` C128
151 | | 4 | `reserved` VIC20
152 | | 5 | `reserved` ZX Spectrum
153 | | 6 | `reserved` Atari
154 | | 7 | `reserved` Apple II
155 | | 8 | `reserved` Amstrad
156 | | 9 | `reserved` Amiga
157 | | 10 | `reserved` PET
158 | |
159 |
160 | ###### Refresh rate:
161 |
162 | | Value | Meaning
163 | |:---:|:---
164 | | 0 | 50Hz
165 | | 1 | 60Hz
166 |
167 |
168 | ##### `$01`: Text screen size
169 |
170 | Reply length: 3 bytes
171 |
172 | | Position | Value
173 | |:---:|:---
174 | | 0 | 2
175 | | 1 | Columns
176 | | 2 | Rows
177 | |
178 |
179 | ##### `$02`: Connection speed
180 |
181 | Reply length: 2 bytes
182 |
183 | | Position | Value
184 | |:---:|:---
185 | | 0 | 1
186 | | 1 |
0: Network
1: 300bps
2: 600bps
3: 1200bps
4: 1800bps
5: 2400bps
6: 4800bps
7: 9600bps
8: 19200bps
9: 28800bps
10: 38400bps
11: 57600bps
12: 76800bps
13: 115200bps
187 | |
188 |
189 | ##### `$03`: RAM size
190 |
191 | Reply length: 3 bytes
192 |
193 | | Position | Value
194 | |:---:|:---
195 | | 0 | 2
196 | | 1-2 | RAM size in Kilobytes (big-endian)
197 | |
198 |
199 | ##### `$04`: VRAM size
200 |
201 | Reply length: 3 bytes
202 |
203 | | Position | Value
204 | |:---:|:---
205 | | 0 | 2
206 | | 1-2 | VRAM size in Kilobytes (big-endian)
207 | |
208 |
209 | ##### `$05`: Graphic modes (platform dependent)
210 |
211 | Reply length: 2 bytes
212 |
213 | | Position | Value
214 | |:---:|:---
215 | | 0 | 1
216 | | 1 | Graphic modes available
217 | |
218 |
219 | ###### C64:
220 |
221 | In addition to Hires and Multicolour
222 |
223 | | bit | Mode
224 | |:---:|:---
225 | | 0 | FLI
226 | | 1 | AFLI
227 | |
228 | ###### C128:
229 |
230 | In addition to Hires and Multicolour
231 |
232 | | bit | Mode
233 | |:---:|:---
234 | | 0 | FLI
235 | | 1 | AFLI
236 | | 2 | VDC
237 | | 3 | VDCI
238 |
239 | ###### MSX:
240 |
241 | In addition to Screen2
242 |
243 | | bit | Mode
244 | |:---:|:---
245 | | 0 | Screen 3
246 | | 1 | Screen 4
247 | | 2 | Screen 5
248 | | 3 | Screen 6
249 | | 4 | Screen 7
250 | | 5 | Screen 8
251 | | 6 | Screen 10
252 | | 7 | Screen 12
253 |
254 | ###### Amiga:
255 |
256 | | Value | Chipset
257 | |:---:|:---
258 | | 0 | OCS
259 | | 1 | ECS
260 | | 2 | AGA
261 |
262 | ##### `$06`: Audio (platform dependent)
263 |
264 | Reply length: 3 bytes
265 |
266 | | Position | Value
267 | |:---:|:---
268 | | 0 | 2
269 | | 1 | Synthesizers
270 | | 2 | PCM
271 |
272 | ###### Synthesizers
273 |
274 | ###### -Commodore 64/128
275 |
276 | | bit | Meaning
277 | |:---:|:---
278 | | 0-3 | Installed SID(s)-1
279 | | 4 | OPL present
280 | | 5 | microSynth present
281 | | 6 | Magic Voice present
282 |
283 | ###### -MSX
284 |
285 | | bit | Meaning
286 | |:---:|:---
287 | | 0 | MSX Audio present
288 | | 1 | MSX Music present
289 | | 2 | OPL3 present
290 |
291 | ###### PCM
292 |
293 | | bit | Meaning
294 | |:---:|:---
295 | | 0-1 | bits per sample (1(PWM)/4/8/16)
296 | | 2 | Channels (1/2)
297 | | 3 | Connection speed dependent sample rate
298 | | 4 | 11025Hz sample rate
299 | | 5 | 16000Hz sample rate
300 | | 6 | 22050Hz sample rate
301 | | 7 | Delta compression
302 |
--------------------------------------------------------------------------------
/docs/turbo56k.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/docs/turbo56k.png
--------------------------------------------------------------------------------
/makefile:
--------------------------------------------------------------------------------
1 |
2 | BUILDFOLDER:=build
3 | SRCFOLDER:=source
4 |
5 | VARIANTS=u sl ulti 232
6 |
7 | MVARIANTS=232 56k 38k
8 |
9 | DEFINES_FOR_u=-D_HARDTYPE_=56
10 | DEFINES_FOR_sl=-D_HARDTYPE_=38
11 | DEFINES_FOR_ulti=-D_HARDTYPE_=1541
12 | DEFINES_FOR_232=-D_HARDTYPE_=232
13 |
14 |
15 | # Read build version from source/version.txt
16 | VERSION:=$(file < $(SRCFOLDER)/version.txt)
17 |
18 |
19 |
20 | define make_target_acme =
21 | $$(BUILDFOLDER)/rt-$(1).prg: $(SRCFOLDER)/retroterm_univ.asm $(SRCFOLDER)/version.asm
22 | acme $$(DEFINES_FOR_$(1)) -D_MAKE_=1 -I $(SRCFOLDER) -f cbm -o $$@ $$<
23 |
24 | endef
25 |
26 | all: $(SRCFOLDER)/version.asm $(foreach variant,$(VARIANTS),$(BUILDFOLDER)/rt-$(variant).prg ) plus4 msx232 msx56k msx38k
27 | comm: $(SRCFOLDER)/version.asm $(foreach variant,$(VARIANTS),$(BUILDFOLDER)/rt-$(variant).prg ) plus4
28 | msx: $(SRCFOLDER)/version.asm $(foreach variant,$(MVARIANTS),$(BUILDFOLDER)/rt$(variant).com )
29 |
30 |
31 | swiftlink: $(BUILDFOLDER)/rt-sl.prg
32 |
33 | ultimate: $(BUILDFOLDER)/rt-ulti.prg
34 |
35 | turbo232: $(BUILDFOLDER)/rt-232.prg
36 |
37 | userport: $(BUILDFOLDER)/rt-u.prg
38 |
39 | plus4: $(BUILDFOLDER)/rt-p4.prg
40 |
41 | msx232: $(BUILDFOLDER)/rt232.com
42 |
43 | msx56k: $(BUILDFOLDER)/rt56k.com
44 |
45 | msx38k: $(BUILDFOLDER)/rt38k.com
46 |
47 | $(BUILDFOLDER)/rt-p4.prg: $(SRCFOLDER)/retrotermp4.asm
48 | acme -f cbm -D_MAKE_=1 -I $(SRCFOLDER) -o $(BUILDFOLDER)/rt-p4.prg $(SRCFOLDER)/retrotermp4.asm
49 |
50 | $(BUILDFOLDER)/rt232.com: $(SRCFOLDER)/retrotermm1.asm $(SRCFOLDER)/retrologo.mseq
51 | pasmo -E IFACE=0 -I $(SRCFOLDER) $(SRCFOLDER)/retrotermm1.asm $(BUILDFOLDER)/rt232.com $(SRCFOLDER)/rtm232.symbol
52 | $(BUILDFOLDER)/rt56k.com: $(SRCFOLDER)/retrotermm1.asm $(SRCFOLDER)/retrologo.mseq
53 | pasmo -E IFACE=56 -I $(SRCFOLDER) $(SRCFOLDER)/retrotermm1.asm $(BUILDFOLDER)/rt56k.com $(SRCFOLDER)/rtm56k.symbol
54 | $(BUILDFOLDER)/rt38k.com: $(SRCFOLDER)/retrotermm1.asm $(SRCFOLDER)/retrologo.mseq
55 | pasmo -E IFACE=38 -I $(SRCFOLDER) $(SRCFOLDER)/retrotermm1.asm $(BUILDFOLDER)/rt38k.com $(SRCFOLDER)/rtm38k.symbol
56 |
57 | $(SRCFOLDER)/version.asm: $(SRCFOLDER)/version.txt
58 | # Generate version include source/version.asm
59 | echo !text '"'$(VERSION)'"' > $(SRCFOLDER)/version.asm
60 |
61 | #Create rules
62 | $(eval $(foreach variant,$(VARIANTS),$(call make_target_acme,$(variant))))
63 |
64 |
--------------------------------------------------------------------------------
/retroterm_u014.prg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/retroterm_u014.prg
--------------------------------------------------------------------------------
/source/chrset.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/source/chrset.bin
--------------------------------------------------------------------------------
/source/intro_sc.asm:
--------------------------------------------------------------------------------
1 |
2 |
3 | ; PETSCII memory layout (example for a 40x25 screen)'
4 | ; byte 0 = border color'
5 | ; byte 1 = background color'
6 | ; bytes 2-1001 = screencodes'
7 | ; bytes 1002-2001 = color
8 |
9 | screen_001
10 | !byte 1,1
11 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
12 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
13 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
14 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
15 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
16 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
17 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
18 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$E1,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
19 | !byte $20,$7C,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$7E,$FF,$E2,$E2,$6C,$E2,$E2,$7F,$7C,$FB,$E2,$6C,$E2,$E2,$7E,$FF,$E2,$E2,$7B,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$7E,$20
20 | !byte $7C,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$7E,$61,$20,$20,$E1,$E2,$E2,$E2,$20,$E1,$20,$E1,$20,$20,$20,$61,$20,$20,$61,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$7E
21 | !byte $7C,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$7E,$7E,$20,$20,$20,$E2,$E2,$E2,$20,$20,$E2,$7C,$20,$20,$20,$7C,$E2,$E2,$20,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$7E
22 | !byte $20,$7C,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$7E,$E2,$E2,$E2,$7C,$E2,$E2,$E2,$7C,$E2,$E2,$7C,$E2,$E2,$7E,$E2,$E2,$E2,$7E,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$E2,$7E,$20
23 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$E1,$20,$20,$20,$20,$20,$20,$20,$20,$20,$7C,$20,$20,$20,$20,$20,$20,$20,$20
24 | !byte $6C,$E2,$E2,$E2,$6C,$E2,$E2,$7F,$E1,$E2,$EC,$7F,$E1,$E2,$E2,$7F,$E1,$20,$20,$E1,$7C,$FB,$E2,$20,$E2,$E2,$7F,$6C,$E2,$E2,$E2,$E1,$6C,$E2,$E2,$7F,$E1,$E2,$E2,$7B
25 | !byte $E1,$20,$20,$20,$E1,$20,$20,$E1,$E1,$20,$61,$E1,$E1,$20,$20,$E1,$E1,$20,$20,$E1,$20,$E1,$20,$6C,$E2,$E2,$FB,$E1,$20,$20,$20,$E1,$E1,$20,$20,$E1,$E1,$20,$20,$61
26 | !byte $20,$E2,$E2,$E2,$20,$E2,$E2,$7E,$7C,$20,$7E,$7C,$E1,$E2,$E2,$7E,$20,$E2,$E2,$7E,$20,$20,$E2,$20,$E2,$E2,$E2,$20,$E2,$E2,$E2,$7C,$20,$E2,$E2,$7E,$7C,$20,$20,$7E
27 | !byte $7C,$E2,$E2,$E2,$7C,$E2,$E2,$E2,$7C,$E2,$E2,$E2,$7C,$7C,$E2,$E2,$7C,$E2,$E2,$E2,$7C,$E2,$E2,$7C,$E2,$E2,$E2,$7C,$E2,$E2,$E2,$7C,$7C,$E2,$E2,$E2,$7C,$E2,$E2,$7E
28 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
29 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
30 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$52,$45,$54,$52,$4F,$43,$4F,$4D,$50,$55,$54,$41,$43,$49,$4F,$4E,$2E,$43,$4F,$4D,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
31 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$10,$12,$05,$13,$05,$0E,$14,$01,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
32 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
33 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$52,$05,$14,$12,$0F,$14,$05,$12,$0D,$20,$20,$16,$30,$2E,$32,$30,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
34 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
35 | !byte $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
36 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
37 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
38 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
39 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
40 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
41 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
42 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
43 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$0E,$0E,$0E,$0E,$00,$00,$0E,$0E,$0E,$0E,$0E,$0E,$00,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
44 | !byte $0E,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$0E
45 | !byte $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$00,$0E,$0E,$00,$00,$00,$00,$02,$00,$00,$00,$00,$0E,$0E,$00,$0E,$00,$00,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
46 | !byte $0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$00,$0E,$0E,$0E,$00,$00,$00,$02,$0E,$00,$00,$00,$0E,$0E,$00,$00,$00,$02,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D
47 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
48 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$00,$00,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$00,$00,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
49 | !byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0E,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
50 | !byte $00,$00,$0E,$00,$00,$0E,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0E,$0E,$00,$02,$00,$00,$00,$00,$00,$00,$00,$00,$0E,$00,$00,$00,$0E,$0E,$00,$00,$00,$0E,$00
51 | !byte $0E,$00,$00,$00,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0E,$00,$00,$00,$02,$0E,$00,$00,$00,$00,$00,$0E,$00,$00,$00,$00,$0E,$00,$00,$00,$00,$00,$0E,$00
52 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$00,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
53 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
54 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
55 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
56 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
57 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$06,$0E,$0E,$0E,$0E,$0E,$0E,$06,$06,$06,$06,$0B,$04,$04,$06,$06,$0E,$0E,$06,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
58 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
59 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$00,$00,$00,$00,$00,$00,$00,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
60 | !byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$00,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
61 |
--------------------------------------------------------------------------------
/source/intro_sc.petmate:
--------------------------------------------------------------------------------
1 | {"version":2,"screens":[0],"framebufs":[{"width":40,"height":25,"backgroundColor":1,"borderColor":1,"charset":"lower","name":"screen_001","framebuf":[[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":225,"color":0},{"code":32,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":124,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":126,"color":2},{"code":255,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":108,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":127,"color":0},{"code":124,"color":0},{"code":251,"color":0},{"code":226,"color":0},{"code":108,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":126,"color":0},{"code":255,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":123,"color":0},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":226,"color":2},{"code":126,"color":2},{"code":32,"color":14}],[{"code":124,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":126,"color":7},{"code":97,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":225,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":32,"color":2},{"code":225,"color":0},{"code":32,"color":0},{"code":225,"color":0},{"code":32,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":97,"color":0},{"code":32,"color":14},{"code":32,"color":0},{"code":97,"color":0},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":226,"color":7},{"code":126,"color":7}],[{"code":124,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":126,"color":13},{"code":126,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":226,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":32,"color":2},{"code":32,"color":14},{"code":226,"color":0},{"code":124,"color":0},{"code":32,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":124,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":32,"color":2},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":226,"color":13},{"code":126,"color":13}],[{"code":32,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":126,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":126,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":126,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":126,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":225,"color":0},{"code":32,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":0},{"code":124,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":108,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":108,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":127,"color":0},{"code":225,"color":0},{"code":226,"color":0},{"code":236,"color":0},{"code":127,"color":0},{"code":225,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":127,"color":0},{"code":225,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":225,"color":0},{"code":124,"color":0},{"code":251,"color":0},{"code":226,"color":0},{"code":32,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":127,"color":0},{"code":108,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":225,"color":0},{"code":108,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":127,"color":0},{"code":225,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":123,"color":0}],[{"code":225,"color":0},{"code":32,"color":0},{"code":32,"color":14},{"code":32,"color":0},{"code":225,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":225,"color":0},{"code":225,"color":0},{"code":32,"color":0},{"code":97,"color":0},{"code":225,"color":0},{"code":225,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":225,"color":0},{"code":225,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":225,"color":0},{"code":32,"color":2},{"code":225,"color":0},{"code":32,"color":0},{"code":108,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":251,"color":0},{"code":225,"color":0},{"code":32,"color":0},{"code":32,"color":14},{"code":32,"color":0},{"code":225,"color":0},{"code":225,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":225,"color":0},{"code":225,"color":0},{"code":32,"color":0},{"code":32,"color":14},{"code":97,"color":0}],[{"code":32,"color":14},{"code":226,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":32,"color":14},{"code":226,"color":0},{"code":226,"color":0},{"code":126,"color":0},{"code":124,"color":0},{"code":32,"color":0},{"code":126,"color":0},{"code":124,"color":0},{"code":225,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":126,"color":0},{"code":32,"color":14},{"code":226,"color":0},{"code":226,"color":0},{"code":126,"color":0},{"code":32,"color":2},{"code":32,"color":14},{"code":226,"color":0},{"code":32,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":32,"color":14},{"code":226,"color":0},{"code":226,"color":0},{"code":226,"color":0},{"code":124,"color":0},{"code":32,"color":14},{"code":226,"color":0},{"code":226,"color":0},{"code":126,"color":0},{"code":124,"color":0},{"code":32,"color":0},{"code":32,"color":14},{"code":126,"color":0}],[{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":0},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":124,"color":14},{"code":226,"color":14},{"code":226,"color":14},{"code":126,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":82,"color":6},{"code":69,"color":6},{"code":84,"color":6},{"code":82,"color":6},{"code":79,"color":6},{"code":67,"color":6},{"code":79,"color":6},{"code":77,"color":6},{"code":80,"color":6},{"code":85,"color":6},{"code":84,"color":6},{"code":65,"color":6},{"code":67,"color":6},{"code":73,"color":6},{"code":79,"color":6},{"code":78,"color":6},{"code":46,"color":6},{"code":67,"color":6},{"code":79,"color":6},{"code":77,"color":6},{"code":32,"color":6},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":6},{"code":32,"color":6},{"code":32,"color":6},{"code":16,"color":6},{"code":18,"color":6},{"code":5,"color":6},{"code":19,"color":6},{"code":5,"color":6},{"code":14,"color":6},{"code":20,"color":6},{"code":1,"color":6},{"code":32,"color":6},{"code":32,"color":6},{"code":32,"color":6},{"code":32,"color":6},{"code":32,"color":6},{"code":32,"color":6},{"code":32,"color":6},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":6},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":6},{"code":32,"color":6},{"code":32,"color":6},{"code":32,"color":6},{"code":32,"color":11},{"code":32,"color":4},{"code":32,"color":4},{"code":32,"color":6},{"code":32,"color":6},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":6},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":82,"color":0},{"code":5,"color":0},{"code":20,"color":0},{"code":18,"color":0},{"code":15,"color":0},{"code":20,"color":0},{"code":5,"color":0},{"code":18,"color":0},{"code":13,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":22,"color":0},{"code":48,"color":0},{"code":46,"color":0},{"code":50,"color":0},{"code":48,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}],[{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":0},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14},{"code":32,"color":14}]]}],"customFonts":{}}
--------------------------------------------------------------------------------
/source/retrologo.mseq:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/retrocomputacion/retroterm/88a960d09673dc9021ea6c3a9241b9c7dc9870dc/source/retrologo.mseq
--------------------------------------------------------------------------------
/source/retrotermp4.asm:
--------------------------------------------------------------------------------
1 | ;////////////////////////////////////////////////////////////////////////////////////////////
2 | ; BBS PETSCII compatible terminal, RS232 with tcpser/BBSServer or wifi with zimodem firmware
3 | ; Supports TURBO56K v0.7 protocol at 19200 bps, using TX, RX and RTS
4 | ;////////////////////////////////////////////////////////////////////////////////////////////
5 | ;
6 | ; Constants
7 |
8 | STROUT = $9088 ; BASIC String out routine
9 | CHROUT = $FFD2 ; Kernal CHROUT (prints a single character)
10 | STOP = $FFE1 ; Kernal STOP (checks STOP key)
11 | GETIN = $FFE4 ; Kernal GETIN
12 | PLOT = $FFF0 ; Kernal PLOT
13 | COLORMEM = $0800 ; Character Colors
14 |
15 | CURRLINEPTR = $C8 ; Current text line pointer (zero page)
16 | CURRLINE = $CD
17 | CURRCOLUMN = $CA ; Current column (pagina cero)
18 | CURRCOLLINE = $EA ; Current text line color porinter (zero page)
19 | ACIABASE = $FD00 ; ACIA 6551 base address
20 | ACIADATA = ACIABASE+0 ; Registro de datos del ACIA 6551
21 | ACIASTATUS = ACIABASE+1 ; Registro de estado del ACIA 6551
22 | ACIACOMMAND = ACIABASE+2; Registro de comando del ACIA 6551
23 | ACIACONTROL = ACIABASE+3; Registro de control del ACIA 6551
24 | BEEPTIME = 4 ; Cantidad minima de cuadros que dura un beep de impresion
25 | PrBuffer = ENDOFCODE ; Buffer de impresion
26 |
27 | MAXCMD = $B7 ; Highest command implemented
28 |
29 | !ifndef _MAKE_{
30 | !to "rt_p4_v0.20.prg", cbm
31 | }
32 | !sl "labels-p4.txt"
33 |
34 |
35 | ;///////////////////////////////////////////////////////////////////////////////////
36 | ; MACROSS
37 | ;///////////////////////////////////////////////////////////////////////////////////
38 | !macro SetCursor .col, .row {
39 | CLC
40 | LDY #.col
41 | LDX #.row
42 | JSR PLOT
43 | }
44 |
45 | !macro StringOut .addr {
46 | LDA #<.addr
47 | LDY #>.addr
48 | JSR STROUT
49 | }
50 |
51 | !macro DisROMs {
52 | STA $FF3F
53 | }
54 |
55 | !macro EnROMs {
56 | STA $FF3E
57 | }
58 |
59 | !macro _Version_{ ; Insert version number string
60 | !src "version.asm"
61 | }
62 |
63 | *= $1001
64 |
65 | ;///////////////////////////////////////////////////////////////////////////////////
66 | ; PROGRAMA BASIC
67 | ;///////////////////////////////////////////////////////////////////////////////////
68 |
69 | !byte $0C, $10, $E4, $07, $9E, $20, $34, $31, $31, $32, $00 ; 10 SYS 4112
70 | !byte $00, $00
71 |
72 | *= $1010
73 |
74 | ;////////////////////////////////////////////////////////////////////////////////////////////
75 | ; Inicio (4110)
76 | ;////////////////////////////////////////////////////////////////////////////////////////////
77 |
78 | _Start:
79 |
80 | LDX #$11
81 | .c0 LDY #$08 ;<-
82 | .c2 LDA _DATA2,X ;<-
83 | ;BEQ .c1
84 | STA $0058,Y
85 | .c1 DEX ;<-
86 | DEY
87 | BPL .c2
88 | TXA
89 | PHA
90 | TYA
91 | PHA
92 | JSR $88C7 ; >>Open space in memory
93 | PLA
94 | TAY
95 | PLA
96 | TAX
97 | BPL .c0
98 |
99 | LDA #113 ; Fondo y borde blancos
100 | STA $FF15
101 | STA $FF19
102 |
103 | LDA #
InitScr
105 | JSR STROUT ;PrintTxt
106 |
107 | ; Copia LogoScr a 3352 ($0D18)
108 | LDX #200
109 | - LDA LogoScr-1,X
110 | STA $0D18-1,X
111 | LDA LogoScr+200-1,X
112 | STA $0D18+200-1,X
113 | DEX
114 | BNE -
115 | ; Copia LogoClr a 2328 ($0918)
116 | LDX #200
117 | - LDA LogoClr-1,X
118 | STA $0918-1,X
119 | LDA LogoClr+200-1,X
120 | STA $0918+200-1,X
121 | DEX
122 | BNE -
123 |
124 | ; Imprime la url de retrocomputacion
125 |
126 | CLC ; Coloca el cursor en la fila 20, columna 4
127 | LDX #20
128 | LDY #4
129 | JSR PLOT
130 | LDA #RetroIntro
132 | JSR STROUT ;PrintTxt
133 | LDA #$81
134 | STA $A5
135 | - LDA $A5
136 | BNE -
137 |
138 | JSR DrvDetect
139 |
140 | JMP CODESTART
141 |
142 | ;Detect present drives for devices 8-15
143 | DrvDetect:
144 | -- JSR chdrive
145 | LDA result
146 | BEQ ++ ; Not found? continue with next device
147 | LDA #IDQTY
148 | STA IDtmp
149 | - LDA IDtmp
150 | ASL
151 | TAY
152 | LDA IDptr,Y
153 | LDX IDptr+1,Y
154 | JSR cmpstr
155 | BPL + ;If found ->
156 | DEC IDtmp ;not found, try next ID string
157 | BPL -
158 | ; found or out of ID strings
159 | + LDA device
160 | SEC
161 | SBC #$08
162 | TAX
163 | LDA IDtmp
164 | STA DRVlst,X
165 |
166 | ++ INC device
167 | LDA #$10
168 | CMP device
169 | BNE --
170 |
171 | ;Copy drive list
172 | SEI
173 | +DisROMs
174 | LDX #$07
175 | - LDA DRVlst,X
176 | STA DRIVES,X
177 | DEX
178 | BPL -
179 | +EnROMs
180 | CLI
181 | RTS
182 |
183 | chdrive:
184 | ;first check if device present
185 | LDA #$00
186 | STA $90 ; clear STATUS flags
187 |
188 | LDA device ; device number
189 | JSR $FFB1 ; call LISTEN
190 | LDA #$6F ; secondary address 15 (command channel)
191 | JSR $FF93 ; call SECLSN (SECOND)
192 | JSR $FFAE ; call UNLSN
193 | LDA $90 ; get STATUS flags
194 | BNE .devnp ; device not present
195 |
196 | LDA #cmd_end-cmd
197 | LDX #cmd
199 | JSR $FFBD ; call SETNAM
200 |
201 | LDA #$0F ; file number 15
202 | LDX device ; last used device number
203 | BNE +
204 | LDX #$08 ; default to device 8
205 | + LDY #$0F ; secondary address 15
206 | JSR $FFBA ; call SETLFS
207 |
208 | JSR $FFC0 ; call OPEN
209 | BCS ++ ; if carry set, the file could not be opened
210 | LDX #$0F ; filenumber 15
211 | JSR $FFC6 ; CHKIN file now used as input
212 | LDY #$03
213 | - JSR $FFB7 ; call READST (read status byte)
214 | BNE + ; either EOF or read error
215 | JSR $FFCF ; call CHRIN (get a byte from file)
216 | DEY ; skip first 3 chars
217 | BNE -
218 | - JSR $FFB7 ; call READST
219 | BNE +
220 | JSR $FFCF ; call CHRIN
221 | STA result,Y
222 | INY
223 | JMP - ; next byte
224 | +
225 | - LDA #$00
226 | STA result,Y ; Null terminate result string
227 | LDA #$0F
228 | JSR $FFC3 ; call CLOSE
229 |
230 | JSR $FFCC ; call CLRCHN
231 | RTS
232 | ++
233 | ;... error handling for open errors ...
234 | LDY #$00
235 | BEQ - ; even if OPEN failed, the file has to be closed
236 | .devnp
237 | LDY #$00
238 | STY result ; 'clear' result string
239 | RTS
240 |
241 | cmpstr: ;Find substring, ID string addr in .a/.x. Return .x :$00 if found, $FF otherwise
242 | STA $D8
243 | STX $D9
244 | LDX #$FF
245 | STX match
246 | ; Iterate ID string until finding the 1st character of the substing
247 | LDY #$FF
248 | -- INY
249 | - INX
250 | LDA ($D8),Y
251 | BEQ ++ ; If null, exit
252 | CMP result,X
253 | BNE +
254 | ; match
255 | LDA #$00
256 | STA match
257 | BEQ -- ; continue with the next character in both strings
258 | ; no match
259 | + LDA #$FF
260 | STA match
261 | LDA result,X
262 | BEQ ++ ; end of ID string?
263 | LDY #$00 ; reset substring index
264 | BEQ -
265 | ++ LDX match
266 | RTS
267 |
268 |
269 | device: !byte $08
270 | cmd: !text "UI",$0d ; command string
271 | cmd_end:
272 | match !byte $ff ; string matched $00 or not $ff
273 |
274 | result: !fill $40, $00 ; Drive response tmp string
275 | DRVlst: !fill $08, $ff ; Available Drive list ($FF = not found)
276 | ; Expected ID substrings
277 | ID1541: !text "1541",$00 ; #ID 10
278 | ID1551: !text "TDISK",$00 ; #ID 9
279 | ID1570: !text "1570",$00 ; #ID 8
280 | ID1571: !text "1571",$00 ; #ID 7
281 | ID1581: !text "1581",$00 ; #ID 6
282 | IDCMDFD: !text "CMD FD",$00 ; #ID 5
283 | IDSD2IEC: !text "SD2IEC",$00 ; #ID 4
284 | IDULTI: !text "ULTIMATE",$00 ; #ID 3
285 | IDVICEFS: !text "VICE",$00 ; #ID 2
286 | IDVICE: !text "VIRTUAL",$00 ; #ID 1
287 | IDPI1541: !text "PI1541",$00 ; #ID 0
288 |
289 | IDQTY = 11-1
290 |
291 | IDptr: !word IDPI1541,IDVICE,IDVICEFS,IDULTI, IDSD2IEC, IDCMDFD, ID1581, ID1571, ID1570, ID1551, ID1541
292 | IDtmp: !byte IDQTY
293 |
294 | _DATA2:
295 | !word ENDOFCODE, _ENDOFCODE_
296 | !byte $00, $00, $00
297 | !word _CODESTART_
298 |
299 | !word ENDSHADOW, _ENDSHADOW_
300 | !byte $00, $00, $00
301 | !word _SHADOWCODE_
302 |
303 | ;///////////////////////////////////////////////////////////////////////////////////
304 | ; Logo de retrocomputacion
305 |
306 | LogoScr
307 | !byte 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,225,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32
308 | !byte 32,124,226,226,226,226,226,226,226,226,126,255,226,226,108,226,226,127,124,251,226,108,226,226,126,255,226,226,123,226,226,226,226,226,226,226,226,226,126,32
309 | !byte 124,226,226,226,226,226,226,226,226,226,126,97,32,32,225,226,226,226,32,225,32,225,32,32,32,97,32,32,97,226,226,226,226,226,226,226,226,226,226,126
310 | !byte 124,226,226,226,226,226,226,226,226,226,126,126,32,32,32,226,226,226,32,32,226,124,32,32,32,124,226,226,32,226,226,226,226,226,226,226,226,226,226,126
311 | !byte 32,124,226,226,226,226,226,226,226,226,126,226,226,226,124,226,226,226,124,226,226,124,226,226,126,226,226,226,126,226,226,226,226,226,226,226,226,226,126,32
312 | !byte 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,225,32,32,32,32,32,32,32,32,32,124,32,32,32,32,32,32,32,32
313 | !byte 108,226,226,226,108,226,226,127,225,226,236,127,225,226,226,127,225,32,32,225,124,251,226,32,226,226,127,108,226,226,226,225,108,226,226,127,225,226,226,123
314 | !byte 225,32,32,32,225,32,32,225,225,32,97,225,225,32,32,225,225,32,32,225,32,225,32,108,226,226,251,225,32,32,32,225,225,32,32,225,225,32,32,97
315 | !byte 32,226,226,226,32,226,226,126,124,32,126,124,225,226,226,126,32,226,226,126,32,32,226,32,226,226,226,32,226,226,226,124,32,226,226,126,124,32,32,126
316 | !byte 124,226,226,226,124,226,226,226,124,226,226,226,124,124,226,226,124,226,226,226,124,226,226,124,226,226,226,124,226,226,226,124,124,226,226,226,124,226,226,126
317 | LScrEnd
318 |
319 | LogoClr
320 | !byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
321 | !byte 0,50,50,50,50,50,50,50,50,50,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,50,50,50,50,50,50,50,50,50,0
322 | !byte 103,103,103,103,103,103,103,103,103,103,103,0,0,0,0,0,0,0,50,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,103,103
323 | !byte 101,101,101,101,101,101,101,101,101,101,101,0,0,0,0,0,0,0,50,0,0,0,0,0,0,0,0,0,50,101,101,101,101,101,101,101,101,101,101,101
324 | !byte 70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70
325 | !byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
326 | !byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
327 | !byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
328 | !byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
329 | !byte 70,70,70,70,70,70,70,70,70,70,70,70,0,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70
330 | LClrEnd
331 |
332 |
333 | _CODESTART_
334 | !pseudopc $7000 {
335 | CODESTART:
336 | JMP MainPrg ; Comienza el programa en MainPrg
337 |
338 | ; Variables
339 |
340 | TXBYTE !byte $00 ; Byte to be transmitted
341 | RXBYTE !byte $00 ; Last received byte
342 | CMDFlags !byte $00 ; Command flags
343 | ; Bit 7 (N): 1 = Last received byte is CMDON ($ff); 0 = Normal operation
344 | ; Bit 6 (V): 1 = Receive N bytes as parameters and wait for the command to complete; 0 = Normal operation
345 | ; Bits 3-0: Parameter counter for bit-6
346 | TEMPCNT1 !byte $00 ; Temporal counter 1
347 | BYTECNT !word $0000 ; 16-bit block transfer remaining bytes to receive counter
348 | BLOCKPTR !word $0000 ; Memory pointer for the block transfer command
349 |
350 | BORDERCLR !byte $00 ; Current screen border color backup
351 | FLAGS1 !byte $00 ; Status flags
352 | ; Bit 7 (N): 1 = Command mode; 0 = Normal mode
353 | ; Bit 6 (V): 1 = Last byte should be redirected to the voice synth; 0 = Last byte is meant for the terminal
354 | ; Bit 4 : 1 = Split screen enabled
355 | ; Bit 3 : 1 = Cursor blink enabled; 0 = Cursor blink disabled
356 | ; Bit 2 : 1 = Microsint enabled; 0 = Microsint disabled / not found
357 | ; Bit 1 : 1 = Terminal is starting up; 0 = Normal operation
358 | ; Bit 0 : 1 = RUN/STOP pressed, returning to BASIC
359 | ; -----
360 | PRBUFFERCNT !byte $00 ; Print buffer byte counter
361 | PRINDEXOUT !byte $00 ; Index to the print buffer byte to output next
362 | PRINDEXIN !byte $00 ; Index to the first free byte in the print buffer
363 | ; -----
364 | PRBYTE !byte $00 ; |UNUSED| Byte to be printed on screen
365 | PRSPEED !byte $00 ; Text print delay (0:no delay)
366 |
367 | WTOP !byte $00 ; Text window top limit
368 | WBOTTOM !byte $19 ; Text window bottom limit
369 | TIMER1 !byte $00 ; Timer decremented on each interrupt call
370 | CRSRTIMER !byte $00 ; Cursor blink timer, decremented on each interrupt call
371 | CRSRCHAR !byte $00 ; Character currently under the cursor
372 | CRSRCOLOR !byte $00 ; Color of the character under the cursor
373 | TEMPCNT2 !byte $00 ; Contador temporal 2
374 | BEEPTIMER !byte $00 ; Timer que decrementa en cada interrupcion
375 | TIMERDIV4 !byte $00 ; Timer que decrementa en cada interrupcion, usado para realizar acciones cada 4 interrupciones
376 | DELAYTIME !byte $00 ; Parametro (tiempos) de las rutinas de temporizacion
377 | SNDSTATUS !byte $00 ; Character beep enable
378 | FLASHSTATUS !byte $00 ; FLASHON control code enable
379 | SPLITRST !byte $00 ; Split screen raster line
380 |
381 | ;///////////////////////////////////////////////////////////////////////////////////
382 | ; ReadByte, receive a byte, store in RXBYTE
383 | ;---------------------------------------------------------------------------------------
384 |
385 | ReadByte
386 | LDA FLAGS1 ; Si estamos inicializando la terminal, ignora la recepcion
387 | AND #%00000010
388 | BNE CancelRX
389 | EnRTS
390 | rb1l:
391 | LDA #$1C
392 | STA $FF02
393 | rb1h:
394 | LDA #$00
395 | STA $FF03 ; Wait ~30uS
396 | LDA #%10010000 ; Clear Timer 2 IRQ
397 | STA $FF09
398 |
399 | LDA #%00001011 ; no parity, no echo, no tx irq (rts=0, habilita envio), no rx irq, rx enabled (dtr=0)
400 | STA ACIACOMMAND
401 | LDA #$10
402 | WaitRX1
403 | BIT $FF09
404 | ;AND #$10
405 | BEQ WaitRX1
406 |
407 | DisRTS
408 | LDA #%00000011 ; no parity, no echo, no tx irq (rts=1, deshabilita envio), no rx irq, rx enabled (dtr=0)
409 | STA ACIACOMMAND
410 | LDA #$EE ;$D2 ; 2 Coloca 2000 ($06EE) microsegundos en el Timer A
411 | STA $FF02 ; 4
412 | LDA #$06 ;$01 ; 2
413 | STA $FF03 ; 4
414 | LDA #%10010000 ; 2 Limpia el bit de interrupcion de Timer 2
415 | STA $FF09 ; 4
416 | WaitRX2
417 | LDA ACIASTATUS ; Verifica si se recibio un byte
418 | AND #%00001000
419 | BNE Received ; 3 Si transcurrio el tiempo, entonces pasaron 85+174 us sin recepcion, sigue en CancelRX
420 | LDA $FF09 ; 4 Si no transcurrieron los 85 microsegundos del Timer A
421 | AND #%00010000 ; 2
422 | BEQ WaitRX2 ; 2 vuelve a WaitRX2 para dar tiempo a que se reciba un byte
423 | CancelRX
424 | LDA #$00 ; 2 Carga RXBYTE con el valor 0
425 | STA RXBYTE ; 4
426 | CLC ; 2 Hace CARRY = 0 (no hubo recepcion)
427 | RTS ; 6 Retorna
428 | Received
429 | LDA ACIADATA ; 4 Lee en A el valor del byte recibido
430 | STA RXBYTE ; y lo almacena en RXBYTE
431 | SEC ; 2 Hace CARRY = 1 (se recibio un byte)
432 | RTS ; 6 Retorna
433 |
434 | ;//////////////////////////////////////////////////////////////////////////////////////////
435 | ; TurboRX, receives a byte stream and plays it as nibbles through the TED volume register
436 | ;------------------------------------------------------------------------------------------
437 |
438 | TurboRX
439 | LDA #%00001011 ; no parity, no echo, no tx irq (rts=0, enable reception), no rx irq, rx enabled (dtr=0)
440 | STA ACIACOMMAND
441 | TurboLoop
442 | LDA #$FB ; Set keyboard latches
443 | STA $FD30
444 | STA $FF08
445 | TXA ; 2
446 | AND #$0F ; 2
447 | TAY
448 | LDA trtable,Y
449 | STA $FF11 ; 4 Write the first sample
450 | STA $FF19 ; 4 <-
451 | ; LDA #$00 ; 2 Set Timer A to 75 ($004B) microseconds
452 | ; STA $DD05 ; 4
453 | ;DD04_1:
454 | ; LDA #$60
455 | ; STA $DD04 ; 4
456 | ; LDA $DD0D ; 4 Clear interrupt register (CIA2: NMI)
457 | ; LDA #$19 ; 2 Force load and start Timer A
458 | ; STA $DD0E ; 4 <-26 total cycles
459 |
460 | TXA ; 2 Prepare second sample
461 | ROR ; 2
462 | ROR ; 2
463 | ROR ; 2
464 | ROR ; 2
465 | AND #$0F ; 2
466 | ;TAX ; 2 <-18 cycles until here
467 | TRXWait1
468 | ; Wait 86 - 16 - 18 cycles for 11520Khz
469 | ; Wait 130 - 16 - 18 cycles for 7680KHz
470 | LDY #$41
471 | - DEY ; 2
472 | BNE -
473 |
474 | TAY
475 |
476 | ; LDA $DD0D ; 4 If Timer A didnt elapse
477 | ; AND #$01 ; 2
478 | ; BEQ TRXWait1 ; 2 go back to TRXWait1 and wiat
479 | LDA trtable,Y
480 | STA $FF11 ; 4 Write second sample
481 | STA $FF19 ; 4
482 | TRXWait2
483 | -
484 | LDA ACIASTATUS ; 4 Wait for a character
485 | AND #%00001000 ; 2
486 | BEQ - ; 3
487 | LDA ACIADATA ; 4 .A = Received character
488 | TAX ; 2
489 | BEQ TurboExit
490 |
491 | LDA $FF08 ; 4 Key press?
492 | CMP #$FF
493 | BEQ TurboLoop ; 3
494 | LDA #$FF ; Yes, send $FF
495 | STA ACIADATA
496 | JMP TurboLoop ; 3
497 |
498 | TurboExit
499 | LDA #%00000011 ; no parity, no echo, no tx irq (rts=1, reception disabled), no rx irq, rx enabled (dtr=0)
500 | _acomm4
501 | STA ACIACOMMAND
502 | RTS
503 | ; 4-bit sample to 13 TED amplitudes
504 | trtable:
505 | !byte $90,$91,$92,$93,$94,$95,$96,$97,$98,$B5,$B5,$B6,$B7,$B7,$B8,$B8
506 |
507 |
508 | ;///////////////////////////////////////////////////////////////////////////////////
509 | ; Programa principal
510 | ;///////////////////////////////////////////////////////////////////////////////////
511 |
512 | MainPrg
513 | JSR InitPalette
514 | JSR $D88B ; Clear Screen (Makes sure the Screen link table is valid from here on)
515 | SEI ; Disable interrupts
516 |
517 | LDA #$00 ; Black screen and border
518 | STA $FF15
519 | STA $FF19
520 | STA $0540 ; Repeat Space, INS/DEL and cursor keys only
521 |
522 | LDA #%00000010 ; no parity, no echo, no tx irq (rts=1), no rx irq, rx disabled (dtr=1)
523 | STA ACIACOMMAND
524 | LDA #%00011111 ; 1 stop bit, 8 data bits, baud rate generator, 19200 bps
525 | ; LDA #%00011000 ; 1 stop bit, 8 data bits, baud rate generator, 1200 bps
526 | STA ACIACONTROL
527 | LDA #$00 ; Inicializa el buffer de impresion
528 | STA PRINDEXOUT
529 | STA PRINDEXIN
530 | STA PRBUFFERCNT
531 | LDA #%00001010 ; Inicializando la terminal
532 | STA FLAGS1
533 | LDA #32 ; Pone un espacio como caracter inicial debajo del cursor
534 | STA CRSRCHAR
535 | LDA #4 ; Inicializa TIMERDIV4
536 | STA TIMERDIV4
537 | LDA #0 ; Pone a 0 los contadores de beeps
538 | STA TEMPCNT1
539 | STA TEMPCNT2
540 |
541 | ResetFkeys
542 | LDX #$07
543 | - LDA FTable,X
544 | STA $0567,X
545 | LDA #$01
546 | STA $055F,X
547 | DEX
548 | BPL -
549 |
550 | ConfigTED
551 | LDA #%00000000 ; Volumen = 0 (minimo), desactiva canales 1 y 2 y reinicia los osciladores
552 | STA $FF11
553 | LDA #$03
554 | STA $FF10 ; Voice 2 freq
555 | LDA #$9a
556 | STA $FF0F
557 | LDA #$10 ; Habilita el TED (activa la pantalla)
558 | ORA $FF06
559 | STA $FF06
560 | ; LDA #%11111110 ; Clear most significant bit in TED's raster register
561 | ; AND $FF0A
562 | ; STA $FF0A
563 | LDA #204 ; Set the raster line number where interrupt should occur
564 | STA $FF0B
565 | LDA #Irq
568 | STA $0315
569 | LDA #%10100010 ; Enable raster interrupt signals from TED, and clear MSB in TED's raster register
570 | STA $FF0A
571 |
572 | ; Set STREND variable (needed by the PAINT ROM routine)
573 | LDA #$00
574 | STA $31
575 | LDA #$40
576 | STA $32
577 |
578 | CLI
579 | LDX #Version
582 | ;STA AddTLoop + 2
583 | JSR AddText ; y la agrega al buffer de impresion
584 | LDA #1 ; Velocidad: 1 caracter por cuadro
585 | STA PRSPEED
586 | STA TIMER1
587 | ;JSR StopCRSR
588 | JSR PrintBuffer ; Procesa el buffer de impresion
589 | ;JSR StartCRSR
590 |
591 | LDA #100 ; Espera 2 segundos
592 | STA PRSPEED
593 | STA TIMER1
594 | LDA #0 ; Inicializa el temporizador del cursor para que empiece encendido
595 | STA CRSRTIMER
596 | Wait1 JSR BlinkCRSR ; Procesa el parpadeo del cursor
597 | LDA TIMER1
598 | BNE Wait1
599 |
600 | LDA #$00 ; A partir de ahora imprime sin retardo
601 | STA PRSPEED
602 | STA TIMER1
603 |
604 | LDX #Msg06
607 | ;STA AddTLoop + 2
608 | JSR AddText ; and it's added to the print buffer
609 | JSR PrintBuffer ; Process the print buffer
610 |
611 | LDA #0 ; Inicializa el temporizador del cursor para que empiece encendido
612 | STA CRSRTIMER
613 | LDA FLAGS1 ; Se termino de inicializar la terminal
614 | AND #%11111101
615 | STA FLAGS1
616 | PrintRX
617 | LDA PRBUFFERCNT ; Si no hay elementos en el buffer para imprimir, sigue en Blink
618 | BEQ Blink
619 | LDA TIMER1 ; Si no es momento de imprimir (TIMER1<>0), sigue en Blink
620 | BNE Blink
621 | ;JSR StopCRSR
622 | JSR PrintBuffer ; Procesa el buffer de impresion
623 | ;JSR StartCRSR
624 | Blink
625 | LDA #%00000001 ; Verifica si hay que volver al BASIC
626 | AND FLAGS1
627 | BEQ +
628 | JMP ExitPrg ; si es asi, sigue en ExitPrg para salir del programa
629 | + JSR BlinkCRSR ; sino, procesa el parpadeo del cursor
630 | JMP PrintRX ; y vuelve a PrintRX
631 |
632 | ;///////////////////////////////////////////////////////////////////////////////////
633 | ; Procesa el parpadeo del cursor
634 | ;///////////////////////////////////////////////////////////////////////////////////
635 |
636 | BlinkCRSR
637 | LDA FLAGS1
638 | AND #%00001000
639 | BEQ BlinkEnd
640 | LDA CRSRTIMER ; Si no es momento de invertir el cursor (CRSRTIMER<>0), sigue en BlinkEnd
641 | BNE BlinkEnd
642 | LDA #30 ; Si CRSRTIMER llego a 0, lo renovamos
643 | STA CRSRTIMER
644 | LDX CRSRCOLOR
645 | LDY CURRCOLUMN
646 | LDA #%10000000 ; e invertimos el caracter bajo el cursor
647 | EOR (CURRLINEPTR), Y
648 | STA (CURRLINEPTR), Y
649 | BPL +
650 | LDX $053B
651 | + TXA
652 | STA ($EA),Y
653 | BlinkEnd
654 | RTS
655 |
656 | ;///////////////////////////////////////////////////////////////////////////////////
657 | ; Deshabilita el cursor, y restaura el caracter debajo del cursor
658 | ;///////////////////////////////////////////////////////////////////////////////////
659 |
660 | StopCRSR
661 | LDY CURRCOLUMN
662 | LDA CRSRCHAR
663 | STA (CURRLINEPTR), Y
664 | LDA CRSRCOLOR
665 | STA ($EA),Y
666 | RTS
667 |
668 | ;///////////////////////////////////////////////////////////////////////////////////
669 | ; Habilita el cursor, y resguarda el caracter debajo del cursor
670 | ;///////////////////////////////////////////////////////////////////////////////////
671 |
672 | StartCRSR
673 | LDY CURRCOLUMN
674 | LDA (CURRLINEPTR), Y
675 | STA CRSRCHAR
676 | LDA ($EA),Y
677 | STA CRSRCOLOR
678 | LDA #0 ; Inicializa el temporizador del cursor para que empiece encendido
679 | STA CRSRTIMER
680 | RTS
681 |
682 | ;///////////////////////////////////////////////////////////////////////////////////
683 | ; Rutina de impresion, imprime el buffer completo
684 | ;///////////////////////////////////////////////////////////////////////////////////
685 |
686 | PrintBuffer
687 | ; LDA PRBUFFERCNT ; Si no hay elementos en el buffer para imprimir, sigue en PrintEnd
688 | ; BEQ PrintEnd
689 | ; LDA TIMER1 ; Si no es momento de imprimir (TIMER1<>0), vuelve a PrintBuffer
690 | ; BNE PrintBuffer
691 | ; LDX PRINDEXOUT
692 | ; LDA PrBuffer, X
693 | ; JSR CHROUT
694 | ; JSR Beep
695 | ; INC PRINDEXOUT
696 | ; DEC PRBUFFERCNT
697 | ; LDA PRSPEED ; Renueva TIMER1 con el valor de PRSPEED
698 | ; STA TIMER1
699 | ; JMP PrintBuffer ; Vuelve a PrintBuffer para seguir imprimiendo el resto del buffer
700 | ; PrintEnd
701 | ; RTS
702 |
703 | JSR StopCRSR
704 | .pb0
705 | LDA PRBUFFERCNT ; If the buffer is empty, continues on PrintEnd
706 | BEQ PrintEnd
707 | ;BNE +
708 | ;LDA #$01
709 | ;STA TIMER1
710 | - ;LDA TIMER1 ; If it's not the time to print (TIMER1<>0), waits
711 | ;BNE -
712 | ;JSR NoChar ; Mutes the print beep
713 | ;BNE PrintEnd
714 | + LDA TIMER1 ; If its not the time to print (TIMER1<>0), returns to .pb0
715 | BNE .pb0
716 | LDX PRINDEXOUT
717 | ;LDA #%11000000 ; Checks the flags states
718 | BIT FLAGS1
719 | BMI .pb2 ; Command mode? -> Parse comnands
720 | BVS .pb4 ; Voice mode, continue on .PB4
721 | LDA PrBuffer, X
722 | CMP #$FF ; Check for commands
723 | BEQ .pb1
724 |
725 | CMP #$FE ; Check for command mode exit <- Captures extraneous $FE characters
726 | BEQ .pb2
727 |
728 | JSR CharOut ;CHROUT replacement routine (Codebase)
729 | LDA SNDSTATUS
730 | BNE ++
731 | JSR Beep ; Print beep
732 | ++ INC PRINDEXOUT
733 | DEC PRBUFFERCNT
734 | LDA PRSPEED ; Renew TIMER1 with PRSPEED
735 | STA TIMER1
736 | JMP .pb0 ; Return to .pb0 to process the rest of the buffer
737 | PrintEnd
738 | ; LDA TEMPCNT2
739 | ;- CMP TEMPCNT2
740 | ; BEQ -
741 | ; JSR NoChar
742 | JSR StartCRSR
743 | RTS
744 | ; // Enter command mode
745 | .pb1
746 | INC PRINDEXOUT
747 | DEC PRBUFFERCNT ; Skip the $FF character
748 | LDA FLAGS1
749 | ORA #%10000000 ; Enters command mode
750 | STA FLAGS1
751 | BNE .pb0
752 | ; Parse commands
753 | .pb2
754 | JSR NoChar ; Mutes the print beep
755 | INC PRINDEXOUT
756 | DEC PRBUFFERCNT ; Update pointers
757 | LDA PrBuffer,X
758 | BPL + ; Invalid command (bit7=0)
759 | CMP #MAXCMD+1
760 | BCC ++ ; Is it less than or equal to the highest implemented command ($B6)?
761 | + LDA #$8F ; Invalid command, replace with unimplemented command ($8F)
762 | ++ AND #%01111111 ; -128
763 | ASL
764 | TAY
765 | LDA CmdTable+1,Y
766 | STA .pb3+2
767 | LDA CmdTable,Y ; Point the JSR to the command address (self-modifying)
768 | STA .pb3+1
769 | .pb3
770 | JSR CmdFE ; Command call<<<<
771 | LDA #$00
772 | STA CMDFlags ; Command completed, reset CMDFlags
773 | JMP .pb0 ; Return to .pb0 to process the rest of the buffer
774 |
775 | .pb4 ; Insert byte into the voice buffer
776 | JSR NoChar ; Mute the print beep
777 | LDA PrBuffer,X
778 | CMP #$FF ; Check for commands
779 | BEQ .pb1
780 | INC PRINDEXOUT
781 | DEC PRBUFFERCNT
782 | !ifdef _SYNTH_ {
783 | JSR AddToSpBuffer
784 | }
785 | JMP .pb0
786 |
787 | ;///////////////////////////////////////////////////////////////////////////////////
788 | ; CHROUT replacement, equivalent to the Kernal routine but no quote mode, 40
789 | ; logical columns and text window support
790 | ; Petscii -> Screen code by Mace (from Codebase64)
791 | ;///////////////////////////////////////////////////////////////////////////////////
792 | CharOut:
793 | CMP #$20 ; if A<32 then...
794 | BCC ddCtrl ; Control characters->
795 |
796 | CMP #$60 ; if A<96 then...
797 | BCC dd1
798 |
799 | CMP #$80 ; if A<128 then...
800 | BCC dd2
801 |
802 | CMP #$a0 ; if A<160 then...
803 | BCC ddCtrl ; Control characters->
804 |
805 | CMP #$c0 ; if A<192 then...
806 | BCC dd4
807 |
808 | CMP #$ff ; if A<255 then...
809 | BCC ddRev
810 |
811 | LDA #$7e ; A=255, then A=126
812 | BNE ddEnd
813 |
814 | dd2 AND #$5f ; if A=96..127 then strip bits 5 and 7
815 | BNE ddEnd
816 |
817 | dd4 EOR #$c0 ; if A=160..191 then flip bits 6 and 7
818 | BNE ddEnd
819 |
820 | dd1 AND #$3f ; if A=32..95 then strip bits 6 and 7
821 | BPL ddEnd ; <- you could also do .byte $0c here
822 |
823 | ddRev
824 | EOR #$80 ; flip bit 7 (reverse on when off and vice versa)
825 | ddEnd
826 | LDX $C7
827 | BEQ +
828 | ORA #$80 ; Inverse video
829 |
830 | + LDY CURRCOLUMN
831 | LDX CURRLINE
832 | STA (CURRLINEPTR),Y ; Write character to screen
833 | JSR $E008 ; Update Attributes
834 | INY
835 | CPY #40 ; Reached right border?
836 | BNE cu1 ; No, go update screen pointers
837 | LDY #00 ; Wrap to column 0
838 | INX
839 | CPX WBOTTOM ; Pass bottom window border?
840 | BCC cu1 ; No, go update screen pointers
841 | DEX
842 | TXA
843 | PHA
844 | TYA
845 | PHA
846 | JSR $DA89 ; Scroll text window
847 | PLA
848 | TAY
849 | PLA
850 | TAX
851 |
852 | cu1 STY CURRCOLUMN
853 | STX CURRLINE
854 | JSR $D8AA ; Set start of line (.X = line)
855 | ;JSR $EA24 ; Synchronize color RAM pointer
856 | ce0 RTS
857 | ddCtrl ;Control chars
858 | CMP #$13 ; Check for HOME
859 | BNE + ; No, next
860 | LDX WTOP
861 | LDY #$00
862 | BEQ cu1
863 | + CMP #$93 ; Check for CLEAR
864 | BNE + ; No, next
865 | LDX WBOTTOM
866 | - DEX
867 | JSR $DAF7 ; Clear Line
868 | CPX WTOP
869 | BNE -
870 | LDX WTOP
871 | LDY #$00
872 | BEQ cu1
873 | + CMP #$91 ; Check for Cursor UP
874 | BNE + ; No, next
875 | LDX CURRLINE
876 | CPX WTOP ; Cursor at the top of the text window?
877 | BEQ ce0 ; Yes, do nothing
878 | DEX
879 | BPL cu1+2
880 | + CMP #$11 ; Check for Cursor DOWN
881 | BNE + ; No, next
882 | LDX CURRLINE
883 | INX
884 | CPX WBOTTOM ; Cursor beyond the bottom of the text window?
885 | BNE cu1+2 ; No, update pointers
886 | DEX
887 | TXA
888 | PHA
889 | JSR $DA89 ; Yes, scroll text window
890 | PLA
891 | TAX
892 | BNE cu1+2
893 | + CMP #$9D ; Check for Cursor LEFT
894 | BNE ++ ; No, next
895 | LDX CURRLINE
896 | LDY CURRCOLUMN
897 | DEY
898 | BPL cu1 ; Cursor still on same row -> update pointers
899 | CPX WTOP
900 | BEQ + ; Cursor is already at the text window's HOME
901 | DEX
902 | LDY #38 ; < 39-1, to be incremented to the correct value further ahead
903 | + INY ; 38 to 39 if going up a row, 255 to 0 if already at HOME
904 | BPL cu1 ; update pointers
905 | ++ CMP #$1D ; Check for Cursor RIGHT
906 | BNE + ; No, next
907 | LDX CURRLINE
908 | LDY CURRCOLUMN
909 | INY
910 | CPY #40 ; Beyond column 40?
911 | BNE cu1 ; No, update pointers
912 | LDY #$00
913 | INX
914 | CPX WBOTTOM ; Do we need to scroll?
915 | BNE cu1 ; No, update pointers
916 | TXA
917 | PHA
918 | TYA
919 | PHA
920 | JSR $DA89 ; Yes, scroll
921 | PLA
922 | TAY
923 | PLA
924 | TAX
925 | DEX
926 | JMP cu1
927 | + CMP #$0D ; Check for RETURN
928 | BEQ +
929 | CMP #$8D ; Check for SHIFT-RETURN
930 | BNE ++
931 | ;+ LDA SNDSTATUS
932 | ;BPL +
933 | ;JSR Beep ; Play beep if SNDSTATUS = $80
934 | + LDX CURRLINE
935 | LDY #0
936 | STY $C7
937 | INX
938 | CPX WBOTTOM ; Beyond the text window's bottom?
939 | BEQ +
940 | JMP cu1 ; No, move cursor
941 | + DEX
942 | TXA
943 | PHA
944 | TYA
945 | PHA
946 | JSR $DA89 ; Yes, scroll
947 | PLA
948 | TAY
949 | PLA
950 | TAX
951 | + JMP cu1
952 | ++ CMP #$14 ; Check for DELETE
953 | BNE ++ ; No, next
954 | LDX CURRLINE
955 | LDY CURRCOLUMN
956 | BEQ + ; If already on column 0, branch
957 | DEY
958 | STY CURRCOLUMN
959 | - INY
960 | LDA (CURRLINEPTR),Y
961 | DEY
962 | STA (CURRLINEPTR),Y
963 | INY
964 | LDA ($EA),Y
965 | DEY
966 | STA ($EA),Y
967 | INY
968 | CPY #39
969 | BNE -
970 | LDA #$20 ; Space
971 | STA (CURRLINEPTR),Y
972 | LDA $053B
973 | STA ($EA),Y
974 | - JMP cu1+2
975 | + CPX WTOP
976 | ; BNE + ; At HOME?
977 | BEQ + ; Yes, do nothing <<<<<<<<<<<<<<<<<<<<<
978 | ;RTS ; Yes, do nothing
979 | ;+
980 | LDY #39
981 | STY CURRCOLUMN
982 | DEX
983 | STX CURRLINE
984 | JSR $D8AA ; Update pointers
985 | ;JSR $EA24
986 | LDA #$20 ; Space
987 | STA (CURRLINEPTR),Y
988 | LDA $053B
989 | STA ($EA),Y
990 | + RTS
991 | ++ CMP #$82 ; Check for FLASH ON
992 | BNE++
993 | LDA FLASHSTATUS
994 | BEQ + ; if disabled do nothing
995 | RTS
996 | + LDA #$80
997 | STA $53C
998 | RTS
999 | ++ CMP #$84 ; Check for FLASH OFF
1000 | BNE +
1001 | LDA #$00
1002 | STA $53C
1003 | RTS
1004 | + CMP #$94 ; Check for INSERT
1005 | BNE ++ ; No, siguiente
1006 | LDY #39
1007 | LDA (CURRLINEPTR),Y
1008 | CMP #$20 ; Space in the row's last column?
1009 | BEQ +
1010 | - RTS ; No, do nothing
1011 | + CPY CURRCOLUMN ; Cursor at the last column?
1012 | BEQ - ; Yes, do nothing
1013 | - DEY
1014 | LDA (CURRLINEPTR),Y
1015 | INY
1016 | STA (CURRLINEPTR),Y
1017 | DEY
1018 | LDA ($EA),Y
1019 | INY
1020 | STA ($EA),Y
1021 | DEY
1022 | CPY CURRCOLUMN
1023 | BNE -
1024 | LDA #$20
1025 | STA (CURRLINEPTR),Y
1026 | LDA $053B
1027 | STA ($EA),Y
1028 | RTS
1029 | ++ CMP #$12 ; Check for RVSON
1030 | BNE + ; No, next
1031 | LDA #$01
1032 | STA $C7 ; Reverse ON
1033 | RTS
1034 | + CMP #$92 ; Check for RVSOFF
1035 | BNE + ; No, next
1036 | LDA #$00
1037 | STA $C7 ; Reverse OFF
1038 | RTS
1039 | + CMP #$08 ; Check disable CBM+SHIFT
1040 | BNE + ; No, next
1041 | LDA #$80
1042 | STA $0547
1043 | RTS
1044 | + CMP #$09 ; Check enable CBM+SHIFT
1045 | BNE + ; No, next
1046 | LDA #$00
1047 | STA $0547
1048 | RTS
1049 | + CMP #$0E ; Check switch to Uppercase/Lowercase
1050 | BNE +
1051 | LDA $FF13
1052 | ORA #$04
1053 | BNE ++
1054 | + CMP #$8E ; Check switch to Uppercase/Graphics
1055 | BNE +
1056 | LDA $FF13
1057 | AND #%11111011
1058 | ++ STA $FF13
1059 | RTS
1060 | + CMP #$07 ; Check for BELL
1061 | BNE +
1062 | LDA #BEEPTIME
1063 | STA BEEPTIMER
1064 | LDA $FF11
1065 | ORA #%00110100
1066 | STA $FF11
1067 | ;LDA #$14 ; Mute sound
1068 | ;STA SIDREG+18
1069 | ;LDA #$15 ; And turn it on again
1070 | ;STA SIDREG+18
1071 | RTS
1072 | + JSR $DCE6 ; Check colors (Kernal)
1073 | RTS
1074 |
1075 | ;///////////////////////////////////////////////////////////////////////////////////
1076 | ; Print beep
1077 | ;///////////////////////////////////////////////////////////////////////////////////
1078 | Beep
1079 | LDA BEEPTIMER
1080 | BNE +
1081 | LDA #BEEPTIME
1082 | STA BEEPTIMER ; Reset beep timer
1083 | + LDA #$01 ; Si TEMPCNT1 es impar sigue en DoBeep2
1084 | AND TEMPCNT1
1085 | BNE +
1086 | LDA #$1A ; Freq channel 1 = ~470 Hz
1087 | BNE ++
1088 | + LDA #$45 ; Freq channel 1 = ~590 Hz
1089 | ++ STA $FF0E
1090 | LDA $FF12
1091 | AND #$FC
1092 | ORA #$03
1093 | STA $FF12
1094 | ; LDA #$01 ; Si TEMPCNT1 es impar sigue en DoBeep2
1095 | ; AND TEMPCNT1
1096 | LDA #%00010010 ; Volumen = 2 (Low), activa canales 1 y 2 en modo tono
1097 | ORA $FF11
1098 | STA $FF11
1099 |
1100 | INC TEMPCNT1
1101 | RTS ;JMP EndBeep
1102 |
1103 | NoChar
1104 | LDA #%00010000 ; Volumen = 0
1105 | STA $FF11
1106 | RTS
1107 |
1108 | ;///////////////////////////////////////////////////////////////////////////////////
1109 | ; Ingresa los caracteres de la cadena al buffer de impresion
1110 | ;///////////////////////////////////////////////////////////////////////////////////
1111 |
1112 | AddText
1113 | STX AddTLoop + 1
1114 | STY AddTLoop + 2
1115 |
1116 | LDX #$00 ; Inicializa X a 0
1117 | AddTLoop
1118 | LDA PrBuffer, X ; Lee un byte de la cadena a imprimir
1119 | BNE AddTLoop1 ; Si es 0, retorna
1120 | RTS
1121 | AddTLoop1
1122 | ; SEI
1123 | JSR AddToPrBuffer ; sino llama a AddToPrBuffer para agregarlo al buffer de impresion
1124 | ; CLI
1125 | INX ; Pasa al siguiente caracter
1126 | JMP AddTLoop ; y vuelve a AddTLoop
1127 |
1128 | ;///////////////////////////////////////////////////////////////////////////////////
1129 | ; Get a character from the print buffer
1130 | ;///////////////////////////////////////////////////////////////////////////////////
1131 | GetFromPrBuffer
1132 | LDA PRBUFFERCNT
1133 | BEQ GetFromPrBuffer ; Wait for a character in the print buffer
1134 | LDX PRINDEXOUT
1135 | INC PRINDEXOUT
1136 | DEC PRBUFFERCNT ; Update pointers
1137 | LDA PrBuffer,X ; Get character
1138 | RTS
1139 |
1140 | ;///////////////////////////////////////////////////////////////////////////////////
1141 | ; Insert the character in .A, to the print buffer
1142 | ;///////////////////////////////////////////////////////////////////////////////////
1143 |
1144 | AddToPrBuffer
1145 | PHA
1146 | LDY PRINDEXIN ; Loads .Y with PRINDEXIN
1147 | - LDA PRBUFFERCNT ; If PRBUFFERCNT=255 (buffer full) waits until a space is open
1148 | EOR #$FF
1149 | BEQ -
1150 | ;SEI ;Disable IRQs
1151 | PLA
1152 | STA PrBuffer, Y
1153 | INC PRINDEXIN ; Increment PRINDEXIN
1154 | INC PRBUFFERCNT ; and PRBUFFERCNT
1155 | ;CLI ; Enable IRQs
1156 | RTS
1157 |
1158 | ;///////////////////////////////////////////////////////////////////////////////////
1159 | ; Espera a que se haya impreso completo el buffer de impresion
1160 | ;///////////////////////////////////////////////////////////////////////////////////
1161 |
1162 | WaitPrint
1163 | LDA PRBUFFERCNT ; Espera hasta que PRBUFFERCNT sea 0
1164 | BNE WaitPrint
1165 | RTS
1166 |
1167 | ;///////////////////////////////////////////////////////////////////////////////////
1168 | ; Vuelve al BASIC
1169 | ;///////////////////////////////////////////////////////////////////////////////////
1170 |
1171 | ExitPrg
1172 | SEI ; Deshabilita las interrupciones
1173 | JSR b3cancel2 ;Cancel split screen
1174 | JSR _txtmode ; Switch to text mode
1175 | LDA #24
1176 | STA $07E5
1177 | LDA #$0F ; Volumen = 15 (maximo), desactiva canales 1 y 2
1178 | STA $FF11
1179 | LDA #32 ; Imprime un espacio
1180 | JSR CHROUT
1181 | LDA #ExitMsg
1183 | JSR STROUT ;PrintTxt
1184 | LDA #%00000010 ; no parity, no echo, no tx irq (rts=1), no rx irq, rx disabled (dtr=1)
1185 | STA ACIACOMMAND
1186 | ; LDA #%01111111
1187 | ; STA $DC0D ; "Switch off" interrupts signals from CIA-1
1188 | ; STA $DD0D ; "Switch off" interrupts signals from CIA-2
1189 | LDA #$0E ; Restaura el vector de interrupcion por defecto
1190 | STA $0314
1191 | LDA #$CE
1192 | STA $0315
1193 | LDA #161 ; Set the raster line number where interrupt should occur
1194 | STA $FF0B
1195 | LDA #%10100010 ; Enable raster interrupt signals from TED, and clear MSB in TED's raster register
1196 | STA $FF0A
1197 | LDA #0 ; Vacia el buffer del teclado
1198 | STA $EF
1199 | CLI ; Vuelve a habilitar las interrupciones
1200 | RTS ; Retorna al BASIC
1201 |
1202 | ;///////////////////////////////////////////////////////////////////////////////////
1203 | ; Rutina de interrupcion
1204 | ;///////////////////////////////////////////////////////////////////////////////////
1205 |
1206 | Irq
1207 | PHA ; store register A in stack
1208 | TXA
1209 | PHA ; store register X in stack
1210 | TYA
1211 | PHA ; store register Y in stack
1212 |
1213 | ;DEC $FF19
1214 |
1215 | ; LDA #%10000000 ; Volumen = 0 (minimo), desactiva canales 1 y 2 y reinicia los osciladores
1216 | ; STA $FF11
1217 |
1218 | ; INC TEMPCNT2
1219 |
1220 | ChkTimer1
1221 | LDA TIMER1 ; Si TIMER1<>0, hace TIMER1--
1222 | BEQ ChkTimer2
1223 | DEC TIMER1
1224 | ChkTimer2
1225 | LDA CRSRTIMER ; Si TIMERCRSR<>0, hace CRSRTIMER--
1226 | BEQ EndTimers
1227 | DEC CRSRTIMER
1228 | EndTimers
1229 |
1230 | ; BNE ChkBuffer
1231 | ; LDA FLAGS1 ; Indica que ya no tenemos que emitir beeps
1232 | ; AND #%11110111
1233 | ; STA FLAGS1
1234 |
1235 | ChkBuffer
1236 | LDA PRBUFFERCNT ; Si no hay elementos en el buffer para imprimir, sigue en +
1237 | BNE ReadBytes
1238 | ; LDA FLAGS1 ; Si hay elementos, habilita los beeps de impresion
1239 | ; EOR #%00001000
1240 | ; STA FLAGS1
1241 |
1242 | ;+ LDA #%00001000 ; Chequea si hay que procesar los beeps de impresion
1243 | ; AND FLAGS1
1244 | ; BEQ EndBeep
1245 | ; LDA #BEEPTIME ; Si hay beeps pendientes, renueva el temporizador de beep
1246 | ; STA BEEPTIMER
1247 |
1248 | ;///////////////////////////////////////////////////////////////////////////////////
1249 | ; Genera el beep de impresion en pantalla
1250 |
1251 | DoBeep
1252 | LDA BEEPTIMER ; Si BEEPTIMER no llego a 0, lo decrementa
1253 | BEQ ReadBytes
1254 | DEC BEEPTIMER
1255 | BNE ReadBytes
1256 |
1257 |
1258 | NoBeep
1259 | LDA #%00010000 ; Volumen = 8 (maximo), activa canales 1 y 2 en modo tono y reinicia los osciladores
1260 | STA $FF11
1261 | ;LDA #0 ; Pone a 0 los contadores de beep
1262 | ;STA TEMPCNT1
1263 | ;STA TEMPCNT2
1264 | EndBeep
1265 |
1266 | ;///////////////////////////////////////////////////////////////////////////////////
1267 | ; Lee hasta 3 bytes del puerto RS232
1268 |
1269 | ReadBytes
1270 | LDA #%10100000 ; Disable raster interrupt signals from TED, and clear MSB in TED's raster register
1271 | STA $FF0A
1272 |
1273 | LDA FLAGS1
1274 | AND #%00010000 ; Is screen split enabled?
1275 | BEQ+
1276 | LDA SPLITRST
1277 | STA $FF0B
1278 | LDA #IrqB3
1281 | STA $0315
1282 | LDA VMODE
1283 | ORA $FF07
1284 | STA $FF07
1285 | LDA #$18 ; Attributes at $1800
1286 | STA $FF14
1287 | LDA $FF12
1288 | AND #$FB ; Bitmap in RAM
1289 | STA $FF12 ; Bitmap at $2000
1290 | LDA #$3B ; Bitmap mode
1291 | BNE ++
1292 |
1293 | + LDA #$10 ; Habilita el TED (activa la pantalla)
1294 | ORA $FF06
1295 | ++ STA $FF06
1296 |
1297 | LDX #$03 ; Lee hasta 3 bytes del RS232
1298 | ReadBLoop
1299 | LDA PRBUFFERCNT ; Si PRBUFFERCNT=255 (buffer lleno) sigue en ReadBEnd
1300 | EOR #$FF
1301 | BEQ ReadBEnd
1302 |
1303 | LDA #%00001111 ; Z = 0 if there's no parameters left to receive
1304 | BIT CMDFlags ; Check command flags
1305 | BVC + ; If we're not waiting for parameters, receive character
1306 | BEQ ReadBEnd ; If we were waiting for parameters but all were received, do not receive more characters
1307 | ; until the command is completed
1308 | + JSR ReadByte ; Receive a character from RS232
1309 | BCC ++ ;ReadBEnd ; If none is received, continue on Speak
1310 | LDA RXBYTE ; Get the received character
1311 | JSR AddToPrBuffer ; Insert it into the print buffer
1312 |
1313 | ;LDA #%00001111 ; Z = 0 if there's no parameters left to receive
1314 | BIT CMDFlags ; Check command flags
1315 | BMI .cmdchk ; If the last character was CMDON, check which command was received
1316 | BVS + ; Branch if we're waiting for parameters
1317 | LDA RXBYTE ; Not waiting for command or parameters
1318 | BPL ++ ; If bit 7 is not set, it isn't a command
1319 | BIT FLAGS1 ; If bit 7 is set, check that we are in command mode
1320 | BMI .cmdchk ; Yes, it is a command
1321 | EOR #$FF ; Check if the received character is CMDON
1322 | BEQ .cmdon ;BNE ++
1323 | CMP #$01 ; Check if the character is an extraneous CMDOFF
1324 | BNE ++
1325 | LDA #$00 ; Last received characters is an extraneous CMDOFF
1326 | BEQ +++
1327 | .cmdon
1328 | LDA #%10000000 ; Last received character is CMDON
1329 | +++ STA CMDFlags ; Set CMDFlags
1330 | BNE ++
1331 | + DEC CMDFlags ; A parameter character was received, decrement counter
1332 |
1333 | -
1334 | ++ DEX ; Decrementa X
1335 | BNE ReadBLoop ; if != 0, return to ReadBLoop
1336 | BEQ ReadBEnd ; Continue on Speak
1337 |
1338 | .cmdchk ; Check the received command and set CMDFlags accordingly
1339 | LDA RXBYTE ; Get the received character
1340 | BPL + ; Invalid command (bit 7 unset)
1341 | CMP #MAXCMD+1
1342 | BCC ++ ; Is it less than or equal to the highest implemented command ($B6)?
1343 | + LDA #$8F ; Invalid command, replace with unimplemented command ($8F)
1344 | ++ AND #%01111111 ; -128
1345 | TAY
1346 | LDA CmdParTable,Y ; Parameter count
1347 | AND #%00001111 ; Clear unwanted bits
1348 | ORA #%01000000 ; Enable parameter wait
1349 | STA CMDFlags ; Set CMDFlags
1350 | BNE - ; Continue the loop
1351 |
1352 |
1353 | ; JSR ReadByte ; Lee un byte desde el RS232
1354 | ; BCC ReadBEnd ; Si no se recibio nada, sigue en ReadBEnd
1355 | ; LDA RXBYTE ; Lee el byte recibido
1356 | ; JSR AddToPrBuffer ; Agrega el byte al buffer de impresion
1357 | ; ; JMP ReadBNext ; sigue en ReadBNext
1358 | ; ReadBNext
1359 | ; DEX ; Decrementa X
1360 | ; BNE ReadBLoop ; Si no llego a 0, vuelve a ReadBLoop
1361 | ReadBEnd
1362 |
1363 | ChkKey
1364 | JSR GETIN ; Leemos el buffer del teclado
1365 | BEQ ExitIrq ; Si no hay ninguna tecla presionada, sigue en ExitIrq
1366 | STA TXBYTE ; sino copia el caracter a TXBYTE
1367 | CMP #$03 ;JSR STOP ; Chequea si se presiono la tecla STOP
1368 | BNE +
1369 | LDA #%00000001 ; Si es STOP, indica que hay que volver al BASIC
1370 | ORA FLAGS1
1371 | STA FLAGS1
1372 | LDA #0 ; Pone a 0 la bandera STREY que indica que se presiono STOP
1373 | STA $91
1374 | JMP ExitIrq ; y sigue en ExitIrq para salir de la interrupcion
1375 | + ;LDA TXBYTE ; Verifica si la tecla presionada es SHIFT + RETURN
1376 | CMP #$8D
1377 | BNE +
1378 | LDA #$0A ; y si es asi, la convierte en LF
1379 | BNE ++
1380 | + CMP #$A7 ; CBM+M
1381 | BNE +
1382 | LDA #$FF
1383 | EOR SNDSTATUS
1384 | STA SNDSTATUS
1385 | JMP ExitIrq
1386 | + CMP #$88 ; F7?
1387 | BNE +
1388 | LDX $0543 ; Shift keys flag
1389 | CPX #$02 ; C= pressed?
1390 | BNE ++
1391 | ;Test terminal not in command mode
1392 | BIT CMDFlags
1393 | BVS ExitIrq
1394 | LDA #>SETUP ; Modify Stack
1395 | PHA
1396 | LDA #IrqB3
1434 | ; STA $0315
1435 | ; LDA VMODE
1436 | ; ORA $FF07
1437 | ; STA $FF07
1438 | ; LDA $FF12
1439 | ; AND #$FB ; Bitmap in RAM
1440 | ; STA $FF12 ; Bitmap at $2000
1441 | ; LDA #$3B ; Bitmap mode
1442 | ; BNE ++
1443 |
1444 | ; + LDA #$10 ; Habilita el TED (activa la pantalla)
1445 | ; ORA $FF06
1446 | ; ++ STA $FF06
1447 |
1448 | LDA $FB
1449 | PHA
1450 | LDA #$00
1451 | STA $FB
1452 | PHP
1453 | CLI
1454 | JSR $DB11 ; Scan keyboard
1455 | PLP
1456 | PLA
1457 | STA $FB
1458 |
1459 |
1460 | PLA
1461 | TAY ; restore register Y from stack
1462 | PLA
1463 | TAX ; restore register X from stack
1464 | PLA ; restore register A from stack
1465 | ;JMP $CE0E ; Jump into KERNAL's standard interrupt service routine to handle keyboard scan, cursor display etc.
1466 | JMP $FCBE
1467 |
1468 | ;///////////////////////////////
1469 | ; Init color codes palette
1470 | ;///////////////////////////////
1471 |
1472 | InitPalette:
1473 | LDX #$0F
1474 | - LDA Palette,X
1475 | STA $0113,X
1476 | DEX
1477 | BPL -
1478 | RTS
1479 |
1480 | ;///////////////////////////////////////////////////////////////////////////////////
1481 | ; SETUP SCREEN
1482 | ;///////////////////////////////////////////////////////////////////////////////////
1483 |
1484 | SETUP:
1485 | +DisROMs
1486 | JSR _SETUP
1487 | +EnROMs
1488 | JMP ExitIrq
1489 |
1490 | ;///////////////////////////////////////////////////////////////////////////////////
1491 | ; COMMANDS
1492 | ;///////////////////////////////////////////////////////////////////////////////////
1493 |
1494 | ;///////////////////////////////////////////////////////////////////////////////////
1495 | ; 128: Set the transfer memory pointer, requires 2 parameter
1496 | ; bytes: destination address (low, high)
1497 |
1498 | Cmd80
1499 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1500 | STA BLOCKPTR ; and store it in BLOCKPTR
1501 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1502 | STA BLOCKPTR + 1 ; and store it in BLOCKPTR + 1
1503 | RTS
1504 |
1505 | ;///////////////////////////////////////////////////////////////////////////////////
1506 | ; 129: Select a preset address for memory transfer,
1507 | ; requires 1 parameter byte: Destiny address preset
1508 |
1509 | Cmd81
1510 | LDY #$00
1511 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1512 | ;EOR #$00
1513 | BEQ Addr00 ; If $00 go to Addr00
1514 | CMP #$10
1515 | BEQ Addr10 ; If $10 go to Addr10
1516 | CMP #$20
1517 | BEQ Addr20 ; If $20 go to Addr20
1518 | INY ; Otherwise set BLOCKPTR to $1001 (BASIC text area)
1519 | LDA #$10
1520 | - STY BLOCKPTR
1521 | STA BLOCKPTR + 1
1522 | RTS
1523 | Addr00
1524 | ; Point BLOCKPTR to $0C00 (3072)
1525 | LDA #$0C
1526 | BNE -
1527 | Addr10
1528 | ; Point BLOCKPTR to $2000 (8192)
1529 | LDA #$20
1530 | BNE -
1531 | Addr20
1532 | ; Point BLOCKPTR to $0800 (2048)
1533 | LDA #$08
1534 | BNE -
1535 |
1536 | ;///////////////////////////////////////////////////////////////////////////////////
1537 | ; 130: Transfers a byte block to memory, requires 2 parameter bytes
1538 | ; Byte count (low, high)
1539 |
1540 | Cmd82
1541 | JSR NoChar ; Mute beep
1542 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1543 | TAY
1544 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1545 | TAX
1546 |
1547 | ; Check if transferring to the BASIC area
1548 | LDA BLOCKPTR
1549 | CMP #$01
1550 | BNE +
1551 | LDA BLOCKPTR + 1
1552 | CMP #$10
1553 | BNE +
1554 | CLC
1555 | TYA
1556 | ADC BLOCKPTR
1557 | STA $2D
1558 | TXA
1559 | ADC BLOCKPTR+1
1560 | STA $2E ; Update Start of BASIC variables pointer
1561 |
1562 | _Cmd82 ;Alternative entry point
1563 | + DEY
1564 | CPY #$FF
1565 | BNE +
1566 | DEX
1567 | + STY BYTECNT
1568 | STX BYTECNT + 1
1569 | LDA $FF19
1570 | STA BORDERCLR
1571 | LDA BLOCKPTR ; Copy BLOCKPTR pointer to C82Loop
1572 | STA C82Addr + 1
1573 | LDA BLOCKPTR + 1
1574 | STA C82Addr + 2
1575 | LDA #%10100000 ; Disable raster interrupt signals from TED
1576 | STA $FF0A
1577 | SEI ; Disable IRQs
1578 | ;LDA $DC0D ; Clear interrupt flags
1579 |
1580 | - LDA $FF1D
1581 | CMP #204
1582 | BNE - ; Waits for raster line 204
1583 |
1584 | LDA $FF06 ; Disables TED screen
1585 | C82enable
1586 | AND #%01101111
1587 | STA $FF06
1588 |
1589 | C82Loop
1590 | ; Timeout counter
1591 | LDA #$0A ; Count ~5.66 seconds
1592 | STA TEMPCNT2 ; H
1593 | LDA #$00 ; 0
1594 | STA TEMPCNT1 ; L
1595 |
1596 | - JSR ReadByte ; Receive a character from RS232
1597 | BCS ++ ; Byte received -> +
1598 | LDA TEMPCNT1 ; Decrement counter
1599 | BNE +
1600 | LDA TEMPCNT2
1601 | BEQ C82End ; Zero, exit
1602 | DEC TEMPCNT2
1603 | + DEC TEMPCNT1
1604 | BCC - ; Keep receiving
1605 |
1606 | ; BCC - ; Nothing received, retry
1607 | ++ LDA RXBYTE ; Store it in RAM
1608 | C82Addr
1609 | STA C82Addr ; (self-modifying code) (WAS BUFFER)
1610 | C82FX
1611 | INC $FF19 ;<<<<
1612 | INC C82Addr + 1 ; 6 Increment the memory pointer
1613 | BNE C82Next ; 2
1614 | INC C82Addr + 2 ; 6
1615 | C82Next ; 1 if coming from the BNE
1616 | LDY BYTECNT
1617 | DEY
1618 | CPY #$FF
1619 | BNE C82Cont
1620 | LDX BYTECNT+1
1621 | DEX
1622 | CPX #$FF
1623 | BEQ C82End ; 2
1624 | STX BYTECNT+1
1625 | C82Cont ; 1 if coming from the BNE
1626 | STY BYTECNT
1627 | LDA C82FX
1628 | EOR #$20 ; Toggle INC <-> DEC
1629 | STA C82FX
1630 | JMP C82Loop
1631 | C82End
1632 | LDA BORDERCLR
1633 | STA $FF19
1634 | ;LDA $DC0D ; Clear the interrupt flags ***
1635 |
1636 | LDA $FF06 ; Enable screen
1637 | ORA #%00010000
1638 | STA $FF06
1639 | LDA #$02
1640 | STA $FF0A ; Enable raster interrupts
1641 | CLI ; Enable IRQs
1642 | RTS
1643 |
1644 | ;///////////////////////////////////////////////////////////////////////////////////
1645 | ; 131: PCM audio streaming until receiving a NUL ($00) character
1646 |
1647 | Cmd83
1648 | SEI
1649 |
1650 | LDA $FF19
1651 | STA BORDERCLR
1652 |
1653 | LDX #$88
1654 |
1655 | - LDA $FF1D
1656 | CMP #251
1657 | BNE - ; Wait for raster line 251
1658 |
1659 | LDA $FF06 ; Disable TED screen
1660 | AND #%01101111
1661 | STA $FF06
1662 |
1663 | JSR TurboRX ; Do the thing
1664 | CLI
1665 |
1666 |
1667 | LDA $FF06 ; Enable TED screen
1668 | ORA #%00010000
1669 | STA $FF06
1670 | LDA #$82
1671 | STA $FF09 ; Ack raster interrupts
1672 |
1673 |
1674 | LDA BORDERCLR
1675 | STA $FF19
1676 | RTS
1677 |
1678 | ;////////////////////////////////////////////////////////////////////////////////////
1679 | ; 134: Start a file transfer
1680 | Cmd86
1681 | SEI
1682 | +DisROMs
1683 | JSR _Cmd86
1684 | +EnROMs
1685 | CLI
1686 | JMP CmdFE ; Exit command mode
1687 |
1688 |
1689 | ;///////////////////////////////////////////////////////////////////////////////////
1690 | ; 144: Returns to the default text mode, requires 3 parameter bytes
1691 | ; Page (not used), border color, background color
1692 |
1693 | Cmd90
1694 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1695 | ;Página - Descartado
1696 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1697 | STA $FF19
1698 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1699 | STA $FF15
1700 | _txtmode
1701 | LDA #%00011011 ; Switch to text mode
1702 | STA $FF06
1703 | LDA #$00
1704 | STA $83
1705 | LDA $FF07 ; Disable multicolor mode
1706 | AND #$48
1707 | STA $FF07
1708 | LDA #$08 ; Attrs at $0800 Screen at $0C00
1709 | STA $FF14
1710 | LDA $FF13 ; Charset at $D400
1711 | AND #$03
1712 | ORA #$D4
1713 | STA $FF13
1714 | LDA $FF12 ; Read Charset from ROM
1715 | ORA #$04
1716 | STA $FF12
1717 |
1718 | RTS
1719 |
1720 | ;///////////////////////////////////////////////////////////////////////////////////
1721 | ; 145: Switch to bitmap hires mode, requires 2 parameter bytes
1722 | ; Page (not used), border color
1723 |
1724 | Cmd91
1725 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1726 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1727 | STA $FF19
1728 | JSR _luchcopy
1729 | ; LDA #$08 ; Attributes at $0800
1730 | LDA #$18 ; Attributes at $1800
1731 | STA $FF14
1732 | LDA $FF12
1733 | AND #$03 ;$07
1734 | ORA #$08
1735 | STA $FF12 ; Bitmap at $2000
1736 | LDA $FF07 ; Disable multicolor mode
1737 | AND #$48
1738 | STA $FF07
1739 | ; Switch to bitmap mode
1740 | LDA #%00111011
1741 | STA $FF06
1742 | STA $83
1743 | RTS
1744 |
1745 | ; Copy color and luma tables from $800 to $1800 before switching to graphic modes
1746 | _luchcopy
1747 | LDX #$00
1748 | - LDA $0800,X ; Lumas
1749 | STA $1800,X
1750 | LDA $0900,X
1751 | STA $1900,X
1752 | LDA $0A00,X
1753 | STA $1A00,X
1754 | LDA $0B00,X
1755 | STA $1B00,X
1756 | LDA $0C00,X ; colors
1757 | STA $1C00,X
1758 | LDA $0D00,X
1759 | STA $1D00,X
1760 | LDA $0E00,X
1761 | STA $1E00,X
1762 | LDA $0F00,X
1763 | STA $1F00,X
1764 | INX
1765 | BNE -
1766 | RTS
1767 |
1768 | ;///////////////////////////////////////////////////////////////////////////////////
1769 | ; 146: Switch to bitmap multicolor mode, requires 4 parameter bytes
1770 | ; Page (not used), border color, background color, multicolor 3 color
1771 |
1772 | Cmd92
1773 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1774 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1775 | STA $FF19
1776 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1777 | STA $FF15
1778 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
1779 | STA $FF16
1780 | JSR _luchcopy
1781 | ; LDA #$08 ; Attributes at $0800
1782 | LDA #$18 ; Attributes at $1800
1783 | STA $FF14
1784 | LDA $FF12
1785 | AND #$03
1786 | ORA #$08
1787 | STA $FF12 ; Bitmap at $2000
1788 | LDA #$10 ; Set multicolor multicolor mode
1789 | ORA $FF07
1790 | STA $FF07
1791 | ; Switch to bitmap mode
1792 | LDA #%00111011
1793 | STA $FF06
1794 | STA $83
1795 | RTS
1796 |
1797 | ;///////////////////////////////////////////////////////////////////////////////////
1798 | ; 152: Clears the graphic screen
1799 | Cmd98
1800 | JMP $C567 ;SCNCLR
1801 | ; RTS
1802 |
1803 | ;///////////////////////////////////////////////////////////////////////////////////
1804 | ; 153: Set Pen color
1805 | ; Parameters: Pen, Color
1806 | Cmd99:
1807 | JSR GetFromPrBuffer ; Pen
1808 | TAY ; Save it
1809 | JSR GetFromPrBuffer ; Color
1810 | TAX
1811 | TYA
1812 | BNE +
1813 | STX $FF15 ; Pen 0
1814 | RTS
1815 | + CMP #$01
1816 | BNE +
1817 | STX $86 ; Pen 1
1818 | RTS
1819 | + CMP #$02
1820 | BNE +
1821 | STX $85 ; Pen 2
1822 | RTS
1823 | + CMP #$03
1824 | BNE +
1825 | STX $FF16 ; Pen 3
1826 | + RTS
1827 |
1828 | ;///////////////////////////////////////////////////////////////////////////////////
1829 | ; 154: Plot point
1830 | ; Parameters: Pen, X(16bit), Y(16bit)
1831 | Cmd9A:
1832 | JSR GetFromPrBuffer ; Pen
1833 | STA $84
1834 | LDY #$00
1835 | - JSR GetFromPrBuffer ; Get coordinates
1836 | STA $02AD,Y
1837 | INY
1838 | CPY #$04
1839 | BNE -
1840 | LDA $FF06
1841 | AND #$20
1842 | BEQ + ; Bitmap mode?
1843 | SEI
1844 | JSR $C1A5 ; Plot point
1845 | CLI
1846 | + RTS
1847 |
1848 | ;///////////////////////////////////////////////////////////////////////////////////
1849 | ; 155: Line
1850 | ; Parameters: Pen, X1(16bit), Y1(16bit), X2(16bit), Y2(16bit)
1851 | Cmd9B:
1852 | JSR GetFromPrBuffer ; Pen
1853 | STA $84
1854 | LDY #$00
1855 | - JSR GetFromPrBuffer ; Get coordinates
1856 | STA $02AD,Y
1857 | INY
1858 | CPY #$08
1859 | BNE -
1860 | LDA $FF06
1861 | AND #$20
1862 | BEQ + ; Bitmap mode?
1863 | ; SEI
1864 | JSR $C0DA ; Draw line
1865 | ; CLI
1866 | + RTS
1867 |
1868 | ;///////////////////////////////////////////////////////////////////////////////////
1869 | ; 156: Box
1870 | ; Parameters: Pen, X1(16bit), Y1(16bit), X2(16bit), Y2(16bit), Fill
1871 | Cmd9C:
1872 | JSR GetFromPrBuffer ; Pen
1873 | STA $84
1874 | LDY #$00
1875 | STY $02D0 ; Rotation lo
1876 | STY $02D1 ; Rotation hi
1877 | - JSR GetFromPrBuffer
1878 | STA $02CC,Y ; X1, Y1
1879 | INY
1880 | CPY #$04
1881 | BNE -
1882 | ; LDY #$00
1883 | - JSR GetFromPrBuffer
1884 | STA $02D4,Y ; X2, Y2
1885 | INY
1886 | CPY #$08
1887 | BNE -
1888 | JSR GetFromPrBuffer ; Fill flag
1889 | BEQ +
1890 | LDA #$01
1891 | + TAX
1892 | JSR $BB02
1893 | RTS
1894 |
1895 | ;///////////////////////////////////////////////////////////////////////////////////
1896 | ; 157: Circle
1897 | ; Parameters: Pen, center X(16bit), center Y(16bit), radius X(16bit), radius Y(16bit)
1898 | Cmd9D:
1899 | JSR GetFromPrBuffer ; Pen
1900 | STA $84
1901 | LDY #$00
1902 | STY $02D8 ; Start angle lo
1903 | STY $02D9 ; Start angle hi
1904 | - JSR GetFromPrBuffer
1905 | STA $02CC,Y ; center X, Y. radius X, Y
1906 | INY
1907 | CPY #$08
1908 | BNE -
1909 | LDA #$68
1910 | STA $02DA ; End angle lo
1911 | LDX #$01
1912 | STX $02DB ; End angle hi
1913 | INX
1914 | STX $E9 ; Segment angle
1915 |
1916 | ; This section adapted from Plus4 ROM
1917 | LDX #$2D
1918 | LDY #$2B
1919 | JSR $C305 ; Subtract to coordinates
1920 | BCC +
1921 | + LDX #$03
1922 | - LDA $02D0,x
1923 | STA $02D4,x
1924 | DEX
1925 | BPL -
1926 | LDA #$90
1927 | JSR $BCD5 ; ???
1928 | LDX #$07
1929 | - LDA $02D0,x
1930 | STA $02DC,x
1931 | DEX
1932 | BPL -
1933 | JSR $BCEE ; ???
1934 | JSR $C37B ; Set graphic cursor
1935 | CLC
1936 | JSR $C0B2 ; Circle?
1937 | RTS
1938 |
1939 | ;///////////////////////////////////////////////////////////////////////////////////
1940 | ; 158: Fill
1941 | ; Parameters: Pen, X(16bit), Y(16bit)
1942 | Cmd9E:
1943 | JSR GetFromPrBuffer ; Pen
1944 | STA $84
1945 | LDY #$00
1946 | - JSR GetFromPrBuffer ; Get coordinates
1947 | STA $02AD,Y
1948 | STA $02B1,Y
1949 | INY
1950 | CPY #$04
1951 | BNE -
1952 | LDA #$00
1953 | JSR $B8E7 ; PAINT
1954 | RTS
1955 |
1956 | ;///////////////////////////////////////////////////////////////////////////////////
1957 | ; 160: Selects the screen as the output for the received characters
1958 | CmdA0
1959 | LDA FLAGS1
1960 | AND #%10111111 ; Switch to screen mode, Setting FLAGS1 bit 6 to 0
1961 | STA FLAGS1 ; and exits command mode
1962 | JMP CmdFE
1963 |
1964 | ;///////////////////////////////////////////////////////////////////////////////////
1965 | ; 161: Selects the voice synthesizer as output for the received characters
1966 | CmdA1
1967 | LDA FLAGS1
1968 | ORA #%01000000 ; Switch to voice mode, Setting FLAGS1 bit 6 to 1
1969 | STA FLAGS1 ; and exits command mode
1970 | JMP CmdFE
1971 |
1972 | ;///////////////////////////////////////////////////////////////////////////////////
1973 | ; 162: Requests the terminal's ID and version
1974 |
1975 | CmdA2
1976 | SEI
1977 | LDY #00
1978 | - LDA IDString,Y
1979 | JSR SendID
1980 | INY
1981 | CPY #24
1982 | BNE -
1983 | CLI
1984 | RTS ;JMP ExitIrq
1985 |
1986 | ;///////////////////////////////////////////////////////////////////////////////////
1987 | ; 163: Queries terminal if a command is implemented, requires 1 parameter: Command #
1988 | ; Returns number of parameters if command exist, or bit-7 = 1 if not.
1989 |
1990 | CmdA3
1991 | JSR GetFromPrBuffer ; Reads a byte from the print buffer / Command #
1992 | SEI
1993 | BPL + ; If it's not a command, replace with unimplemented command ($8F)
1994 | CMP #MAXCMD+1
1995 | BCC ++ ; Is it less than or equal to the highest implemented command?
1996 | + LDA #$8F ; Invalid command, replace with unimplemented command ($8F)
1997 | ++ AND #%01111111 ; -128
1998 | TAY
1999 | LDA CmdParTable,Y ; Get parameter count/Command implemented
2000 | JSR SendID
2001 | CLI
2002 | RTS
2003 |
2004 | ;///////////////////////////////////////////////////////////////////////////////////
2005 | ; 176: Sets cursor position, requires two parameter bytes: Column, row
2006 | ; Relative to the current text window
2007 |
2008 | CmdB0
2009 | JSR StopCRSR
2010 | JSR GetFromPrBuffer ; Reads a byte from the print buffer / Column
2011 | CMP #39 ; Greater than 39?
2012 | BCC + ; No, save it, get row
2013 | LDA #39 ; Yes, force 39
2014 | + PHA ; temp save
2015 | JSR GetFromPrBuffer ; Reads a byte from the print buffer / Row
2016 | CLC
2017 | ADC WTOP
2018 | TAX
2019 | CPX WBOTTOM ; Greater than WBOTTOM?
2020 | BCC + ; No, continue
2021 | LDX WBOTTOM ; Yes, force WBOTTOM
2022 | + PLA
2023 | TAY ;LDY TEMP1
2024 | CLC
2025 | JSR $D839 ; Set cursor position
2026 | JSR StartCRSR
2027 | LDA WTOP ; Restore OS text window limits
2028 | STA $07E6
2029 | LDX WBOTTOM
2030 | DEX
2031 | STX $07E5
2032 | JSR $DE80 ; Rebuild link table
2033 | JMP CmdFE ; Exit command mode
2034 |
2035 | ;///////////////////////////////////////////////////////////////////////////////////
2036 | ; 177: Fill a row with the selected character (screen code) cursor is not moved
2037 | ; Requires 2 parameter bytes: Row, screen_code
2038 |
2039 | CmdB1
2040 | JSR StopCRSR
2041 | JSR GetFromPrBuffer ; Reads a byte from the print buffer / Row
2042 | CMP #$24 ; Greater than 24?
2043 | BCC + ; No, continue
2044 | LDA #$24 ; Yes, force 24
2045 | + TAX
2046 | LDA $D802,X ; Get the row address low byte from the ROM table
2047 | STA .cb11+1 ; Screen
2048 | STA .cb12+1 ; Attributes
2049 | LDA $D81B,X ; Row address high byte
2050 | STA .cb11+2 ; Screen
2051 | EOR #$04
2052 | STA .cb12+2 ; Attributes
2053 |
2054 | JSR GetFromPrBuffer ; Reads a byte from the print buffer / screen_code
2055 |
2056 | TAY ; Save screen_code
2057 |
2058 | ; Fill row
2059 | LDX #39
2060 | .cb11
2061 | STA $0C00,X
2062 | LDA $053B ; Current Color
2063 | ;ORA $053C ; Flash
2064 | .cb12
2065 | STA $0800,X
2066 | TYA
2067 | DEX
2068 | BPL .cb11
2069 |
2070 | JSR StartCRSR
2071 |
2072 | RTS
2073 |
2074 | ;///////////////////////////////////////////////////////////////////////////////////
2075 | ; 178: Set the cursor enable status, requires a single parameter byte
2076 |
2077 | CmdB2
2078 | LDA FLAGS1
2079 | ORA #%00001000
2080 | TAY
2081 | JSR GetFromPrBuffer ; Reads a byte from the print buffer
2082 | BNE CrSr00 ; IF not $00 continue on CrSr00
2083 | JSR StopCRSR
2084 | LDA FLAGS1
2085 | AND #%11110111
2086 | TAY
2087 | CrSr00
2088 | STY FLAGS1
2089 | RTS ;JMP ExitIrq
2090 |
2091 | ;///////////////////////////////////////////////////////////////////////////////////
2092 | ; 179: Split screen, requires 2 parameters, mode/row and background colors
2093 |
2094 | UPBGC:
2095 | !byte $00 ; Background color for the upper part of the split
2096 | BTBGC:
2097 | !byte $00 ; Background color for the bottom part of the split
2098 | VMODE:
2099 | !byte $00 ; Video mode for the upper part of the split
2100 |
2101 | CmdB3
2102 | JSR GetFromPrBuffer
2103 | BEQ b3cancel
2104 | TAY
2105 | BMI +
2106 | LDX #$00
2107 | BEQ ++
2108 | + LDX #$10
2109 | ++ STX VMODE
2110 | AND #$1F ; Remove mode bit
2111 | STA WTOP ; Set text window
2112 | STA $88 ; Limit for drawing routines
2113 | ASL
2114 | ASL
2115 | ASL ; .A*8
2116 | CLC
2117 | ADC #$01 ; +01 = Scanline-3
2118 | STA SPLITRST
2119 | JSR GetFromPrBuffer
2120 | STA UPBGC ; This is wrong, we need 1 byte per bg color
2121 | TAX
2122 | TYA
2123 | AND #$20 ; Check if there's additional parameters
2124 | BEQ +
2125 | LDA #$42 ; Get 2 more parameters
2126 | STA CMDFlags
2127 | JSR GetFromPrBuffer
2128 | STA BTBGC
2129 | JSR GetFromPrBuffer
2130 | AND #$7F
2131 | STA $FF16
2132 | BPL ++
2133 | + TXA
2134 | LSR
2135 | LSR
2136 | LSR
2137 | LSR
2138 | STA BTBGC
2139 | ++ LDA #%00010000
2140 | ORA FLAGS1
2141 | STA FLAGS1
2142 | LDY #$00
2143 | LDX WTOP
2144 | CLC
2145 | JSR $D839 ; Set cursor position
2146 | LDA WTOP
2147 | STA $07E6
2148 | LDA $FF12
2149 | AND #$03
2150 | ORA #$08
2151 | STA $FF12 ; Bitmap at $2000
2152 | JSR _luchcopy ; Copy luma/colors to $1800
2153 | ; LDA #$03
2154 | ; STA ReadBLoop-1 ; Limit reception to 3 characters per frame
2155 | RTS
2156 | b3cancel ; Cancel split screen
2157 | JSR GetFromPrBuffer
2158 | b3cancel2
2159 | LDA #%11101111
2160 | AND FLAGS1
2161 | STA FLAGS1
2162 | LDA #$00
2163 | STA WTOP ; Set text window
2164 | STA $07E6
2165 | LDA #$19
2166 | STA $88 ; Max lines for drawing routines
2167 | ; LDA #$03
2168 | ; STA ReadBLoop-1
2169 | RTS
2170 |
2171 | ;---------------------------------
2172 | ; Split screen interrupt routine
2173 |
2174 | IrqB3:
2175 | LDY BTBGC
2176 | LDA $FF12
2177 | ORA #$04
2178 |
2179 | LDX #$0D ;2
2180 | - DEX ;2
2181 | BNE - ;3
2182 | TAX
2183 |
2184 | ; NOP
2185 | NOP
2186 | LDA #$08 ; Attributes at $0800
2187 | STA $FF14
2188 | LDA #%00011011 ;2 Text mode
2189 | STA $FF06 ;4
2190 | LDA $FF07 ;4
2191 | AND #%11101111 ;2
2192 | STA $FF07 ;4 Disable multicolor
2193 | STX $FF12
2194 | STY $FF15 ;4 Bottom section background color
2195 |
2196 |
2197 | ; LDA $FF12 ; Charset from ROM
2198 | ; ORA #$04
2199 |
2200 | LDA #204 ;2
2201 | STA $FF0B ;4
2202 |
2203 | LDA #%10000010 ; Limpia todas las banderas de interrupcion, incluyendo la de interrupcion de barrido
2204 | STA $FF09
2205 | LDA #%10100010 ; Enable raster interrupt signals from TED, and clear MSB in TED's raster register
2206 | STA $FF0A
2207 |
2208 | LDA #Irq
2211 | STA $0315
2212 |
2213 | JMP $FCBE
2214 |
2215 | ;///////////////////////////////////////////////////////////////////////////////////
2216 | ; 180: Get cursor position, returns 2 bytes, column and row. Exit CMD mode
2217 |
2218 | CmdB4
2219 | SEI
2220 | SEC
2221 | JSR $D839 ; Get cursor position
2222 | TXA
2223 | SEC
2224 | SBC WTOP
2225 | PHA
2226 | TYA ; Column
2227 | SEC
2228 | SBC WTOP
2229 | JSR SendID
2230 | PLA ; Row
2231 | JSR SendID
2232 | CLI
2233 | LDA WTOP ; Restore text window limits
2234 | STA $07E6
2235 | LDX WBOTTOM
2236 | DEX
2237 | STX $07E5
2238 | JMP CmdFE
2239 |
2240 | ;///////////////////////////////////////////////////////////////////////////////////
2241 | ; 181: Set text window, requires 2 parameters, top and bottom rows
2242 |
2243 | CmdB5
2244 | JSR GetFromPrBuffer
2245 | BPL +
2246 | LDA #$00
2247 | + CMP #24
2248 | BCC +
2249 | LDA #24
2250 | + STA WTOP
2251 | JSR GetFromPrBuffer
2252 | TAY
2253 | BPL +
2254 | LDY #$00
2255 | + CPY #24
2256 | BCC +
2257 | LDY #24
2258 | + INY
2259 | STY WBOTTOM
2260 | LDY #$00
2261 | LDX WTOP
2262 | CLC
2263 | JSR $D839 ; Set cursor position
2264 | LDA WTOP ; Set OS text window limits
2265 | STA $07E6
2266 | LDX WBOTTOM
2267 | DEX
2268 | STX $07E5
2269 | RTS
2270 |
2271 | ;///////////////////////////////////////////////////////////////////////////////////
2272 | ; 182: Scroll text window, requires 1 parameter: rows to scroll, signed byte
2273 | CmdB6
2274 | JSR GetFromPrBuffer
2275 | BEQ ++
2276 | BPL +
2277 | ;Scroll up
2278 | EOR #$FF
2279 | STA $D8
2280 | INC $D8
2281 | - JSR $DF04
2282 | DEC $D8
2283 | BNE -
2284 | BEQ ++
2285 | + STA $D8
2286 | - JSR $DEF6
2287 | DEC $D8
2288 | BNE -
2289 |
2290 | ++ RTS
2291 |
2292 | ;///////////////////////////////////////////////////////////////////////////////////
2293 | ; 183: Set Ink color, requires 1 parameter: Color index
2294 | CmdB7
2295 | JSR GetFromPrBuffer
2296 | AND #$7F ; Remove Flash bit
2297 | STA $053B
2298 | JMP CmdFE
2299 |
2300 | ;///////////////////////////////////////////////////////////////////////////////////
2301 | ; 254: Exit command mode, setting FLAGS1 bit 7 to 0
2302 | CmdFE
2303 | LDA FLAGS1
2304 | AND #%01111111
2305 | STA FLAGS1
2306 | RTS
2307 |
2308 | ;///////////////////////////////////////////////////////////////////////////////////
2309 |
2310 | SendID
2311 | STA ACIADATA ; Store the character in the transmit register
2312 | LDA #%00001011 ; no parity, no echo, no tx irq (rts=0, receive enable), no rx irq, rx enabled (dtr=0)
2313 | STA ACIACOMMAND
2314 | - LDA ACIASTATUS ; Wait for the character to be transmitted
2315 | AND #%00010000
2316 | BEQ -
2317 | LDA #%00000011 ; no parity, no echo, no tx irq (rts=1, receive disable), no rx irq, rx enabled (dtr=0)
2318 | STA ACIACOMMAND
2319 | RTS
2320 |
2321 | ; Commands routine pointer table, unimplemented commands point to CMDOFF
2322 | CmdTable:
2323 | !word Cmd80,Cmd81,Cmd82,Cmd83,CmdFE,CmdFE,Cmd86,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE
2324 | !word Cmd90,Cmd91,Cmd92,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,Cmd98,Cmd99,Cmd9A,Cmd9B,Cmd9C,Cmd9D,Cmd9E,CmdFE
2325 | !word CmdA0,CmdA1,CmdA2,CmdA3,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE,CmdFE
2326 | !word CmdB0,CmdB1,CmdB2,CmdB3,CmdB4,CmdB5,CmdB6,CmdB7
2327 |
2328 | ; Command parameter number table.
2329 | ; bit-7 = 1 : Parameter not implemented
2330 | CmdParTable:
2331 | !byte $02 ,$01 ,$02 ,$00 ,$80 ,$80 ,$00 ,$80 ,$80 ,$80 ,$80 ,$80 ,$80 ,$80 ,$80 ,$80
2332 | !byte $03 ,$02 ,$04 ,$80 ,$80 ,$80 ,$80 ,$80 ,$00 ,$02 ,$05 ,$09 ,$0A ,$09 ,$05 ,$80
2333 | !byte $00 ,$00 ,$00 ,$01 ,$80 ,$80 ,$80 ,$80 ,$80 ,$80 ,$80 ,$80 ,$80 ,$80 ,$80 ,$80
2334 | !byte $02 ,$02 ,$01 ,$02 ,$00 ,$02 ,$01 ,$01
2335 |
2336 | InitScr
2337 | !byte $90, $93, $08, $0E, $00
2338 | RetroIntro
2339 | !text " rETROCOMPUTACION PRESENTS"
2340 | !byte 13, 13, 29, 29, 29, 29, 29, 29, 29, 29
2341 | !text " rETROTERM pLUS/4"
2342 | !byte 19, 0
2343 | Version
2344 | !byte $05, $93, $99, $08, $0E
2345 | ; !text "retroterm VERSION 0.5 turbo 57600,8n1"
2346 | ; !text "retroterm turbo232 VER 0.11 57600,8n1"
2347 | !text "retroterm plus/4 VER "
2348 | +_Version_
2349 | !text " 19200,8n1"
2350 | !byte $05, $0D , $00
2351 | Msg06
2352 | !text "(c)2025 RETROCOMPUTACION.COM"
2353 | !byte $0D
2354 | !byte $9A
2355 | !text "turbo56k V0.8"
2356 | !byte $0D, $05, $00
2357 | ExitMsg
2358 | !byte $93, $8E
2359 | !text "EXITING TO BASIC..."
2360 | !byte $0D
2361 | !text "SYS28672 TO RESTART RETROTERM"
2362 | !byte $0D, $0D, $00
2363 |
2364 | IDString:
2365 | !text "RTRETROTERM-P4 "
2366 | +_Version_
2367 | !text " " ; ID String 22 characters long
2368 | !byte $00,$08 ;Turbo56K version, subversion
2369 |
2370 | Palette
2371 | !byte $00,$71,$32,$63,$34,$45,$26,$67
2372 | !byte $48,$29,$52,$31,$41,$65,$46,$51
2373 | ;$FF15 background, $FF19 border
2374 |
2375 | FTable
2376 | !byte $85,$89,$86,$8A,$87,$8B,$88,$8C
2377 |
2378 | ;///////////////////////////////////////////////////////////////////////////////////
2379 | ; Buffer de impresion
2380 | ;///////////////////////////////////////////////////////////////////////////////////
2381 |
2382 | ENDOFCODE
2383 | !if ENDOFCODE > $7EFF {
2384 | !error "ERROR - Part 1 data beyond $8EFF"
2385 | }
2386 | }
2387 | _ENDOFCODE_
2388 |
2389 | ;///////////////////////////////////////////////////////////////////////////////////
2390 | ; Mobile code section $D000->
2391 | ;///////////////////////////////////////////////////////////////////////////////////
2392 | _SHADOWCODE_
2393 | !pseudopc $8000{
2394 | SHADOWCODE:
2395 |
2396 | ; ------------------------------------------
2397 | ; Save to disk routines
2398 | CRC = $0F40 ;$FD ; CRC result $FD/$FE
2399 | CRCHI = $1900 ; CRC tables
2400 | CRCLO = $1A00
2401 | FNAME = $0332 ; Null terminated file name
2402 | FNL = $03F2 ; Filename length
2403 |
2404 | ; Copy Memory
2405 | ; Source at SOURCEPTR($D8/$D9)
2406 | ; Destination at DESTPTR($DA/$DB)
2407 | ; Size at CSIZE($58/$59)
2408 | CSIZE = $E8
2409 | SOURCEPTR = $D8
2410 | DESTPTR = $DA
2411 |
2412 | ; List of detected drives. Filled at first startup
2413 | DRIVES:
2414 | !fill $08,$FF
2415 |
2416 | _MemCpy
2417 | -- LDY #$00
2418 | - LDA (SOURCEPTR),Y
2419 | STA (DESTPTR),Y
2420 | LDA CSIZE
2421 | BNE +
2422 | LDA CSIZE+1
2423 | BEQ ++
2424 | DEC CSIZE+1
2425 | + DEC CSIZE
2426 | INY
2427 | BNE -
2428 |
2429 | INC SOURCEPTR+1
2430 | INC DESTPTR+1
2431 | BNE --
2432 | ++ RTS
2433 |
2434 | _Cmd86
2435 | JSR MAKECRCTABLE
2436 |
2437 | DESTADDR = $1B00
2438 | BBUF = $0E00
2439 |
2440 | ; Copy routine to lower RAM ($1B00)
2441 | LDX #$01
2442 | - LDA _86data,X
2443 | STA SOURCEPTR,X
2444 | LDA _86data+2,X
2445 | STA DESTPTR,X
2446 | LDA _86data+4,X
2447 | STA CSIZE,X
2448 | DEX
2449 | BPL -
2450 |
2451 | JSR _MemCpy ;Do mem copy
2452 | LDX #$08
2453 | - LDA DRIVES,X ;Copy list of detected drives to low RAM
2454 | STA _drives,X
2455 | DEX
2456 | BPL -
2457 | JMP bsave
2458 | _86data
2459 | !word _bsstart,DESTADDR,_bsend-_bsstart
2460 |
2461 | _bsstart:
2462 | !pseudopc $1B00{
2463 | bsave:
2464 | +EnROMs
2465 | LDA #$00
2466 | STA $FF19
2467 | STA $FF15
2468 | JSR b3cancel2 ; Cancel split screen
2469 |
2470 | CLI
2471 | ; Print message
2472 | +StringOut bst1
2473 | SEI
2474 | - LDA $FF1D
2475 | CMP #251
2476 | BNE - ; Waits for raster line 251
2477 | JSR ReadByte ; Get file type
2478 | BCC-
2479 | CLI
2480 | LDA RXBYTE
2481 | STA $02
2482 | BMI + ; Bit 7 = 1 : PRG, else SEQ
2483 | LDA #bst5
2486 | STA .ft+2
2487 | LDY #>bst3
2488 | LDA #bst4
2493 | STA .ft+2
2494 | LDA #bst2
2496 | ++ JSR STROUT
2497 | +StringOut bst1a
2498 | JSR ReadString ; Get filename
2499 | +SetCursor $0A,$01
2500 | ; Print filename
2501 | +StringOut FNAME
2502 | +SetCursor $20,$0B
2503 | ; Print buffer frame
2504 | +StringOut bst6
2505 |
2506 | JSR UBlock ; Print counters
2507 | JSR URetry
2508 |
2509 | LDX #$00
2510 | STX _curdrv ; Find first available drive #
2511 | - CPX #$08
2512 | BEQ ++ ; No available drive found > CANCEL
2513 | LDA _drives,X
2514 | BPL + ; Available drive
2515 | INX
2516 | BNE -
2517 |
2518 | + STX _curdrv ; Store as current drive
2519 | JSR ddrive
2520 |
2521 | - LDA $C6 ; Matrix value for last keypress
2522 | CMP #$19 ; Wait for 'Y'
2523 | BEQ .y1
2524 | CMP #$27 ; Or 'N'
2525 | BNE +
2526 | ++ LDY #$42 ; CANCEL
2527 | BNE .bb
2528 | + CMP #$28 ; '+'
2529 | BNE +
2530 | JSR ndrive ; Get next drive
2531 | JMP -
2532 | + CMP #$2B ; '-'
2533 | BNE -
2534 | JSR pdrive ; Get previous drive
2535 | JMP -
2536 |
2537 | .y1 ;Continue
2538 | +SetCursor $0B,$08
2539 | +StringOut bst9 ; Print abort message
2540 |
2541 | LDY FNL ; add write string to filename
2542 | LDX #$00
2543 | .ft LDA bst4,X
2544 | STA FNAME,Y
2545 | INY
2546 | INX
2547 | CPX #$04
2548 | BNE .ft
2549 | TXA
2550 | CLC
2551 | ADC FNL
2552 | ;STA FNL
2553 | JSR .bo ; Open file. Input .A = filename length. Returns flag on .Y
2554 | ;LDY #$80 ; OK Flag
2555 |
2556 | ; Read block
2557 | LDA #$00 ; Sound off
2558 | STA $FF11
2559 | .bb
2560 | LDA $C6 ; Keymatrix
2561 | CMP #$03 ; F7?
2562 | BNE +
2563 | LDY #$42 ; ABORT!
2564 | + SEI
2565 | TYA
2566 | JSR SendID
2567 |
2568 | LDY #$03
2569 |
2570 | LDA CMDFlags
2571 | ORA #$44
2572 | STA CMDFlags ; Get 4 parameter bytes
2573 |
2574 | ; Get 4 bytes: Block size LSB,MSB | CRC16 LSB,MSB
2575 |
2576 | CLI
2577 | - JSR GetFromPrBuffer
2578 |
2579 | STA $D8,Y ; $FD/$FE : Size
2580 | DEY
2581 | BPL -
2582 |
2583 | SEI
2584 |
2585 | ;If block size = 0, exit transfer
2586 | LDY $DA
2587 | STY .c+1 ; Set CRC check counter limit
2588 | BNE +
2589 | LDA $DB
2590 | BNE +
2591 | JMP .be ; 0 length -> end transfer
2592 | + LDA #BBUF
2595 | STA BLOCKPTR+1 ; Destination
2596 | LDX $DB
2597 | JSR _Cmd82 ; Receive block
2598 | ;check CRC
2599 | LDY #$FF
2600 | STY CRC
2601 | STY CRC+1
2602 | INY
2603 | - LDA BBUF,Y
2604 | JSR UPDCRC
2605 | INY
2606 | .c CPY #$00
2607 | BNE -
2608 | LDA $D8
2609 | CMP CRC
2610 | BNE .er ; CRC doesn't match, error
2611 | LDA $D9
2612 | CMP CRC+1
2613 | BNE .er ; CRC doesn't match, error
2614 | ;Write to disk
2615 | JSR UBlock
2616 | JSR bwrite ; Write block
2617 | ;LDY #$80 ; OK
2618 | JMP .bb ; Get next block
2619 | .er
2620 | JSR URetry
2621 | LDY #$AA ; ERROR
2622 | JMP .bb ; Retry
2623 |
2624 | ;Open file
2625 | .bo
2626 | ;LDA FNL ; Name length
2627 | LDX #FNAME
2629 | JSR $FFBD ; call SETNAM
2630 |
2631 | LDA _curdrv ; current selected drive
2632 | CLC
2633 | ADC #$08
2634 | TAX
2635 | LDA #$02 ; file number 2
2636 | LDY #$02 ; secondary address 2
2637 | JSR $FFBA ; call SETLFS
2638 | JSR $FFC0 ; call OPEN
2639 | BCS .error ; if carry set, file couldnt not be opened
2640 | LDX #$02 ; filenumber 2
2641 | JSR $FFC9 ; call CHKOUT (file 2 now used as output)
2642 | BEQ +
2643 | BNE .error
2644 | + JSR $FFCC ; CLRCHN
2645 | LDY #$81 ; OK
2646 | RTS
2647 |
2648 | .error ; Handle errors - Cancels transfer
2649 | JSR .bc ; Close file
2650 | LDY #$42 ; CANCEL
2651 | RTS
2652 |
2653 | .bc ; Close file
2654 | LDA #$02
2655 | JSR $FFC3 ; CLOSE
2656 | JSR $FFCC ; CLRCHN
2657 | RTS
2658 |
2659 | .be ; Transfer complete
2660 | JSR .bc ; Close file
2661 | SEI
2662 | +DisROMs
2663 | RTS
2664 |
2665 | bwrite ; Write data
2666 | LDY $DA ; Get counter limit
2667 | STY .b1+1
2668 | LDX #$02 ; filenumber 2
2669 | JSR $FFC9 ; call CHKOUT (file 2 now used as output)
2670 |
2671 | LDY #$00
2672 | - JSR $FFB7 ; call READST
2673 | BNE .error ; handle error
2674 | LDA BBUF,Y
2675 | JSR $FFD2 ; call CHROUT (write byte to file)
2676 | INY
2677 | .b1 CPY #$00
2678 | BNE -
2679 | JSR $FFCC ; CLRCHN
2680 | LDY #$81 ; OK
2681 | RTS
2682 |
2683 | ; Quick CRC computation with lookup tables
2684 | UPDCRC:
2685 | EOR CRC+1
2686 | TAX
2687 | LDA CRC
2688 | EOR CRCHI,X
2689 | STA CRC+1
2690 | LDA CRCLO,X
2691 | STA CRC
2692 | RTS
2693 |
2694 | ;Update received block count
2695 | UBlock:
2696 | +SetCursor $00,$06
2697 | +StringOut bst7
2698 | LDA bcount
2699 | LDX bcount+1
2700 | JSR $A45F ; Print number
2701 | INC bcount+1
2702 | BNE +
2703 | INC bcount
2704 | + RTS
2705 |
2706 | bcount
2707 | !byte $00,$00
2708 |
2709 | ;Update retries count
2710 | URetry:
2711 | +SetCursor $00,$07
2712 | +StringOut bst8
2713 | LDA rcount
2714 | LDX rcount+1
2715 | JSR $A45F ; Print number
2716 | INC rcount+1
2717 | BNE +
2718 | INC rcount
2719 | + RTS
2720 |
2721 | rcount
2722 | !byte $00,$00
2723 |
2724 | ;Receive NULL terminated String
2725 | ReadString:
2726 | LDA #$46
2727 | STA CMDFlags
2728 |
2729 |
2730 | LDY #$00
2731 |
2732 | -- INC CMDFlags ; +1 Parameter to read
2733 | JSR GetFromPrBuffer
2734 |
2735 | STA FNAME,Y ; Store name
2736 | BEQ + ; Stop if $00 received
2737 | INY
2738 | CPY #$11
2739 | BNE -- ; Repeat until 16 characters (+ null) are read
2740 | +
2741 | LDA #$00
2742 | STA FNAME,Y ; Make sure the string is NULL terminated
2743 | STY FNL ; String length
2744 | LDA #$40
2745 | STA CMDFlags
2746 | RTS
2747 |
2748 | ; Find next available drive
2749 | ndrive:
2750 | LDX _curdrv
2751 | - INX
2752 | CPX #$08
2753 | BEQ +
2754 | LDA _drives,X
2755 | BMI -
2756 | STX _curdrv
2757 | + JSR ddrive
2758 | RTS
2759 |
2760 | ;Find previous available drive
2761 | pdrive:
2762 | LDX _curdrv
2763 | - DEX
2764 | BMI +
2765 | LDA _drives,X
2766 | BMI -
2767 | STX _curdrv
2768 | + JSR ddrive
2769 | RTS
2770 |
2771 | ;Print drive number
2772 | ddrive:
2773 | +SetCursor 11,2
2774 | +StringOut bst10
2775 | CLC
2776 | LDA _curdrv
2777 | ADC #$08
2778 | TAX
2779 | LDA #$00
2780 | JSR $A45F ; Print number
2781 | ; and wait for key release
2782 | - LDA $C6
2783 | CMP #$40
2784 | BNE -
2785 | RTS
2786 |
2787 | ; File save text
2788 | bst1:
2789 | !byte $93,$8E,$99,$92 ;Clear, upp/gfx, light green, rvsoff
2790 | !text "HOST REQUESTED TO SAVE ",$00
2791 | bst1a:
2792 | !text "FILE",$0D
2793 | !text $05,"FILENAME:",$0D
2794 | !text $9E,"TO DRIVE ",$12,"+",$92," ",$12,"-",$0D
2795 | !text $11,$81,"CONTINUE? (Y/N)",$05,$00
2796 | bst2: ;Program
2797 | !text "PROGRAM ",$00
2798 | bst3: ;Sequential
2799 | !text "SEQUENTIAL ",$00
2800 | bst4: ;Write Program
2801 | !text ",P,W"
2802 | bst5: ;Write Sequential
2803 | !text ",S,W"
2804 | ; Buffer frame
2805 | bst6:
2806 | !byte $9E ; Yellow
2807 | !fill $27,$AF ; 39 _
2808 | !byte $BA
2809 | !fill $07,$0D
2810 | !fill $08,$1D ; cursor
2811 | !byte $6F
2812 | !fill $27,$B7 ; 39
2813 | !byte $05, $00 ; White
2814 | ; Block count
2815 | bst7:
2816 | !text "BLOCKS: "
2817 | !fill $05,$9D
2818 | !byte $00
2819 | ; Retry count
2820 | bst8:
2821 | !text "RETRIES: "
2822 | !fill $05,$9D
2823 | !byte $00
2824 | ; Abort text
2825 | bst9:
2826 | !text "HOLD ",$12," F7 ",$92," TO ABORT",$00
2827 | ; Drive clean spaces
2828 | bst10:
2829 | !text " ",$9D,$9D,$00
2830 |
2831 | ; Detected drives copy
2832 | _curdrv:
2833 | !byte $00
2834 | _drives:
2835 | bsend
2836 | }
2837 | _bsend
2838 | ; Generate CRC tables
2839 | MAKECRCTABLE:
2840 | LDX #0 ; X counts from 0 to 255
2841 | BYTELOOP
2842 | LDA #0 ; A contains the low 8 bits of the CRC-16
2843 | STX CRC ; and CRC contains the high 8 bits
2844 | LDY #8 ; Y counts bits in a byte
2845 | BITLOOP
2846 | ASL
2847 | ROL CRC ; Shift CRC left
2848 | BCC NOADD ; Do nothing if no overflow
2849 | EOR #$21 ; else add CRC-16 polynomial $1021
2850 | PHA ; Save low byte
2851 | LDA CRC ; Do high byte
2852 | EOR #$10
2853 | STA CRC
2854 | PLA ; Restore low byte
2855 | NOADD
2856 | DEY
2857 | BNE BITLOOP ; Do next bit
2858 | STA CRCLO,X ; Save CRC into table, low byte
2859 | LDA CRC ; then high byte
2860 | STA CRCHI,X
2861 | INX
2862 | BNE BYTELOOP ; Do next byte
2863 | RTS
2864 |
2865 | ;//////////////////////////
2866 | ; Setup screen
2867 | ;//////////////////////////
2868 | _SETUP
2869 | JSR b3cancel2 ;Cancel split screen
2870 | LDA #suIRQ
2873 | STA $0315
2874 |
2875 | ; Copy routine to lower RAM ($0B00)
2876 | LDX #$01
2877 | - LDA _sudata,X
2878 | STA SOURCEPTR,X
2879 | LDA _sudata+2,X
2880 | STA DESTPTR,X
2881 | LDA _sudata+4,X
2882 | STA CSIZE,X
2883 | DEX
2884 | BPL -
2885 |
2886 | JSR _MemCpy ;Do mem copy
2887 | JSR dosetup ;Call setup routine
2888 |
2889 | LDA #Irq
2892 | STA $0315
2893 |
2894 | RTS
2895 |
2896 | _sudata
2897 | !word _sustart,$1B00,_suend-_sustart
2898 | ;----
2899 | _sustart:
2900 | !pseudopc $1B00{
2901 | dosetup:
2902 | +EnROMs
2903 | LDA $FF15 ;Save screen colors
2904 | PHA
2905 | LDA $FF19
2906 | PHA
2907 | LDA $053B
2908 | PHA
2909 |
2910 | LDA #$32
2911 | STA $FF15
2912 | STA $FF19
2913 | LDA #%10100010 ; Enable raster interrupt signals from TED, and clear MSB in TED's raster register
2914 | STA $FF0A
2915 | JSR _txtmode ; Switch to text mode
2916 |
2917 | LDA #24
2918 | STA $07E5
2919 |
2920 | CLI
2921 | ;...
2922 | ; Print message
2923 | +StringOut sut1
2924 | +SetCursor $07,$18
2925 | +StringOut sut3
2926 | LDA #$80
2927 | STA $0540 ; Repeat all keys
2928 |
2929 | --
2930 | +SetCursor $14,$02
2931 | +StringOut sut2
2932 | LDX rb1l+1
2933 | LDA rb1h+1
2934 |
2935 | JSR $A45F ;Print number
2936 |
2937 | - JSR $EBDD ; Read keyboard buffer
2938 | BEQ -
2939 | CMP #$2B ; (+)
2940 | BNE +
2941 | INC rb1l+1
2942 | BNE --
2943 | INC rb1h+1
2944 | JMP --
2945 | + CMP #$2D ; (-)
2946 | BNE ++
2947 | LDA rb1l+1
2948 | BNE +
2949 | DEC rb1h+1
2950 | + DEC rb1l+1
2951 | JMP --
2952 | ++
2953 | CMP #$85 ; (F1)
2954 | BEQ +
2955 | BNE --
2956 | +
2957 |
2958 | ;....
2959 | LDA #$00
2960 | STA $0540 ; Default key repeat
2961 | SEI
2962 | LDA #%10100000 ; Disable raster interrupt signals from TED
2963 | STA $FF0A
2964 |
2965 | PLA
2966 | STA $053B
2967 | PLA
2968 | STA $FF19 ;Restore screen colors
2969 | PLA
2970 | STA $FF15
2971 | JSR $D88B ;Clear screen
2972 | +DisROMs
2973 | RTS
2974 |
2975 | ; --- Minimal IRQ
2976 | suIRQ:
2977 |
2978 | PHA ; store register A in stack
2979 | TXA
2980 | PHA ; store register X in stack
2981 | TYA
2982 | PHA ; store register Y in stack
2983 |
2984 | LDA #%10000010 ; Limpia todas las banderas de interrupcion, incluyendo la de interrupcion de barrido
2985 | STA $FF09
2986 | LDA #%10100010 ; Enable raster interrupt signals from TED, and clear MSB in TED's raster register
2987 | STA $FF0A
2988 |
2989 | LDA $FB
2990 | PHA
2991 | LDA #$00
2992 | STA $FB
2993 | PHP
2994 | CLI
2995 | JSR $DB11 ; Scan keyboard
2996 | PLP
2997 | PLA
2998 | STA $FB
2999 |
3000 |
3001 | PLA
3002 | TAY ; restore register Y from stack
3003 | PLA
3004 | TAX ; restore register X from stack
3005 | PLA ; restore register A from stack
3006 | ;JMP $CE0E ; Jump into KERNAL's standard interrupt service routine to handle keyboard scan, cursor display etc.
3007 | JMP $FCBE
3008 |
3009 | ; --- Setup Texts
3010 | sut1:
3011 | ;Clear, Lower/upper, yellow
3012 | !text $93,$0E,$9E," --== rETROTERM sETUP SCREEN ==--"
3013 | !text $0D,$0D,"rts PULSE TIMING: ",$12,"+",$92," ",$12,"-"
3014 | !byte $00
3015 | sut2:
3016 | !text " "
3017 | !fill $05,$9D
3018 | !byte $00
3019 | sut3:
3020 | !byte $12
3021 | !text $12," f1 ",$92," TO RETURN TO rETROTERM",$00
3022 | suend
3023 | }
3024 | _suend
3025 | ENDSHADOW
3026 | }
3027 | _ENDSHADOW_
3028 |
--------------------------------------------------------------------------------
/source/version.asm:
--------------------------------------------------------------------------------
1 | !text "0.21"
2 |
--------------------------------------------------------------------------------
/source/version.txt:
--------------------------------------------------------------------------------
1 | 0.21
--------------------------------------------------------------------------------