Support for VT100 dot stretching
This commit is contained in:
parent
37593a107d
commit
f7464dd182
7 changed files with 4890 additions and 4701 deletions
|
|
@ -34,11 +34,42 @@ See [DEC VT100 ROMs](/devices/pc8080/rom/vt100/) for more information about the
|
|||
(aka [phooky](https://github.com/phooky) aka Adam Mayer) further explains VT100 memory usage:
|
||||
|
||||
Start End Size Description
|
||||
0x0000 0x1fff 8K Basic ROM
|
||||
0x2000 0x2012 18B Blank lines for refresh (6 x 3B)
|
||||
0x2012 0x204f 61B Stack area (grows down from 0x204e)
|
||||
0x204f 0x22d0 641B Scratch Pad/Setup Area(?)
|
||||
0x22d0 0x2c00 2352B Screen RAM
|
||||
0x0000 0x1fff 8K Basic ROM
|
||||
0x2000 0x2012 18 Blank lines for refresh (6 x 3B)
|
||||
0x2012 0x204f 61 Stack area (grows down from 0x204e)
|
||||
0x204f 0x22d0 641 Scratch Pad/Setup Area(?)
|
||||
0x22d0 0x2c00 2352 Screen RAM
|
||||
|
||||
Note: 0x22bb through 0x22d0 appear to be unused
|
||||
|
||||
In his [Platform Notes](https://github.com/phooky/VT100-Hax/blob/master/Platform%20Notes.md), he further describes
|
||||
portions of the "Scratch Pad" area:
|
||||
|
||||
Start End Size Description
|
||||
0x2052 0x2054 2 0x2004 during init?
|
||||
0x2068 0x2069 1 Keys flag buffer
|
||||
0x206a 0x206e 3 New keys pressed buffer
|
||||
0x20f6 0x20f8 2 0x22d0 during init?
|
||||
0x2014 0x2015 1 0xff during init? [Typo or reference to a byte in the Stack area? -JP]
|
||||
|
||||
and the "Setup" area:
|
||||
|
||||
Start End Size Description
|
||||
0x217b 22 Answerback message (20chars+2delim)
|
||||
0x2191 17 Tabs (bit encoding) (first bit always set)
|
||||
0x21a2 1 80/132 col mode (00 = 80 col, 01 = 132 col)
|
||||
0x21a3 1 intensity (00 = brightest, 0x1f = dimmest)
|
||||
0x21a4 1 Mode byte for PUSART
|
||||
0x21a5 1 Online/local
|
||||
0x21a6 1 Switches 1
|
||||
0x21a7 1 Switches 2
|
||||
0x21a8 1 Switches 3
|
||||
0x21a9 1 Switches 4
|
||||
0x21aa 1 Switches 5
|
||||
0x21ab 1 TX baud rate
|
||||
0x21ac 1 RX baud rate
|
||||
0x21ad 1 parity
|
||||
0x21ae 1 nvr checksum
|
||||
|
||||
VT100 I/O Ports
|
||||
---------------
|
||||
|
|
@ -78,11 +109,11 @@ information about the Flags buffer (port 0x42):
|
|||
|
||||
Bit Active? Description
|
||||
7 H KBD Transmit Buffer Empty
|
||||
6 H LBA 7(?) (It's a pin on the backplane connector...) - used to clock NVR - line buffer address
|
||||
6 H NVR CLOCK, driven by LBA7 (line buffer address)
|
||||
5 H NVR DATA
|
||||
4 L EVEN FIELD (comes out of the video timing generator)
|
||||
3 H OPTION PRESENT (terminal output option???)
|
||||
2 L GRAPHICS FLAG (is VT52 graphics card present) [I think he meant VT125 -JP]
|
||||
2 L GRAPHICS FLAG (is VT125 graphics card present)
|
||||
1 L ADVANCED VIDEO (is AVO present)
|
||||
0 H XMIT FLAG
|
||||
|
||||
|
|
@ -127,6 +158,65 @@ measure 2.0mm x 3.35mm (in 132-column mode, they measure 1.3mm x 3.35mm), which
|
|||
roughly 160mm x 80mm, implying a screen aspect ratio of 2.0. However, after visually comparing the Technical Manual's SET-UP
|
||||
screenshots to our test screens, 1.67 appears to be closer to reality than 2.0. I'll revisit this issue at a later date.
|
||||
|
||||
VT100 Initialization Process
|
||||
----------------------------
|
||||
|
||||
From "Power-Up and Self-Test", section 4.2.8, p. 4-19, of the VT100 Technical Manual (July 1982):
|
||||
|
||||
When power is first applied to the terminal controller board, the reset circuit in the 8224 holds the microprocessor
|
||||
in a halt state. Within a second, after the voltages stabilize in the power supply, the RC network at the reset input
|
||||
allows tlhe input voltage to rise to the switching threshold of a Schmitt trigger. Then the reset is released with the
|
||||
8080 program counter set to 0. The low 64 bytes of program are reserved for the eight interrupt service routines which
|
||||
can be addressed by the restart instruction (see previous section). The low 8 start the power-up routine by disabling
|
||||
the interrupts, setting up the stack pointer, and then going immediately into the self-test routines.
|
||||
|
||||
Assuming there are no hard logic failures present on the board, the microprocessor attempts to perform a confidence
|
||||
check of the controller. Some failures are considered fatal and will stop the machine; other failures limit its operation
|
||||
but win not prevent its use. Fatal failures are indicated by the LEDs on the keyboard, while nonfatal errors are indicated
|
||||
as a single character on the screen.
|
||||
|
||||
The microprocessor first sends the number of the first ROM to the LEDs on the keyboard. Then it calculates a checksum
|
||||
of the contents of the first 2K of program. (Since firmware is treated as four 2K blocks of code, later VT100s with one
|
||||
8K X 8 ROM chip operate the same way but any block failure requires replacement of the one chip). At the time of ROM
|
||||
preparation, a special byte was included within each block to make the checksum equal zero if there are no errors. If
|
||||
there is an error, the microprocessor halts and the LEDs indicate the current ROM at the time of failure. Otherwise, the
|
||||
LEDs are incremented to show the next ROM number and the process continues.
|
||||
|
||||
The next part of the test is writing and reading the RAM. Every bit in the RAM is written with a 0 and a 1 and read each
|
||||
time. If the advanced video option is present (as indicated by the Option Present flag), its RAM is tested immediately
|
||||
after the main RAM. In the main RAM a failure halts the machine. Failure of a bit in the advanced video option RAM is
|
||||
indicated on the screen and the process continues. In another termnnal, the VT52, one bad bit in the screen RAM means there
|
||||
is one location that may not contain right character. This can be annoying to the user but does not affect the rest of the
|
||||
screen. If one bit is bad in a VT100 line address, the entire screen below the affected line can become garbled and unsuable.
|
||||
A bad bit in the scratch area could disable communication with the host. So this confidence check ensures that any RAM
|
||||
failure is detected immediately.
|
||||
|
||||
The next test checks the nonvola1tile RAM by reading it. A checksum is calculated and compared with the value stored the
|
||||
last time the NVR was written during a save. A bad NVR does not stop the VT100 because the SET-UP values can always be
|
||||
reestablished from the keyboard at power-up. The NVR test is also the normal time when the terminal gets its auto SET-UP
|
||||
readings from the NVR. Time is saved because reading the NVR is the most time-consuming part of both the self-test and the
|
||||
auto SET-UP. If the NVR fails, the bell sounds several times to inform the operator, and then default settings stored in
|
||||
the ROM allow the terminal to work. The operator must then manually reset any parameters that differ from the default values.
|
||||
|
||||
To test the keyboard, the microprocessor commands the keyboard to scan once, lights all the LEDs, for about a half second,
|
||||
and sounds the bell. It waits for the scan to finish and then looks for the last key address 7FH at the keyboard UART.
|
||||
If the test fails, the terminal remains on-line, making it a receive-only (RO) terminal.
|
||||
|
||||
This is the end of testing.
|
||||
|
||||
Once the NVR data is in the scratch area in RAM, the microprocessor uses that data to program the hardware. All operating
|
||||
parameters that were last saved (see NVR) are recalled and the terminal is set to match them. Finally the cursor appears
|
||||
at column 1, line 1, and the microprocessor enters its background routine, ready for operation.
|
||||
|
||||
Some additional observations:
|
||||
|
||||
- During the NVR test, a "WAIT" message is displayed in the top-left corner of the screen.
|
||||
- Following the NVR test, code at 0x00D2 loops for 0xFFF (4095) times with the CLICK bit (0x80) set in the keyboard STATUS
|
||||
port (0x82), generating a "bell" (beep), presumably because the NVR test failed. And one would expect the NVR checksum test
|
||||
to fail, since we initialize all NVR words with the freshly-erased value of 0x3fff. Also, at some point before arriving at the
|
||||
preceding loop, the "WAIT" message has been cleared.
|
||||
|
||||
|
||||
Additional VT100 Resources
|
||||
--------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -26,15 +26,18 @@ He then describes the memory map as follows:
|
|||
E52 H H L 0x0800
|
||||
E56 H L L 0x0000
|
||||
|
||||
The above PCB chip locations correspond to the following [DEC ROM](/devices/roms/dec/) dumps:
|
||||
The above PCB chip locations correspond to the following [DEC ROMs](/devices/roms/dec/):
|
||||
|
||||
* E56: [23-061E2.bin](https://web.archive.org/web/20140723115846/http://www.dunnington.u-net.com/public/DECROMs/23-061E2.bin)
|
||||
* E52: [23-032E2.bin](https://web.archive.org/web/20140723115846/http://www.dunnington.u-net.com/public/DECROMs/23-032E2.bin)
|
||||
* E45: [23-033E2.bin](https://web.archive.org/web/20140723115846/http://www.dunnington.u-net.com/public/DECROMs/23-033E2.bin)
|
||||
* E40: [23-034E2.bin](https://web.archive.org/web/20140723115846/http://www.dunnington.u-net.com/public/DECROMs/23-034E2.bin)
|
||||
|
||||
And sure enough, concatenating those four DEC ROM dumps produced a perfect match for Trammell Hudson's
|
||||
[VT100.bin](http://trmm.net/images/2/20/VT100.bin).
|
||||
And sure enough, concatenating those four DEC ROMs:
|
||||
|
||||
cat 23-061E2.bin 23-032E2.bin 23-033E2.bin 23-034E2.bin > VT100.bin
|
||||
|
||||
produces a perfect match for Trammell Hudson's [VT100.bin](http://trmm.net/images/2/20/VT100.bin).
|
||||
|
||||
### Character Generator (2Kb)
|
||||
|
||||
|
|
@ -46,7 +49,7 @@ The ROM contains 128 rows of character data, 16 bytes per character. More on th
|
|||
Following in the footsteps of [vt100romhax](http://vt100romhax.tumblr.com/post/90697428973/the-vt100-memory-map-and-8080-disassembly),
|
||||
I disassembled the ROM, using `dz80` from [D52](http://www.brouhaha.com/~eric/software/d52/) ([manual](http://www.bipom.com/documents/dis51/d52manual.html)):
|
||||
|
||||
dz80 -80 archive/VT100.bin
|
||||
dz80 -80 VT100.bin
|
||||
|
||||
This produced VT100.d80, which I renamed to [VT100.asm](VT100.asm). I fixed one `dz80` bug, replacing references to
|
||||
`X2000` with `2000h`, and then hand-merged most of the comments from [haxrom.d80](https://github.com/phooky/VT100-Hax/blob/master/ROMs/haxrom.d80).
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@ X0000: di
|
|||
jmp X003b
|
||||
|
||||
org 8
|
||||
|
||||
;
|
||||
; Interrupt vector 0x1 for keyboard
|
||||
;
|
||||
X0008: call X00fd
|
||||
ei
|
||||
ret
|
||||
|
|
@ -160,6 +162,9 @@ X00c4: jz X00cb
|
|||
X00cb: mvi a,2fh
|
||||
sta X21c9
|
||||
out 62h
|
||||
;
|
||||
; Prepare to enter the "beep" loop
|
||||
;
|
||||
X00d2: lxi b,X0fff
|
||||
ei
|
||||
X00d6: mvi a,8
|
||||
|
|
@ -172,7 +177,10 @@ X00e0: out 82h
|
|||
mov a,b
|
||||
ora c
|
||||
jnz X00d6
|
||||
out 82h
|
||||
;
|
||||
; Done "beeping" now
|
||||
;
|
||||
X00e8: out 82h ; A = 0, so all LEDs off now
|
||||
lda X2068
|
||||
ora a
|
||||
jm X00f5
|
||||
|
|
@ -180,7 +188,28 @@ X00e0: out 82h
|
|||
ori 4
|
||||
mov d,a
|
||||
X00f5: push d
|
||||
|
||||
;
|
||||
; The next call issues the following:
|
||||
;
|
||||
; 03A2 CD8103 CALL 0381 ;stack=204A
|
||||
; 0B67 CDAD10 CALL 10AD ;stack=2048
|
||||
; chipset.outPort(0x00A2,DC012,0x00) at 10BD
|
||||
; chipset.outPort(0x00A2,DC012,0x04) at 10C1
|
||||
;
|
||||
; and then:
|
||||
;
|
||||
; 03A2 CD8103 CALL 0381 ;stack=204A
|
||||
; 0B67 CDAD10 CALL 10AD ;stack=2048
|
||||
; 10C9 CDAA0F CALL 0FAA ;stack=2046
|
||||
; 0FB6 CC8814 CALLZ 1488 ;stack=2040
|
||||
; 1488 CD9314 CALL 1493 ;stack=203E
|
||||
; chipset.inPort(0x0042,FLAGS.BUFFER): 0x60 at 1493
|
||||
;
|
||||
; Note that once we're inside 0FAA, that appears to be where we stay.
|
||||
;
|
||||
call X03a2
|
||||
|
||||
pop d
|
||||
jmp X0875
|
||||
;;
|
||||
|
|
@ -934,10 +963,10 @@ X06a7: mov a,d
|
|||
ora a
|
||||
ret
|
||||
|
||||
X06aa: lda X2068
|
||||
X06aa: lda X2068 ; A <- [Keys flag buffer]
|
||||
mov e,a
|
||||
ani 80h
|
||||
rz
|
||||
ani 80h ; bit 7 set?
|
||||
rz ; return if not
|
||||
lxi h,X0841
|
||||
push h
|
||||
mov a,e
|
||||
|
|
@ -2344,6 +2373,22 @@ X0f9e: ora m
|
|||
mov m,a
|
||||
ret
|
||||
|
||||
;
|
||||
; Main loop?
|
||||
;
|
||||
; Absent any interrupts, execution gravitates here:
|
||||
;
|
||||
; 0FAA:
|
||||
; ...
|
||||
; call 1488
|
||||
; call 1493 ; read port 0x42 (check flags buffer)
|
||||
; call 06aa ; check byte at [2068]
|
||||
; cli
|
||||
; call 0e3e ; fetch byte at [21A5], OR byte at [207B]
|
||||
; sti
|
||||
; ; return byte at [2172] in A
|
||||
; jmp 0FAE
|
||||
;
|
||||
X0faa: lxi h,X207f
|
||||
add m
|
||||
X0fae: cmp m
|
||||
|
|
@ -2356,6 +2401,9 @@ X0fb2: lda X207b
|
|||
pop psw
|
||||
pop h
|
||||
jmp X0fae
|
||||
;
|
||||
; End of main loop?
|
||||
;
|
||||
|
||||
X0fbe: lhld X204e
|
||||
mov a,h
|
||||
|
|
@ -4728,46 +4776,7 @@ X1fd4: ora a
|
|||
|
||||
; Last but not least, pad out to 8K (8192) bytes
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
org 1fffh
|
||||
nop
|
||||
|
||||
; Miscellaneous equates
|
||||
|
|
@ -4797,7 +4806,7 @@ X205b equ 205bh
|
|||
X205c equ 205ch
|
||||
X2065 equ 2065h
|
||||
X2067 equ 2067h
|
||||
X2068 equ 2068h
|
||||
X2068 equ 2068h ; Keys flag buffer
|
||||
X2069 equ 2069h
|
||||
X206a equ 206ah
|
||||
X206e equ 206eh
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue