… | |
… | |
21 | # ./vt102 bash |
21 | # ./vt102 bash |
22 | # ./vt102 telnet towel.blinkenlights.nl |
22 | # ./vt102 telnet towel.blinkenlights.nl |
23 | # ./vt102 curl http://artscene.textfiles.com/vt100/trekvid.vt |
23 | # ./vt102 curl http://artscene.textfiles.com/vt100/trekvid.vt |
24 | # ./vt102 curl http://artscene.textfiles.com/vt100/surf.vt # in 3d! |
24 | # ./vt102 curl http://artscene.textfiles.com/vt100/surf.vt # in 3d! |
25 | |
25 | |
|
|
26 | # TODO: ctrl |
|
|
27 | |
26 | use common::sense; |
28 | use common::sense; |
27 | |
29 | |
28 | $| = 1; |
30 | $| = 1; |
29 | |
31 | |
30 | my $VT102 = 0; |
32 | my $VT102 = 1; |
31 | my $AVO = $VT102 || 1; |
33 | my $AVO = $VT102 || 1; |
32 | my $KBD = 1; |
34 | my $KBD = 1; |
33 | |
35 | |
34 | ############################################################################# |
36 | ############################################################################# |
35 | |
37 | |
… | |
… | |
141 | |
143 | |
142 | sub out_00 { # pusartdata |
144 | sub out_00 { # pusartdata |
143 | # handle xon/xoff, but also pass it through |
145 | # handle xon/xoff, but also pass it through |
144 | if ($_[0] == 0x13) { |
146 | if ($_[0] == 0x13) { |
145 | $XON = 0; |
147 | $XON = 0; |
|
|
148 | return;#d# |
146 | } elsif ($_[0] == 0x11) { |
149 | } elsif ($_[0] == 0x11) { |
147 | $XON = 1; |
150 | $XON = 1; |
|
|
151 | return;#d# |
148 | } |
152 | } |
149 | |
153 | |
150 | syswrite $PTY, chr $_[0]; |
154 | syswrite $PTY, chr $_[0]; |
151 | |
155 | |
152 | $INTPEND |= 1; # 5.5 txrdy |
156 | $INTPEND |= 1; |
153 | } |
157 | } |
154 | |
158 | |
155 | sub out_01 { |
159 | sub out_01 { |
156 | $PUSARTCMD = shift; |
160 | $PUSARTCMD = shift; |
157 | |
161 | |
158 | $INTPEND |= 1 if $PUSARTCMD & 0x01; # VT102, 5.5 txrdy |
162 | $INTPEND |= 1 if $PUSARTCMD & 0x01; # VT102, 5.5 txrdy |
159 | $INTPEND |= 2 if $PUSARTCMD & 0x04; # VT102, 6.5 rxrdy |
163 | $INTPEND |= 2 if $PUSARTCMD & 0x04 && !@PUSARTRECV; # VT102, 6.5 rxrdy, needed for some reason |
160 | } |
164 | } |
161 | |
165 | |
162 | sub out_02 { } # baudrate generator |
166 | sub out_02 { } # baudrate generator |
163 | |
167 | |
164 | sub out_23 { } # unknown |
168 | sub out_23 { } # unknown |
… | |
… | |
215 | |
219 | |
216 | my $NVRBIT; |
220 | my $NVRBIT; |
217 | my $LBA; |
221 | my $LBA; |
218 | |
222 | |
219 | sub in_00 { # pusart data |
223 | sub in_00 { # pusart data |
220 | # print "READ PUSARTDATA (@PUSARTRECV)\n"; |
224 | # interrupt not generated here, because infinite |
221 | |
225 | # speed does not go well with the vt102. |
222 | # $RST |= 2 if $#PUSARTRECV && $XON; |
|
|
223 | # $INTPEND |= 2 if $#PUSARTRECV && $XON; |
|
|
224 | |
226 | |
225 | shift @PUSARTRECV |
227 | shift @PUSARTRECV |
226 | } |
228 | } |
227 | |
229 | |
228 | sub in_01 { # pusart status |
230 | sub in_01 { # pusart status |
… | |
… | |
237 | |
239 | |
238 | sub in_0f { } # unknown, connected to out 2f |
240 | sub in_0f { } # unknown, connected to out 2f |
239 | |
241 | |
240 | sub in_42 { # flag buffer |
242 | sub in_42 { # flag buffer |
241 | ++$LBA; |
243 | ++$LBA; |
242 | # ++$LBA; |
|
|
243 | # printf "%04x lba %04x, %04x\n", $PC, $LBA, $CLK; |
|
|
244 | |
244 | |
245 | $NVRBIT = nvr ? 0x20 : 0x00 if ($LBA & 0x3) == 0x2; |
245 | $NVRBIT = nvr ? 0x20 : 0x00 if ($LBA & 0x3) == 0x2; |
246 | |
246 | |
247 | # KBD_XMITEMPTY LBA7 NVRDATA ODDFIELD - OPTION !GFX !AVO PUSART_TXRDY |
247 | # KBD_XMITEMPTY LBA7 NVRDATA ODDFIELD - OPTION !GFX !AVO PUSART_TXRDY |
248 | |
248 | |
… | |
… | |
266 | sub in_17 { 0xff } # unknown, printer status clear by reading? |
266 | sub in_17 { 0xff } # unknown, printer status clear by reading? |
267 | sub in_1b { 0xff } # unknown |
267 | sub in_1b { 0xff } # unknown |
268 | |
268 | |
269 | ############################################################################# |
269 | ############################################################################# |
270 | |
270 | |
271 | sub sf { |
271 | sub sf { # set flags (ZSC - AP not implemented) |
272 | $FS = $_[0] & 0x080; |
272 | $FS = $_[0] & 0x080; |
273 | $FZ = ($_[0] & 0x0ff) == 0; |
273 | $FZ = ($_[0] & 0x0ff) == 0; |
274 | $FC = $_[0] & 0x100; |
274 | $FC = $_[0] & 0x100; |
275 | |
275 | |
276 | $_[0] & 0xff |
276 | $_[0] & 0xff |
277 | } |
277 | } |
278 | |
278 | |
279 | sub sf_nc { |
279 | sub sf_nc { # set flags except carry |
280 | $FS = $_[0] & 0x080; |
280 | $FS = $_[0] & 0x080; |
281 | $FZ = ($_[0] & 0x0ff) == 0; |
281 | $FZ = ($_[0] & 0x0ff) == 0; |
282 | |
282 | |
283 | $_[0] & 0xff |
283 | $_[0] & 0xff |
284 | } |
284 | } |
… | |
… | |
549 | require IO::Pty; |
549 | require IO::Pty; |
550 | $PTY = IO::Pty->new; |
550 | $PTY = IO::Pty->new; |
551 | |
551 | |
552 | my $slave = $PTY->slave; |
552 | my $slave = $PTY->slave; |
553 | |
553 | |
|
|
554 | $PTY->set_winsize (24, 80); |
|
|
555 | |
554 | unless (fork) { |
556 | unless (fork) { |
555 | $ENV{TERM} = $VT102 ? "vt102" : "vt100"; |
557 | $ENV{TERM} = $VT102 ? "vt102" : "vt100"; |
556 | |
558 | |
557 | close $PTY; |
559 | close $PTY; |
558 | |
560 | |
559 | open STDIN , "<&", $slave; |
561 | open STDIN , "<&", $slave; |
560 | open STDOUT, ">&", $slave; |
562 | open STDOUT, ">&", $slave; |
561 | open STDERR, ">&", $slave; |
563 | open STDERR, ">&", $slave; |
562 | |
564 | |
|
|
565 | system "stty ixoff erase ^H"; |
|
|
566 | |
|
|
567 | $PTY->make_slave_controlling_terminal; |
563 | close $slave; |
568 | $PTY->close_slave; |
564 | |
569 | |
565 | exec @ARGV; |
570 | exec @ARGV; |
566 | } |
571 | } |
567 | |
572 | |
568 | close $slave; |
573 | $PTY->close_slave; |
|
|
574 | |
569 | } else { |
575 | } else { |
570 | open $PTY, "</dev/null" or die;#d |
576 | open $PTY, "</dev/null" or die;#d |
571 | } |
577 | } |
572 | |
578 | |
573 | ############################################################################# |
579 | ############################################################################# |
… | |
… | |
782 | } |
788 | } |
783 | } |
789 | } |
784 | |
790 | |
785 | # kick off various interrupts |
791 | # kick off various interrupts |
786 | |
792 | |
787 | $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) |
788 | #$INTPEND |= 2 if @PUSARTRECV && $XON;# real vt102 probably does it this way |
794 | #$INTPEND |= 2 if @PUSARTRECV && $XON; # VT102, 6.5 rxrdy |
789 | |
795 | |
|
|
796 | # kick off vertical retrace form time to time |
790 | unless ($CLK & 0x3ff) { |
797 | unless ($CLK & 0x3ff) { |
791 | $RST |= 4; # vertical retrace |
798 | $RST |= 4; # vertical retrace |
792 | } |
799 | } |
793 | |
800 | |
794 | # handle video hardware |
801 | # handle video hardware |