1 | #!/opt/bin/perl |
1 | #!/opt/bin/perl |
|
|
2 | |
|
|
3 | # |
|
|
4 | # Copyright(C) 2014 Marc Alexander Lehmann <vt102@schmorp.de> |
|
|
5 | # |
|
|
6 | # vt102 is free software; you can redistribute it and/or modify it under |
|
|
7 | # the terms of the GNU General Public License as published by the Free |
|
|
8 | # Software Foundation; either version 3, or (at your option) any later |
|
|
9 | # version. |
|
|
10 | # |
|
|
11 | # vt102 is distributed in the hope that it will be useful, but WITHOUT |
|
|
12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
|
13 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
|
14 | # for more details. |
|
|
15 | # |
|
|
16 | |
|
|
17 | # If this file contains embedded ROMs, the above copyright notice does |
|
|
18 | # not apply to them. |
2 | |
19 | |
3 | # this hack is not considered release ready in and way, shape, or form |
20 | # this hack is not considered release ready in and way, shape, or form |
4 | # ./vt102 bash |
21 | # ./vt102 bash |
5 | # ./vt102 telnet towel.blinkenlights.nl |
22 | # ./vt102 telnet towel.blinkenlights.nl |
6 | # ./vt102 curl http://artscene.textfiles.com/vt100/trekvid.vt |
23 | # ./vt102 curl http://artscene.textfiles.com/vt100/trekvid.vt |
7 | # ./vt102 curl http://artscene.textfiles.com/vt100/surf.vt # in 3d! |
24 | # ./vt102 curl http://artscene.textfiles.com/vt100/surf.vt # in 3d! |
|
|
25 | |
|
|
26 | # TODO: ctrl |
8 | |
27 | |
9 | use common::sense; |
28 | use common::sense; |
10 | |
29 | |
11 | $| = 1; |
30 | $| = 1; |
12 | |
31 | |
… | |
… | |
124 | |
143 | |
125 | sub out_00 { # pusartdata |
144 | sub out_00 { # pusartdata |
126 | # handle xon/xoff, but also pass it through |
145 | # handle xon/xoff, but also pass it through |
127 | if ($_[0] == 0x13) { |
146 | if ($_[0] == 0x13) { |
128 | $XON = 0; |
147 | $XON = 0; |
|
|
148 | return;#d# |
129 | } elsif ($_[0] == 0x11) { |
149 | } elsif ($_[0] == 0x11) { |
130 | $XON = 1; |
150 | $XON = 1; |
|
|
151 | return;#d# |
131 | } |
152 | } |
132 | |
153 | |
133 | syswrite $PTY, chr $_[0]; |
154 | syswrite $PTY, chr $_[0]; |
134 | |
155 | |
135 | $INTPEND |= 1; # 5.5 txrdy |
156 | $INTPEND |= 1; |
136 | } |
157 | } |
137 | |
158 | |
138 | sub out_01 { |
159 | sub out_01 { |
139 | $PUSARTCMD = shift; |
160 | $PUSARTCMD = shift; |
140 | |
161 | |
141 | $INTPEND |= 1 if $PUSARTCMD & 0x01; # VT102, 5.5 txrdy |
162 | $INTPEND |= 1 if $PUSARTCMD & 0x01; # VT102, 5.5 txrdy |
142 | $INTPEND |= 2 if $PUSARTCMD & 0x04; # VT102, 6.5 rxrdy |
163 | $INTPEND |= 2 if $PUSARTCMD & 0x04 && !@PUSARTRECV; # VT102, 6.5 rxrdy, needed for some reason |
143 | } |
164 | } |
144 | |
165 | |
145 | sub out_02 { } # baudrate generator |
166 | sub out_02 { } # baudrate generator |
146 | |
167 | |
147 | sub out_23 { } # unknown |
168 | sub out_23 { } # unknown |
… | |
… | |
198 | |
219 | |
199 | my $NVRBIT; |
220 | my $NVRBIT; |
200 | my $LBA; |
221 | my $LBA; |
201 | |
222 | |
202 | sub in_00 { # pusart data |
223 | sub in_00 { # pusart data |
203 | # print "READ PUSARTDATA (@PUSARTRECV)\n"; |
224 | # interrupt not generated here, because infinite |
204 | |
225 | # speed does not go well with the vt102. |
205 | # $RST |= 2 if $#PUSARTRECV && $XON; |
|
|
206 | # $INTPEND |= 2 if $#PUSARTRECV && $XON; |
|
|
207 | |
226 | |
208 | shift @PUSARTRECV |
227 | shift @PUSARTRECV |
209 | } |
228 | } |
210 | |
229 | |
211 | sub in_01 { # pusart status |
230 | sub in_01 { # pusart status |
… | |
… | |
220 | |
239 | |
221 | sub in_0f { } # unknown, connected to out 2f |
240 | sub in_0f { } # unknown, connected to out 2f |
222 | |
241 | |
223 | sub in_42 { # flag buffer |
242 | sub in_42 { # flag buffer |
224 | ++$LBA; |
243 | ++$LBA; |
225 | # ++$LBA; |
|
|
226 | # printf "%04x lba %04x, %04x\n", $PC, $LBA, $CLK; |
|
|
227 | |
244 | |
228 | $NVRBIT = nvr ? 0x20 : 0x00 if ($LBA & 0x3) == 0x2; |
245 | $NVRBIT = nvr ? 0x20 : 0x00 if ($LBA & 0x3) == 0x2; |
229 | |
246 | |
230 | # KBD_XMITEMPTY LBA7 NVRDATA ODDFIELD - OPTION !GFX !AVO PUSART_TXRDY |
247 | # KBD_XMITEMPTY LBA7 NVRDATA ODDFIELD - OPTION !GFX !AVO PUSART_TXRDY |
231 | |
248 | |
… | |
… | |
249 | sub in_17 { 0xff } # unknown, printer status clear by reading? |
266 | sub in_17 { 0xff } # unknown, printer status clear by reading? |
250 | sub in_1b { 0xff } # unknown |
267 | sub in_1b { 0xff } # unknown |
251 | |
268 | |
252 | ############################################################################# |
269 | ############################################################################# |
253 | |
270 | |
254 | sub sf { |
271 | sub sf { # set flags (ZSC - AP not implemented) |
255 | $FS = $_[0] & 0x080; |
272 | $FS = $_[0] & 0x080; |
256 | $FZ = ($_[0] & 0x0ff) == 0; |
273 | $FZ = ($_[0] & 0x0ff) == 0; |
257 | $FC = $_[0] & 0x100; |
274 | $FC = $_[0] & 0x100; |
258 | |
275 | |
259 | $_[0] & 0xff |
276 | $_[0] & 0xff |
260 | } |
277 | } |
261 | |
278 | |
262 | sub sf_nc { |
279 | sub sf_nc { # set flags except carry |
263 | $FS = $_[0] & 0x080; |
280 | $FS = $_[0] & 0x080; |
264 | $FZ = ($_[0] & 0x0ff) == 0; |
281 | $FZ = ($_[0] & 0x0ff) == 0; |
265 | |
282 | |
266 | $_[0] & 0xff |
283 | $_[0] & 0xff |
267 | } |
284 | } |
… | |
… | |
466 | "\x{2502}", |
483 | "\x{2502}", |
467 | "\x{2264}", |
484 | "\x{2264}", |
468 | "\x{2265}", |
485 | "\x{2265}", |
469 | "\x{03c0}", |
486 | "\x{03c0}", |
470 | "\x{2260}", |
487 | "\x{2260}", |
471 | "\x{0142}", |
488 | "\x{00a3}", |
472 | "\x{00b7}", |
489 | "\x{00b7}", |
473 | (map chr, 0x020 .. 0x7e), |
490 | (map chr, 0x020 .. 0x7e), |
474 | "?", |
491 | "?", |
475 | ); |
492 | ); |
476 | |
493 | |
… | |
… | |
532 | require IO::Pty; |
549 | require IO::Pty; |
533 | $PTY = IO::Pty->new; |
550 | $PTY = IO::Pty->new; |
534 | |
551 | |
535 | my $slave = $PTY->slave; |
552 | my $slave = $PTY->slave; |
536 | |
553 | |
|
|
554 | $PTY->set_winsize (24, 80); |
|
|
555 | |
537 | unless (fork) { |
556 | unless (fork) { |
538 | $ENV{TERM} = $VT102 ? "vt102" : "vt100"; |
557 | $ENV{TERM} = $VT102 ? "vt102" : "vt100"; |
539 | |
558 | |
540 | close $PTY; |
559 | close $PTY; |
541 | |
560 | |
542 | open STDIN , "<&", $slave; |
561 | open STDIN , "<&", $slave; |
543 | open STDOUT, ">&", $slave; |
562 | open STDOUT, ">&", $slave; |
544 | open STDERR, ">&", $slave; |
563 | open STDERR, ">&", $slave; |
545 | |
564 | |
|
|
565 | system "stty ixoff erase ^H"; |
|
|
566 | |
|
|
567 | $PTY->make_slave_controlling_terminal; |
546 | close $slave; |
568 | $PTY->close_slave; |
547 | |
569 | |
548 | exec @ARGV; |
570 | exec @ARGV; |
549 | } |
571 | } |
550 | |
572 | |
551 | close $slave; |
573 | $PTY->close_slave; |
|
|
574 | |
552 | } else { |
575 | } else { |
553 | open $PTY, "</dev/null" or die;#d |
576 | open $PTY, "</dev/null" or die;#d |
554 | } |
577 | } |
555 | |
578 | |
556 | ############################################################################# |
579 | ############################################################################# |
… | |
… | |
765 | } |
788 | } |
766 | } |
789 | } |
767 | |
790 | |
768 | # kick off various interrupts |
791 | # kick off various interrupts |
769 | |
792 | |
770 | $RST |= 2 if @PUSARTRECV && $XON;# vt100, also works on vt102, probably by accident |
793 | $RST |= 2 if @PUSARTRECV && $XON; # VT100, but works on vt102, too (probably not used on real hardware though) |
771 | #$INTPEND |= 2 if @PUSARTRECV && $XON;# real vt102 probably does it this way |
794 | #$INTPEND |= 2 if @PUSARTRECV && $XON; # VT102, 6.5 rxrdy |
772 | |
795 | |
|
|
796 | # kick off vertical retrace form time to time |
773 | unless ($CLK & 0x3ff) { |
797 | unless ($CLK & 0x3ff) { |
774 | $RST |= 4; # vertical retrace |
798 | $RST |= 4; # vertical retrace |
775 | } |
799 | } |
776 | |
800 | |
777 | # handle video hardware |
801 | # handle video hardware |