… | |
… | |
21 | #use common::sense; |
21 | #use common::sense; |
22 | |
22 | |
23 | my $VT102 = 1; |
23 | my $VT102 = 1; |
24 | my $VT131 = 0; |
24 | my $VT131 = 0; |
25 | my $AVO = 1; |
25 | my $AVO = 1; |
26 | my $KBD = 1; |
|
|
27 | |
26 | |
28 | shift, ($VT102 = 0), ($AVO = 0) if $ARGV[0] =~ /^-?-vt100$/; |
27 | shift, ($VT102 = 0), ($AVO = 0) if $ARGV[0] =~ /^-?-vt100$/; |
29 | shift, ($VT102 = 0) if $ARGV[0] =~ /^-?-vt100\+avo$/; |
28 | shift, ($VT102 = 0) if $ARGV[0] =~ /^-?-vt100\+avo$/; |
30 | shift if $ARGV[0] =~ /^-?-vt102$/; |
29 | shift if $ARGV[0] =~ /^-?-vt102$/; |
31 | shift, ($VT131 = 1) if $ARGV[0] =~ /^-?-vt131$/; |
30 | shift, ($VT131 = 1) if $ARGV[0] =~ /^-?-vt131$/; |
… | |
… | |
72 | EOF |
71 | EOF |
73 | } |
72 | } |
74 | |
73 | |
75 | ############################################################################# |
74 | ############################################################################# |
76 | # ROM/hardware init |
75 | # ROM/hardware init |
|
|
76 | |
|
|
77 | my $PTY; # the pty we allocated, if any |
|
|
78 | my $KBD = 1; |
77 | |
79 | |
78 | my $ROMS = do { |
80 | my $ROMS = do { |
79 | binmode DATA; |
81 | binmode DATA; |
80 | local $/; |
82 | local $/; |
81 | <DATA> |
83 | <DATA> |
… | |
… | |
95 | } |
97 | } |
96 | |
98 | |
97 | ############################################################################# |
99 | ############################################################################# |
98 | # 8085 CPU registers and I/O support |
100 | # 8085 CPU registers and I/O support |
99 | |
101 | |
100 | my $PTY; # the pty we allocated, if any |
|
|
101 | |
|
|
102 | # 8080/8085 registers |
102 | # 8080/8085 registers |
103 | # b, c, d, e, h, l, a |
|
|
104 | my ($A, $B, $C, $D, $E, $H, $L, $A); |
103 | my ($A, $B, $C, $D, $E, $H, $L); |
105 | my ($PC, $SP, $IFF, $FA, $FZ, $FS, $FP, $FC); |
104 | my ($PC, $SP, $IFF, $FA, $FZ, $FS, $FP, $FC); |
106 | |
105 | |
107 | my $RST = 0; # 8080 pending interrupts |
106 | my $RST = 0; # 8080 pending interrupts |
108 | my $INTMASK = 7; # 8085 half interrupts |
107 | my $INTMASK = 7; # 8085 half interrupts |
109 | my $INTPEND = 0; # 8085 half interrupts |
108 | my $INTPEND = 0; # 8085 half interrupts |
110 | |
|
|
111 | my $x; # dummy temp for instructions |
|
|
112 | |
109 | |
113 | my $CLK; # rather inexact clock |
110 | my $CLK; # rather inexact clock |
114 | |
111 | |
115 | ############################################################################# |
112 | ############################################################################# |
116 | # the dreaded NVR1400 chip. not needed to get it going, but provided anyway |
113 | # the dreaded NVR1400 chip. not needed to get it going, but provided anyway |
… | |
… | |
130 | sub { $NVR[$_[0]] = 0x3fff; }, # 5 erase |
127 | sub { $NVR[$_[0]] = 0x3fff; }, # 5 erase |
131 | sub { $NVRDATA = $NVR[$_[0]]; }, # 6 read |
128 | sub { $NVRDATA = $NVR[$_[0]]; }, # 6 read |
132 | sub { }, # 7 standby |
129 | sub { }, # 7 standby |
133 | ); |
130 | ); |
134 | |
131 | |
135 | my @bitidx; |
132 | my @NVR_BITIDX; |
136 | $bitidx[1 << $_] = 9 - $_ for 0..9; |
133 | $NVR_BITIDX[1 << $_] = 9 - $_ for 0..9; |
137 | |
134 | |
138 | # the nvr1400 state machine. what a monster |
135 | # the nvr1400 state machine. what a monster |
139 | sub nvr() { |
136 | sub nvr() { |
140 | my $a1 = $bitidx[(~$NVRADDR ) & 0x3ff]; |
137 | my $a1 = $NVR_BITIDX[(~$NVRADDR ) & 0x3ff]; |
141 | my $a0 = $bitidx[(~$NVRADDR >> 10) & 0x3ff]; |
138 | my $a0 = $NVR_BITIDX[(~$NVRADDR >> 10) & 0x3ff]; |
142 | |
139 | |
143 | # printf "NVR %02x A %020b %d %d D %02x\n", $NVRLATCH, $NVRADDR & 0xfffff, $a1, $a0, $NVRDATA; |
140 | # printf "NVR %02x A %020b %d %d D %02x\n", $NVRLATCH, $NVRADDR & 0xfffff, $a1, $a0, $NVRDATA; |
144 | |
141 | |
145 | $NVRCMD[($NVRLATCH >> 1) & 7]($a1 * 10 + $a0, $NVRLATCH & 1) |
142 | $NVRCMD[($NVRLATCH >> 1) & 7]($a1 * 10 + $a0, $NVRLATCH & 1) |
146 | } |
143 | } |
… | |
… | |
292 | sub in_17 { 0xff } # vt102 unknown, printer status clear by reading? |
289 | sub in_17 { 0xff } # vt102 unknown, printer status clear by reading? |
293 | sub in_1b { 0xff } # vt102 unknown |
290 | sub in_1b { 0xff } # vt102 unknown |
294 | |
291 | |
295 | ############################################################################# |
292 | ############################################################################# |
296 | # 8085 cpu opcodes and flag handling |
293 | # 8085 cpu opcodes and flag handling |
|
|
294 | |
|
|
295 | my $x; # dummy scratchpad for opcodes |
297 | |
296 | |
298 | sub sf { # set flags (ZSC - AP not implemented) |
297 | sub sf { # set flags (ZSC - AP not implemented) |
299 | $FS = $_[0] & 0x080; |
298 | $FS = $_[0] & 0x080; |
300 | $FZ = !($_[0] & 0x0ff); |
299 | $FZ = !($_[0] & 0x0ff); |
301 | $FC = $_[0] & 0x100; |
300 | $FC = $_[0] & 0x100; |
… | |
… | |
801 | # 6.5 vt125 mb7 read ready (something modem?) |
800 | # 6.5 vt125 mb7 read ready (something modem?) |
802 | # 7.5 vt125 mb7 vblank h(?) |
801 | # 7.5 vt125 mb7 vblank h(?) |
803 | # trap vt125 mbi init h(?) |
802 | # trap vt125 mbi init h(?) |
804 | my $vec; |
803 | my $vec; |
805 | |
804 | |
806 | $x = $INTPEND & ~$INTMASK; |
805 | my $pend = $INTPEND & ~$INTMASK; |
807 | |
806 | |
808 | if ($x & 1) { $vec = 0x2c; $INTPEND &= ~1; |
807 | if ($pend & 1) { $vec = 0x2c; $INTPEND &= ~1; |
809 | } elsif ($x & 2) { $vec = 0x34; $INTPEND &= ~2; |
808 | } elsif ($pend & 2) { $vec = 0x34; $INTPEND &= ~2; |
810 | } elsif ($x & 4) { $vec = 0x3c; $INTPEND &= ~4; |
809 | } elsif ($pend & 4) { $vec = 0x3c; $INTPEND &= ~4; |
811 | # } elsif ($RST ) { $vec = $RST * 8; $RST = 0; # the vt102 firmware doesn't like combined interrupts |
810 | # } elsif ($RST ) { $vec = $RST * 8; $RST = 0; # the vt102 firmware doesn't like combined interrupts |
812 | } elsif ($RST & 1) { $vec = 0x08; $RST &= ~1; # separate is better for vt102 |
811 | } elsif ($RST & 1) { $vec = 0x08; $RST &= ~1; # separate is better for vt102 |
813 | } elsif ($RST & 2) { $vec = 0x10; $RST &= ~2; |
812 | } elsif ($RST & 2) { $vec = 0x10; $RST &= ~2; |
814 | } elsif ($RST & 4) { $vec = 0x20; $RST &= ~4; |
813 | } elsif ($RST & 4) { $vec = 0x20; $RST &= ~4; |
815 | } else { |
814 | } else { |