… | |
… | |
15 | # |
15 | # |
16 | |
16 | |
17 | # If this file contains embedded ROMs, the above copyright notice does |
17 | # If this file contains embedded ROMs, the above copyright notice does |
18 | # not apply to them. |
18 | # not apply to them. |
19 | |
19 | |
|
|
20 | use 5.010; |
20 | use strict; |
21 | use strict; |
|
|
22 | use integer; |
21 | #use common::sense; |
23 | #use common::sense; |
22 | |
24 | |
23 | my $VT102 = 1; |
25 | my $VT102 = 1; |
24 | my $VT131 = 0; |
26 | my $VT131 = 0; |
25 | my $AVO = 1; |
27 | my $AVO = 1; |
… | |
… | |
64 | SET UP Home |
66 | SET UP Home |
65 | BACKSPACE Rubout |
67 | BACKSPACE Rubout |
66 | CAPS LOCK Prior/PgUp |
68 | CAPS LOCK Prior/PgUp |
67 | NO SCROLL Next/PgDown |
69 | NO SCROLL Next/PgDown |
68 | BREAK End |
70 | BREAK End |
|
|
71 | CTRL-C Insert |
69 | |
72 | |
70 | Set-Up Guide: |
73 | Set-Up Guide: |
71 | |
74 | |
72 | http://vt100.net/docs/vt102-ug/chapter3.html#S3.6 |
75 | http://vt100.net/docs/vt102-ug/chapter3.html#S3.6 |
73 | |
76 | |
… | |
… | |
527 | |
530 | |
528 | my @LED = $VT102 |
531 | my @LED = $VT102 |
529 | ? qw(L1 INSERT DSR CTS LOCKED LOCAL SCAN BEEP) |
532 | ? qw(L1 INSERT DSR CTS LOCKED LOCAL SCAN BEEP) |
530 | : qw(L4 L3 L2 L1 LOCKED LOCAL SCAN BEEP); |
533 | : qw(L4 L3 L2 L1 LOCKED LOCAL SCAN BEEP); |
531 | |
534 | |
|
|
535 | my $CURSOR_IS_ON; |
|
|
536 | |
532 | # display screen |
537 | # display screen |
533 | sub display { |
538 | sub display { |
|
|
539 | # this is for the powersave mode - check whether the cursor is on here, |
|
|
540 | # and only allow powersave later when it was on the last display time |
|
|
541 | $CURSOR_IS_ON = $M[$VT102 ? 0x207b : 0x21ba]; |
|
|
542 | |
534 | my $i = 0x2000; |
543 | my $i = 0x2000; |
535 | |
544 | |
536 | my $leds = join " ", map $KSTATUS & 2**$_ ? "\e[7m$LED[$_]\e[m" : "$LED[$_]", reverse 0 .. $#LED; |
545 | my $leds = join " ", map $KSTATUS & 2**$_ ? "\e[7m$LED[$_]\e[m" : "$LED[$_]", reverse 0 .. $#LED; |
537 | |
546 | |
538 | my $scr = sprintf "\e[H--- LED [ %s ] CLK %d\e[K\n", $leds, $CLK; |
547 | my $scr = sprintf "\e[H--- LED [ %s ] CLK %d\e[K\n", $leds, $CLK; |
… | |
… | |
590 | "\x1e" => 0x24 | 0x100, # CTRL-~ |
599 | "\x1e" => 0x24 | 0x100, # CTRL-~ |
591 | "\x1f" => 0x75 | 0x100, # CTRL-? |
600 | "\x1f" => 0x75 | 0x100, # CTRL-? |
592 | |
601 | |
593 | # hardcoded rxvt keys |
602 | # hardcoded rxvt keys |
594 | "\e" => 0x2a, # ESC |
603 | "\e" => 0x2a, # ESC |
|
|
604 | "\e[2~" => 0x79 | 0x100, # CTRL-C (insert) |
595 | "\e[3~" => 0x03, # DC |
605 | "\e[3~" => 0x03, # DC |
596 | "\e[5~" => 0x7e, # CAPS LOCK (prior) |
606 | "\e[5~" => 0x7e, # CAPS LOCK (prior) |
597 | "\e[6~" => 0x6a, # NO SCROLL (next) |
607 | "\e[6~" => 0x6a, # NO SCROLL (next) |
598 | "\e[A" => 0x30, # UP |
608 | "\e[A" => 0x30, # UP |
599 | "\e[B" => 0x22, # DOWN |
609 | "\e[B" => 0x22, # DOWN |
… | |
… | |
606 | "\e[7~" => 0x7b, # SETUP (home) |
616 | "\e[7~" => 0x7b, # SETUP (home) |
607 | "\e[8~" => 0x23, # BREAK (end) |
617 | "\e[8~" => 0x23, # BREAK (end) |
608 | "\e[8\$" => 0x23 | 0x080, # SHIFT BREAK / DISCONNECT (shift-end) |
618 | "\e[8\$" => 0x23 | 0x080, # SHIFT BREAK / DISCONNECT (shift-end) |
609 | "\x7f" => 0x33, # BACKSPACE |
619 | "\x7f" => 0x33, # BACKSPACE |
610 | |
620 | |
611 | "\e[11~" => 0x32, # F1 |
621 | "\e[11~" => 0x32, # PF1 |
612 | "\e[11~" => 0x42, # F2 |
622 | "\e[12~" => 0x42, # PF2 |
613 | "\e[11~" => 0x31, # F3 |
623 | "\e[13~" => 0x31, # PF3 |
614 | "\e[11~" => 0x41, # F4 |
624 | "\e[14~" => 0x41, # PF4 |
615 | ); |
625 | ); |
616 | |
626 | |
617 | @KEYMAP{map chr, 0x20 .. 0x40, 0x5b .. 0x7e} = unpack "C*", pack "H*", |
627 | @KEYMAP{map chr, 0x20 .. 0x40, 0x5b .. 0x7e} = unpack "C*", pack "H*", |
618 | "779ad5a9a8b8a755a6b5b6b466256575" . "351a3929283837273626d656e634e5f5" . "b9" # 20..40 |
628 | "779ad5a9a8b8a755a6b5b6b466256575" . "351a3929283837273626d656e634e5f5" . "b9" # 20..40 |
619 | . "154514b7a5" . "244a6879591949485816574746766706" . "050a185a0817780969077a95c594a4"; # 5b..7e |
629 | . "154514b7a5" . "244a6879591949485816574746766706" . "050a185a0817780969077a95c594a4"; # 5b..7e |
… | |
… | |
648 | # skip input we can't decipher |
658 | # skip input we can't decipher |
649 | substr $STDIN_BUF, 0, 1, ""; |
659 | substr $STDIN_BUF, 0, 1, ""; |
650 | } |
660 | } |
651 | |
661 | |
652 | if ($KBD) { |
662 | if ($KBD) { |
653 | system "stty -icanon -icrnl -inlcr -echo min 1 time 0"; |
663 | system "stty -icanon -icrnl -inlcr -echo min 1 time 0"; # -isig |
654 | eval q{ sub END { system "stty sane" } }; |
664 | eval q{ sub END { system "stty sane" } }; |
655 | $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = sub { exit 1 }; |
665 | $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = sub { exit 1 }; |
656 | } |
666 | } |
657 | |
667 | |
658 | ############################################################################# |
668 | ############################################################################# |
… | |
… | |
679 | ); |
689 | ); |
680 | |
690 | |
681 | ############################################################################# |
691 | ############################################################################# |
682 | # process/pty management |
692 | # process/pty management |
683 | |
693 | |
|
|
694 | if (1) { |
684 | require IO::Pty; |
695 | require IO::Pty; |
685 | $PTY = IO::Pty->new; |
696 | $PTY = IO::Pty->new; |
686 | |
697 | |
687 | my $slave = $PTY->slave; |
698 | my $slave = $PTY->slave; |
688 | |
699 | |
689 | $PTY->set_winsize (24, 80); |
700 | $PTY->set_winsize (24, 80); |
690 | |
701 | |
691 | unless (fork) { |
702 | unless (fork) { |
692 | $ENV{LC_ALL} = "C"; |
703 | $ENV{LC_ALL} = "C"; |
693 | $ENV{TERM} = $VT102 ? "vt102" : "vt100"; |
704 | $ENV{TERM} = $VT102 ? "vt102" : "vt100"; |
694 | |
705 | |
695 | close $PTY; |
706 | close $PTY; |
696 | |
707 | |
697 | open STDIN , "<&", $slave; |
708 | open STDIN , "<&", $slave; |
698 | open STDOUT, ">&", $slave; |
709 | open STDOUT, ">&", $slave; |
699 | open STDERR, ">&", $slave; |
710 | open STDERR, ">&", $slave; |
700 | |
711 | |
701 | system "stty ixoff erase ^H"; |
712 | system "stty ixoff erase ^H"; |
702 | |
713 | |
703 | $PTY->make_slave_controlling_terminal; |
714 | $PTY->make_slave_controlling_terminal; |
|
|
715 | $PTY->close_slave; |
|
|
716 | |
|
|
717 | @ARGV = "sh" unless @ARGV; |
|
|
718 | exec @ARGV; |
|
|
719 | } |
|
|
720 | |
704 | $PTY->close_slave; |
721 | $PTY->close_slave; |
705 | |
722 | } else { |
706 | @ARGV = "sh" unless @ARGV; |
723 | open $PTY, "+</dev/null" |
707 | exec @ARGV; |
724 | or die "/dev/null: $!"; |
708 | } |
725 | } |
709 | |
|
|
710 | $PTY->close_slave; |
|
|
711 | |
726 | |
712 | ############################################################################# |
727 | ############################################################################# |
713 | # the actual hardware simulator |
728 | # the actual hardware simulator |
714 | |
729 | |
715 | my @ICACHE; # compiled instruction/basic block cache |
730 | my @ICACHE; # compiled instruction/basic block cache |
… | |
… | |
721 | (vec $RIN, 0, 1) = 1 if $KBD; |
736 | (vec $RIN, 0, 1) = 1 if $KBD; |
722 | (vec $RIN, fileno $PTY, 1) = 1 if $PTY; |
737 | (vec $RIN, fileno $PTY, 1) = 1 if $PTY; |
723 | |
738 | |
724 | # the cpu. |
739 | # the cpu. |
725 | while () { |
740 | while () { |
726 | # execute extended basic blocks |
741 | # execute an extended basic block |
727 | $PC = ($ICACHE[$PC] ||= do { |
742 | $PC = ($ICACHE[$PC] ||= do { |
728 | my $pc = $PC; |
743 | my $pc = $PC; |
729 | |
744 | |
730 | my $insn = ""; |
745 | my $insn = ""; |
731 | |
746 | |
… | |
… | |
754 | |
769 | |
755 | |
770 | |
756 | $insn .= $pc; |
771 | $insn .= $pc; |
757 | $insn =~ s/\x00.*$//s; |
772 | $insn =~ s/\x00.*$//s; |
758 | |
773 | |
759 | eval "use integer; sub { $insn }" or die "$insn: $@" |
774 | eval "sub { $insn }" or die "$insn: $@" |
760 | })->(); |
775 | })->(); |
761 | |
776 | |
762 | ++$CLK; |
777 | ++$CLK; |
763 | |
778 | |
764 | # things we do from time to time only |
779 | # things we do from time to time only |
765 | unless ($CLK & 0xf) { |
780 | unless ($CLK & 0xf) { |
766 | # do I/O |
781 | # do I/O |
767 | |
782 | |
768 | unless ($CLK & 0xfff) { |
783 | unless ($CLK & 0xfff) { |
769 | if (select $x = $RIN, undef, undef, $POWERSAVE < 100 ? 0 : 0.2) { |
784 | if (select $x = $RIN, undef, undef, $POWERSAVE < 10 ? 0 : $CURSOR_IS_ON && 3600) { |
770 | |
785 | |
771 | # pty/serial I/O |
786 | # pty/serial I/O |
772 | if ($PTY && (vec $x, fileno $PTY, 1) && (@PUSARTRECV < 128) && !@KQUEUE) { |
787 | if ($PTY && (vec $x, fileno $PTY, 1) && (@PUSARTRECV < 128) && !@KQUEUE) { |
773 | sysread $PTY, my $buf, 256; |
788 | sysread $PTY, my $buf, 256; |
774 | |
789 | |