Merge branch 'master' into gh-pages
This commit is contained in:
commit
28418ab9c7
16 changed files with 2011 additions and 564 deletions
|
|
@ -5,14 +5,15 @@ permalink: /devices/pc8080/machine/invaders/
|
|||
machines:
|
||||
- type: pc8080
|
||||
id: invaders
|
||||
debugger: true
|
||||
---
|
||||
|
||||
Space Invaders (1978)
|
||||
---
|
||||
|
||||
This is a test of [PC8080](/modules/pc8080/), a new 8080-based machine emulator recently added to the
|
||||
PCjs Project. It is currently playable only in desktop browsers and uses the following hard-coded key mappings:
|
||||
PCjs Project.
|
||||
|
||||
It is currently playable only in desktop browsers and uses the following hard-coded key mappings:
|
||||
|
||||
- 1: One Player
|
||||
- 2: Two Player
|
||||
|
|
@ -21,71 +22,7 @@ PCjs Project. It is currently playable only in desktop browsers and uses the fo
|
|||
- D: Move Right
|
||||
- L: Fire Missile
|
||||
|
||||
Assorted [Space Invaders Hardware Notes](#space-invaders-hardware-notes) are collected below.
|
||||
See the [Debugger Configuration](/devices/pc8080/machine/invaders/debugger/) for more control of the machine, along
|
||||
with assorted [Space Invaders Hardware Notes](/devices/pc8080/machine/invaders/debugger/#space-invaders-hardware-notes).
|
||||
|
||||
{% include machine.html id="invaders" %}
|
||||
|
||||
Space Invaders Hardware Notes
|
||||
---
|
||||
|
||||
### Memory Map
|
||||
|
||||
0000-1FFF r ROM code
|
||||
2000-23FF rw RAM
|
||||
2400-3FFF rw bitmapped screen (224x256)
|
||||
|
||||
### I/O Map
|
||||
|
||||
00 r
|
||||
01 r control inputs
|
||||
bit 7
|
||||
bit 6 right
|
||||
bit 5 left
|
||||
bit 4 fire
|
||||
bit 3
|
||||
bit 2 1 player start
|
||||
bit 1 2 player start
|
||||
bit 0 coin slot
|
||||
02 r control inputs
|
||||
bit 7 0=display coin info
|
||||
bit 6 right 2
|
||||
bit 5 left 2
|
||||
bit 4 fire 2
|
||||
bit 3 bonus (1500,1000) / preset mode
|
||||
bit 2 1=tilt
|
||||
bit 0-1 initial lives (3,4,5,6) / (3,4)
|
||||
02 w shift count (0-7)
|
||||
03 r shifted value (low then high)
|
||||
03 w sound
|
||||
bit 4 bonus base
|
||||
bit 3 invader hit
|
||||
bit 2 base hit
|
||||
bit 1 base fire
|
||||
bit 0 saucer
|
||||
04 w value to shift
|
||||
05 w sound
|
||||
bit 5 flip video
|
||||
bit 4 saucer hit
|
||||
bit 3 invader movement 4
|
||||
bit 2 invader movement 3
|
||||
bit 1 invader movement 2
|
||||
bit 0 invader movement 1
|
||||
06 w watchdog timer clear
|
||||
|
||||
Note that, unlike most emulators, PC8080 (like PCx86) has a *[Bus](/modules/pc8080/lib/bus.js)* architecture,
|
||||
allowing components to "plug in" different kinds of memory or memory-mapped devices at different addresses,
|
||||
and to register specific functions for specific I/O ports.
|
||||
|
||||
For example, Space Invaders has 8Kb of ROM at addresses 0x0000 through 0x1FFF, which means that if any 8080 code
|
||||
attempts to write to those addresses, nothing should happen. Unfortunately, most emulators treat the entire address
|
||||
space as one contiguous array of bytes. Which means either that the ROM is susceptible to corruption *or* that every
|
||||
write operation must check the address to determine its validity, which hurts the performance of *all* writes.
|
||||
|
||||
In PC8080 (and PCx86), all writes are equally fast, and all ROMs are fully protected. An exception is made for the
|
||||
Debugger, which allows you to use the "e" command to modify ("patch") ROM code on the fly, but that is completely
|
||||
outside and independent of the 8080 code being emulated.
|
||||
|
||||
### Other Online References
|
||||
|
||||
See [Computer Archeology](http://www.computerarcheology.com/Arcade/SpaceInvaders/) for an excellent collection
|
||||
of materials on the original Space Invaders, including commented ROM disassemblies.
|
||||
|
|
|
|||
94
devices/pc8080/machine/invaders/debugger/README.md
Normal file
94
devices/pc8080/machine/invaders/debugger/README.md
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
---
|
||||
layout: page
|
||||
title: Space Invaders (1978) with Debugger
|
||||
permalink: /devices/pc8080/machine/invaders/debugger/
|
||||
machines:
|
||||
- type: pc8080
|
||||
id: invaders
|
||||
debugger: true
|
||||
---
|
||||
|
||||
Space Invaders (1978) with Debugger
|
||||
-----------------------------------
|
||||
|
||||
The [PC8080](/modules/pc8080/) machine below is configured to run [Space Invaders](/devices/pc8080/machine/invaders/)
|
||||
with a Control Panel and Debugger.
|
||||
|
||||
It is currently playable only in desktop browsers and uses the following hard-coded key mappings:
|
||||
|
||||
- 1: One Player
|
||||
- 2: Two Player
|
||||
- 3: Insert Coin
|
||||
- A: Move Left
|
||||
- D: Move Right
|
||||
- L: Fire Missile
|
||||
|
||||
Click the "Run" button to start the simulation. You'll also find assorted
|
||||
[Space Invaders Hardware Notes](#space-invaders-hardware-notes) below.
|
||||
|
||||
{% include machine.html id="invaders" %}
|
||||
|
||||
Space Invaders Hardware Notes
|
||||
-----------------------------
|
||||
|
||||
### Memory Map
|
||||
|
||||
0000-1FFF r ROM code
|
||||
2000-23FF rw RAM
|
||||
2400-3FFF rw bitmapped screen (224x256)
|
||||
|
||||
### I/O Map
|
||||
|
||||
00 r
|
||||
01 r control inputs
|
||||
bit 7
|
||||
bit 6 right
|
||||
bit 5 left
|
||||
bit 4 fire
|
||||
bit 3
|
||||
bit 2 1 player start
|
||||
bit 1 2 player start
|
||||
bit 0 coin slot
|
||||
02 r control inputs
|
||||
bit 7 0=display coin info
|
||||
bit 6 right 2
|
||||
bit 5 left 2
|
||||
bit 4 fire 2
|
||||
bit 3 bonus (1500,1000) / preset mode
|
||||
bit 2 1=tilt
|
||||
bit 0-1 initial lives (3,4,5,6) / (3,4)
|
||||
02 w shift count (0-7)
|
||||
03 r shifted value (low then high)
|
||||
03 w sound
|
||||
bit 4 bonus base
|
||||
bit 3 invader hit
|
||||
bit 2 base hit
|
||||
bit 1 base fire
|
||||
bit 0 saucer
|
||||
04 w value to shift
|
||||
05 w sound
|
||||
bit 5 flip video
|
||||
bit 4 saucer hit
|
||||
bit 3 invader movement 4
|
||||
bit 2 invader movement 3
|
||||
bit 1 invader movement 2
|
||||
bit 0 invader movement 1
|
||||
06 w watchdog timer clear
|
||||
|
||||
Note that, unlike most emulators, PC8080 (like PCx86) has a *[Bus](/modules/pc8080/lib/bus.js)* architecture,
|
||||
allowing components to "plug in" different kinds of memory or memory-mapped devices at different addresses,
|
||||
and to register specific functions for specific I/O ports.
|
||||
|
||||
For example, Space Invaders has 8Kb of ROM at addresses 0x0000 through 0x1FFF, which means that if any 8080 code
|
||||
attempts to write to those addresses, nothing should happen. Unfortunately, most emulators treat the entire address
|
||||
space as one contiguous array of bytes. Which means either that the ROM is susceptible to corruption *or* that every
|
||||
write operation must check the address to determine its validity, which hurts the performance of *all* writes.
|
||||
|
||||
In PC8080 (and PCx86), all writes are equally fast, and all ROMs are fully protected. An exception is made for the
|
||||
Debugger, which allows you to use the "e" command to modify ("patch") ROM code on the fly, but that is completely
|
||||
outside and independent of the 8080 code being emulated.
|
||||
|
||||
### Other Online References
|
||||
|
||||
See [Computer Archeology](http://www.computerarcheology.com/Arcade/SpaceInvaders/) for an excellent collection
|
||||
of materials on the original Space Invaders, including commented ROM disassemblies.
|
||||
24
devices/pc8080/machine/invaders/debugger/machine.xml
Normal file
24
devices/pc8080/machine/invaders/debugger/machine.xml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml-stylesheet type="text/xsl" href="/versions/pc8080/1.23.3/machine.xsl"?>
|
||||
<machine id="invaders" class="pc8080" border="1" pos="center" background="#FAEBD7">
|
||||
<name pos="center">Space Invaders</name>
|
||||
<computer id="computer" busWidth="16"/>
|
||||
<cpu id="cpu8080" model="8080" cycles="2000000" autoStart="true"/>
|
||||
<rom id="romH" addr="0x0000" size="0x0800" file="/devices/pc8080/rom/invaders/INVADERS-H.json"/>
|
||||
<rom id="romG" addr="0x0800" size="0x0800" file="/devices/pc8080/rom/invaders/INVADERS-G.json"/>
|
||||
<rom id="romF" addr="0x1000" size="0x0800" file="/devices/pc8080/rom/invaders/INVADERS-F.json"/>
|
||||
<rom id="romE" addr="0x1800" size="0x0800" file="/devices/pc8080/rom/invaders/INVADERS-E.json"/>
|
||||
<ram id="ram" addr="0x2000" size="0x0400"/>
|
||||
<video id="video" screenWidth="896" screenHeight="1024" bufferRotate="-90" smoothing="false" bufferAddr="0x2400" bufferCols="256" bufferRows="224" bufferBits="1" bufferLeft="0" interruptRate="120" width="40%" pos="left" padding="8px">
|
||||
<menu>
|
||||
<title>224x256 Screen (Rotated)</title>
|
||||
<control type="container" pos="right">
|
||||
<control type="button" binding="fullScreen" padleft="8px;line-height:1em">Full Screen</control>
|
||||
</control>
|
||||
</menu>
|
||||
</video>
|
||||
<chipset id="chipset" model="SI1978"/>
|
||||
<keyboard id="keyboard"/>
|
||||
<panel ref="/devices/pc8080/panel/left.xml"/>
|
||||
<debugger id="debugger" commands="s 8086"/>
|
||||
</machine>
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
<rom id="romF" addr="0x1000" size="0x0800" file="/devices/pc8080/rom/invaders/INVADERS-F.json"/>
|
||||
<rom id="romE" addr="0x1800" size="0x0800" file="/devices/pc8080/rom/invaders/INVADERS-E.json"/>
|
||||
<ram id="ram" addr="0x2000" size="0x0400"/>
|
||||
<video id="video" screenWidth="896" screenHeight="1024" bufferRotate="-90" smoothing="false" bufferAddr="0x2400" bufferCols="256" bufferRows="224" bufferBits="1" bufferLeft="0" interruptRate="120" width="40%" pos="left" padding="8px">
|
||||
<video id="video" screenWidth="896" screenHeight="1024" bufferRotate="-90" smoothing="false" bufferAddr="0x2400" bufferCols="256" bufferRows="224" bufferBits="1" bufferLeft="0" interruptRate="120" padding="8px">
|
||||
<menu>
|
||||
<title>224x256 Screen (Rotated)</title>
|
||||
<control type="container" pos="right">
|
||||
|
|
@ -19,6 +19,4 @@
|
|||
</video>
|
||||
<chipset id="chipset" model="SI1978"/>
|
||||
<keyboard id="keyboard"/>
|
||||
<panel ref="/devices/pc8080/panel/left.xml"/>
|
||||
<debugger id="debugger" commands="s 8086"/>
|
||||
</machine>
|
||||
|
|
|
|||
|
|
@ -11,121 +11,16 @@ machines:
|
|||
DEC VT100 Terminal
|
||||
------------------
|
||||
|
||||
This is a work-in-progress emulation of another 8080-based machine: the VT100 Terminal.
|
||||
This is a PCjs work-in-progress emulation of another 8080-based machine: the VT100 Terminal.
|
||||
|
||||
Unlike other VT100 emulators, this is not simply an emulation of VT100 protocols. It is a simulation of the original VT100
|
||||
Unlike other VT100 emulators, it is not simply an emulation of VT100 protocols. It is a simulation of the original VT100
|
||||
machine, running the [VT100 Firmware](/devices/pc8080/rom/vt100/) inside the [PC8080](/modules/pc8080/) CPU emulator.
|
||||
|
||||
Admittedly, terminals aren't that useful in isolation, since they're designed to be connected to other (host) machines.
|
||||
But once this PCjs VT100 Terminal simulation is fully operational, you can expect to see it used in conjunction with a variety
|
||||
of other PCjs machines.
|
||||
|
||||
For now, play with the [Debugger Configuration](/devices/pc8080/machine/vt100/debugger/), which also provides information
|
||||
about VT100 internals and links to other technical resources.
|
||||
|
||||
{% include machine.html id="vt100" %}
|
||||
|
||||
VT100 Memory Usage
|
||||
------------------
|
||||
|
||||
As described in the [Technical Manual (July 1982)](http://bitsavers.informatik.uni-stuttgart.de/pdf/dec/terminal/vt100/EK-VT100-TM-003_VT100_Technical_Manual_Jul82.pdf),
|
||||
p. 4-15, 8Kb (0x2000) of ROM is located at 0x0000, and 3Kb (0x0C00) of RAM immediately follows it at 0x2000. The ROM at
|
||||
0x0000 contains all the VT100's 8080 code. The VT100 also contains a 2Kb character generator ROM, but that ROM is not
|
||||
addressable by the CPU; it is used directly by the Video Processor.
|
||||
|
||||
See [DEC VT100 ROMs](/devices/pc8080/rom/vt100/) for more information about the ROMs.
|
||||
|
||||
[vt100romhax](http://vt100romhax.tumblr.com/post/90697428973/the-vt100-memory-map-and-8080-disassembly)
|
||||
(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
|
||||
|
||||
VT100 I/O Ports
|
||||
---------------
|
||||
|
||||
From p. 4-17 of the Technical Manual:
|
||||
|
||||
READ OR WRITE
|
||||
00H PUSART data bus
|
||||
01H PUSART command port
|
||||
|
||||
WRITE ONLY (Decoded with I/O WR L)
|
||||
02H Baud rate generator
|
||||
42H Brightness D/A latch
|
||||
62H NVR latch
|
||||
82H Keyboard UART data input
|
||||
A2H Video processor DC012
|
||||
C2H Video processor DC011
|
||||
E2H Graphics port
|
||||
|
||||
READ ONLY (Decoded with I/O RD L)
|
||||
22H Modem buffer
|
||||
42H Flags buffer
|
||||
82H Keyboard UART data output
|
||||
|
||||
The PC8080 ChipSet component deals with the ER1400's Non-volatile RAM (NVR) ports, the Flags buffer, and the
|
||||
DC011 and DC012 circuits, while the Keyboard component deals with the Keyboard UART.
|
||||
|
||||
You might wonder why the PC8080 Video component doesn't manage the DC011 and DC012. In fact, the above labels are misleading.
|
||||
If you look at the Functional Diagram on p. 4-53 of the Technical Manual, you'll see that DC011 and DC012 are really
|
||||
peripheral components providing inputs to the Video Processor. Moreover, they are not exclusive to the Video Processor.
|
||||
For example, the LBA7 output of the DC011 is also used to clock the NVR chip.
|
||||
|
||||
In most respects, the VT100 Technical Manual provides a phenomenal amount of detail.
|
||||
However, documentation for some of the above ports is almost non-existent. It's only thanks to
|
||||
[third parties](https://github.com/phooky/VT100-Hax/blob/master/Platform%20Notes.md) that we have, for example, the following
|
||||
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
|
||||
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]
|
||||
1 L ADVANCED VIDEO (is AVO present)
|
||||
0 H XMIT FLAG
|
||||
|
||||
VT100 Video Processor
|
||||
---------------------
|
||||
|
||||
Normally, the PC8080 Video component allocates its own video buffer, based on the specified buffer address
|
||||
(*bufferAddr*) and other dimensions (eg, *bufferCols* and *bufferRows*), but the VT100 is a little unusual:
|
||||
it has a custom Video Processor that uses DMA to request character data from any region of RAM, one line at a time.
|
||||
It always defaults to address 0x2000 for the first line of character data, but each line terminates with 3 bytes
|
||||
containing the attributes and address of the next line, so the location of subsequent lines will vary, depending
|
||||
on the type of line:
|
||||
|
||||
- Single-wide characters (80 or 132 columns)
|
||||
- Double-wide characters (40 or 66 columns)
|
||||
|
||||
In addition to single-wide vs. double-wide, line attributes can also specify double-high, along with whether the
|
||||
top or bottom halves of the double-high characters should be displayed, because double-high always implies double-wide
|
||||
(ie, there is no support for double-high, single-wide characters).
|
||||
|
||||
Conssequently, a VT100 [machine XML file](machine.xml) must set the Video component's *bufferRAM* property
|
||||
to "true", indicating that existing RAM should be used, and a new property, *bufferFormat* must be set to "vt100",
|
||||
enabling support for the VT100's line data format; eg:
|
||||
|
||||
<ram id="ram" addr="0x2000" size="0x0C00"/>
|
||||
<video id="video" screenWidth="1600" screenHeight="960" bufferAddr="0x2000" bufferRAM="true" bufferFormat="vt100" bufferCols="80" bufferRows="24" ...>
|
||||
|
||||
VT100 Screen and Character Dimensions
|
||||
-------------------------------------
|
||||
|
||||
Ordinarily, the VT100 screen displays 800 dots per horizontal scan, and a total of 240 horizontal scans, and by default,
|
||||
it uses a 10x10 character cell, for a total of 80 columns and 24 rows of characters. However, in 132-column mode, it
|
||||
uses a 9x10 character cell instead, implying a total of 1188 dots displayed per horizontal scan. This means we will have
|
||||
to dynamically reallocate our internal buffers whenever the horizontal dimensions change. Also, if no AVO expansion
|
||||
card is present, there is only enough RAM available for 14 rows of characters in 132-column mode.
|
||||
|
||||
For optimum scaling, I define the virtual screen size using multiples of the VT100's default "dot" dimensions; eg, 1600x960
|
||||
(a horizontal multiplier of 2 and a vertical multiplier of 4). That gives us a virtual screen aspect ratio of 1.67.
|
||||
|
||||
According to the Technical Manual, a physical VT100 screen measures 12 inches diagonally, and in 80-column mode, characters
|
||||
measure 2.0mm x 3.35mm (in 132-column mode, they measure 1.3mm x 3.35mm), which suggests that the text area of the screen is
|
||||
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.
|
||||
|
||||
Additional VT100 Resources
|
||||
--------------------------
|
||||
|
||||
[VT100 Publications](/pubs/dec/vt100/)
|
||||
|
|
|
|||
134
devices/pc8080/machine/vt100/debugger/README.md
Normal file
134
devices/pc8080/machine/vt100/debugger/README.md
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
---
|
||||
layout: page
|
||||
title: DEC VT100 Terminal
|
||||
permalink: /devices/pc8080/machine/vt100/debugger/
|
||||
machines:
|
||||
- type: pc8080
|
||||
id: vt100
|
||||
debugger: true
|
||||
---
|
||||
|
||||
DEC VT100 Terminal with Debugger
|
||||
--------------------------------
|
||||
|
||||
The [PC8080](/modules/pc8080/) machine below is configured to simulate a [VT100 Terminal](/devices/pc8080/machine/vt100/)
|
||||
with a Control Panel and Debugger. It is running the original [VT100 Firmware](/devices/pc8080/rom/vt100/) inside the
|
||||
[PC8080](/modules/pc8080/) CPU emulator.
|
||||
|
||||
Click the "Run" button to start the simulation. You'll also find assorted
|
||||
[Hardware Notes](#vt100-memory-usage) below.
|
||||
|
||||
{% include machine.html id="vt100" %}
|
||||
|
||||
VT100 Memory Usage
|
||||
------------------
|
||||
|
||||
As described in the [Technical Manual (July 1982)](http://bitsavers.informatik.uni-stuttgart.de/pdf/dec/terminal/vt100/EK-VT100-TM-003_VT100_Technical_Manual_Jul82.pdf),
|
||||
p. 4-15, 8Kb (0x2000) of ROM is located at 0x0000, and 3Kb (0x0C00) of RAM immediately follows it at 0x2000. The ROM at
|
||||
0x0000 contains all the VT100's 8080 code. The VT100 also contains a 2Kb character generator ROM, but that ROM is not
|
||||
addressable by the CPU; it is used directly by the Video Processor.
|
||||
|
||||
See [DEC VT100 ROMs](/devices/pc8080/rom/vt100/) for more information about the ROMs.
|
||||
|
||||
[vt100romhax](http://vt100romhax.tumblr.com/post/90697428973/the-vt100-memory-map-and-8080-disassembly)
|
||||
(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
|
||||
|
||||
VT100 I/O Ports
|
||||
---------------
|
||||
|
||||
From p. 4-17 of the Technical Manual:
|
||||
|
||||
READ OR WRITE
|
||||
00H PUSART data bus
|
||||
01H PUSART command port
|
||||
|
||||
WRITE ONLY (Decoded with I/O WR L)
|
||||
02H Baud rate generator
|
||||
42H Brightness D/A latch
|
||||
62H NVR latch
|
||||
82H Keyboard UART data input
|
||||
A2H Video processor DC012
|
||||
C2H Video processor DC011
|
||||
E2H Graphics port
|
||||
|
||||
READ ONLY (Decoded with I/O RD L)
|
||||
22H Modem buffer
|
||||
42H Flags buffer
|
||||
82H Keyboard UART data output
|
||||
|
||||
The PC8080 ChipSet component deals with the ER1400's Non-volatile RAM (NVR) ports, the Flags buffer, and the
|
||||
DC011 and DC012 circuits, while the Keyboard component deals with the Keyboard UART.
|
||||
|
||||
You might wonder why the PC8080 Video component doesn't manage the DC011 and DC012. In fact, the above labels are misleading.
|
||||
If you look at the Functional Diagram on p. 4-53 of the Technical Manual, you'll see that DC011 and DC012 are really
|
||||
peripheral components providing inputs to the Video Processor. Moreover, they are not exclusive to the Video Processor.
|
||||
For example, the LBA7 output of the DC011 is also used to clock the NVR chip.
|
||||
|
||||
In most respects, the VT100 Technical Manual provides a phenomenal amount of detail.
|
||||
However, documentation for some of the above ports is almost non-existent. It's only thanks to
|
||||
[third parties](https://github.com/phooky/VT100-Hax/blob/master/Platform%20Notes.md) that we have, for example, the following
|
||||
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
|
||||
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]
|
||||
1 L ADVANCED VIDEO (is AVO present)
|
||||
0 H XMIT FLAG
|
||||
|
||||
VT100 Video Processor
|
||||
---------------------
|
||||
|
||||
Normally, the PC8080 Video component allocates its own video buffer, based on the specified buffer address
|
||||
(*bufferAddr*) and other dimensions (eg, *bufferCols* and *bufferRows*), but the VT100 is a little unusual:
|
||||
it has a custom Video Processor that uses DMA to request character data from any region of RAM, one line at a time.
|
||||
It always defaults to address 0x2000 for the first line of character data, but each line terminates with 3 bytes
|
||||
containing the attributes and address of the next line, so the location of subsequent lines will vary, depending
|
||||
on the type of line:
|
||||
|
||||
- Single-wide characters (80 or 132 columns)
|
||||
- Double-wide characters (40 or 66 columns)
|
||||
|
||||
In addition to single-wide vs. double-wide, line attributes can also specify double-high, along with whether the
|
||||
top or bottom halves of the double-high characters should be displayed, because double-high always implies double-wide
|
||||
(ie, there is no support for double-high, single-wide characters).
|
||||
|
||||
Conssequently, a VT100 [machine XML file](machine.xml) must set the Video component's *bufferRAM* property
|
||||
to "true", indicating that existing RAM should be used, and a new property, *bufferFormat* must be set to "vt100",
|
||||
enabling support for the VT100's line data format; eg:
|
||||
|
||||
<ram id="ram" addr="0x2000" size="0x0C00"/>
|
||||
<video id="video" screenWidth="1600" screenHeight="960" bufferAddr="0x2000" bufferRAM="true" bufferFormat="vt100" bufferCols="80" bufferRows="24" ...>
|
||||
|
||||
VT100 Screen and Character Dimensions
|
||||
-------------------------------------
|
||||
|
||||
Ordinarily, the VT100 screen displays 800 dots per horizontal scan, and a total of 240 horizontal scans, and by default,
|
||||
it uses a 10x10 character cell, for a total of 80 columns and 24 rows of characters. However, in 132-column mode, it
|
||||
uses a 9x10 character cell instead, implying a total of 1188 dots displayed per horizontal scan. This means we will have
|
||||
to dynamically reallocate our internal buffers whenever the horizontal dimensions change. Also, if no AVO expansion
|
||||
card is present, there is only enough RAM available for 14 rows of characters in 132-column mode.
|
||||
|
||||
For optimum scaling, I define the virtual screen size using multiples of the VT100's default "dot" dimensions; eg, 1600x960
|
||||
(a horizontal multiplier of 2 and a vertical multiplier of 4). That gives us a virtual screen aspect ratio of 1.67.
|
||||
|
||||
According to the Technical Manual, a physical VT100 screen measures 12 inches diagonally, and in 80-column mode, characters
|
||||
measure 2.0mm x 3.35mm (in 132-column mode, they measure 1.3mm x 3.35mm), which suggests that the text area of the screen is
|
||||
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.
|
||||
|
||||
Additional VT100 Resources
|
||||
--------------------------
|
||||
|
||||
[VT100 Publications](/pubs/dec/vt100/)
|
||||
|
||||
30
devices/pc8080/machine/vt100/debugger/machine.xml
Normal file
30
devices/pc8080/machine/vt100/debugger/machine.xml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml-stylesheet type="text/xsl" href="/versions/pc8080/1.23.3/machine.xsl"?>
|
||||
<machine id="vt100" class="pc8080" border="1" pos="center" background="#FAEBD7">
|
||||
<name pos="center">VT100 Terminal</name>
|
||||
<computer id="computer" busWidth="16"/>
|
||||
<cpu id="cpu8080" model="8080" cycles="2764800"/>
|
||||
<rom id="rom" addr="0x0000" size="0x2000" file="/devices/pc8080/rom/vt100/VT100.json"/>
|
||||
<ram id="ram" addr="0x2000" size="0x0C00"/>
|
||||
<video id="video" screenWidth="1600" screenHeight="960" smoothing="false"
|
||||
fontROM="/devices/pc8080/rom/vt100/23-018E2.json" fontColor="white" cellWidth="10" cellHeight="10"
|
||||
bufferAddr="0x2000" bufferRAM="true" bufferFormat="vt100" bufferCols="80" bufferRows="24" pos="left" padding="8px">
|
||||
<menu>
|
||||
<title>VT100 Screen</title>
|
||||
<control type="container" pos="right">
|
||||
<control type="rled" label="ON LINE" binding="online" padleft="8px"/>
|
||||
<control type="rled" label="LOCAL" binding="local" padleft="8px"/>
|
||||
<control type="rled" label="LOCKED" binding="locked" padleft="8px"/>
|
||||
<control type="rled" label="L1" binding="l1" padleft="8px"/>
|
||||
<control type="rled" label="L2" binding="l2" padleft="8px"/>
|
||||
<control type="rled" label="L3" binding="l3" padleft="8px"/>
|
||||
<control type="rled" label="L4" binding="l4" padleft="8px"/>
|
||||
<control type="button" binding="fullScreen" padleft="8px;line-height:1em">Full Screen</control>
|
||||
</control>
|
||||
</menu>
|
||||
</video>
|
||||
<chipset id="chipset" model="VT100"/>
|
||||
<keyboard id="keyboard"/>
|
||||
<panel ref="/devices/pc8080/panel/wide.xml"/>
|
||||
<debugger id="debugger" messages="mem" commands="s 8086"/>
|
||||
</machine>
|
||||
|
|
@ -3,12 +3,12 @@
|
|||
<machine id="vt100" class="pc8080" border="1" pos="center" background="#FAEBD7">
|
||||
<name pos="center">VT100 Terminal</name>
|
||||
<computer id="computer" busWidth="16"/>
|
||||
<cpu id="cpu8080" model="8080" cycles="2764798"/>
|
||||
<cpu id="cpu8080" model="8080" cycles="2764800"/>
|
||||
<rom id="rom" addr="0x0000" size="0x2000" file="/devices/pc8080/rom/vt100/VT100.json"/>
|
||||
<ram id="ram" addr="0x2000" size="0x0C00"/>
|
||||
<video id="video" screenWidth="1600" screenHeight="960" smoothing="false"
|
||||
fontROM="/devices/pc8080/rom/vt100/23-018E2.json" fontColor="white" cellWidth="10" cellHeight="10"
|
||||
bufferAddr="0x2000" bufferRAM="true" bufferFormat="vt100" bufferCols="80" bufferRows="24" pos="left" padding="8px">
|
||||
bufferAddr="0x2000" bufferRAM="true" bufferFormat="vt100" bufferCols="80" bufferRows="24" padding="8px">
|
||||
<menu>
|
||||
<title>VT100 Screen</title>
|
||||
<control type="container" pos="right">
|
||||
|
|
@ -25,6 +25,4 @@
|
|||
</video>
|
||||
<chipset id="chipset" model="VT100"/>
|
||||
<keyboard id="keyboard"/>
|
||||
<panel ref="/devices/pc8080/panel/wide.xml"/>
|
||||
<debugger id="debugger" messages="port|mem" commands="s 8086"/>
|
||||
</machine>
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ and passed on to the PC8080 Debugger. Here are the rebuild steps:
|
|||
grep -E "[0-9]+ [0-9A-D]+.*;;" VT100.lst | sed -E "s/ *[0-9]+ ([0-9A-F]+).*;(;.*)/ \1 . \2/" > VT100.map
|
||||
filedump --file=VT100.bin --format=bytes --output=VT100.json --comments --overwrite
|
||||
|
||||
You can omit `--comments` to reduce the size of the [VT100.json](VT100.json) file.
|
||||
|
||||
Some [VT100.asm](VT100.asm) clean-up remains, because there are still chunks of data that were incorrectly disassembled as code.
|
||||
From a reassembly standpoint, it doesn't matter too much, because such instructions get reassembled into the same original binary
|
||||
patterns, but from a readability standpoint, it's a nuisance.
|
||||
|
|
|
|||
|
|
@ -3703,8 +3703,8 @@ X18d7: in 42h
|
|||
jnz X18d7
|
||||
mvi a,2fh ;; Write 0x2fh (standby) to nvr latch
|
||||
out 62h
|
||||
lxi h,X21d3 ;; HL=X21d3
|
||||
mvi b,0eh ;; B= 14 -- we're reading 14 bits
|
||||
lxi h,X21d3 ;; HL = X21d3
|
||||
mvi b,0eh ;; B = 14 -- we're reading 14 bits
|
||||
X18e6: in 42h
|
||||
ana c
|
||||
jz X18e6
|
||||
|
|
@ -3726,7 +3726,7 @@ X1900: in 42h
|
|||
jnz X18f6 ;; read next bit
|
||||
mvi a,2fh ;; send standby
|
||||
out 62h
|
||||
lxi d,X21d3 ;; DE=0x21d3
|
||||
lxi d,X21d3 ;; DE = 0x21d3
|
||||
mvi b,0eh ;; B = 14
|
||||
lxi h,X0000 ;; HL = 0
|
||||
X1916: dad h ;;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -631,7 +631,7 @@ FileDump.prototype.loadMap = function(sMapFile, done)
|
|||
done(new Error("unrecognized line (" + s + ") in MAP file: " + sMapName), null);
|
||||
return;
|
||||
}
|
||||
sMapData = JSON.stringify(aSymbols);
|
||||
sMapData = obj.fJSONComments? JSON.stringify(aSymbols, null, 2) : JSON.stringify(aSymbols);
|
||||
if (sMapData) {
|
||||
obj.json = '{' + obj.json + ',"symbols":' + sMapData + '}';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,10 +171,10 @@ ChipSet.SI1978 = {
|
|||
* to yield a 361.69ns clock period for the 8080 CPU, which means the CPU is running at 2.76Mhz (cycles per second).
|
||||
* Hence the CPU component in the VT100's machine.xml is defined as:
|
||||
*
|
||||
* <cpu id="cpu8080" model="8080" cycles="2764798"/>
|
||||
* <cpu id="cpu8080" model="8080" cycles="2764800"/>
|
||||
*
|
||||
* Beyond that, we don't really care about that particular 8224. I only mention it because knowing the CPU frequency
|
||||
* is helpful for simulating some of the other circuits below that we DO care about.
|
||||
* where 2764800 = 24883200 / 9. Beyond that, we don't really care about that particular 8224. I only mention it
|
||||
* because knowing the CPU frequency is helpful for simulating some of the other circuits below that we DO care about.
|
||||
*/
|
||||
ChipSet.VT100 = {
|
||||
MODEL: 100.0,
|
||||
|
|
@ -189,13 +189,24 @@ ChipSet.VT100 = {
|
|||
NVR_CLK: 0x40, // NVR CLOCK if SET
|
||||
KBD_XMIT: 0x80 // KBD XMIT BUFFER empty if SET
|
||||
},
|
||||
BRIGHTNESS_LATCH: {
|
||||
BRIGHTNESS: {
|
||||
PORT: 0x42, // write-only
|
||||
INIT: 0x00 // for lack of a better guess
|
||||
},
|
||||
NVR_LATCH: {
|
||||
PORT: 0x62, // write-only
|
||||
INIT: 0x00 // for lack of a better guess
|
||||
NVR: {
|
||||
LATCH: {
|
||||
PORT: 0x62 // write-only
|
||||
},
|
||||
CMD: {
|
||||
ACCEPT_DATA: 0x0,
|
||||
ACCEPT_ADDR: 0x1,
|
||||
SHIFT_OUT: 0x2,
|
||||
WRITE: 0x4,
|
||||
ERASE: 0x5,
|
||||
READ: 0x6,
|
||||
STANDBY: 0x7
|
||||
},
|
||||
WORDMASK: 0x3fff // NVR words are 14-bit
|
||||
},
|
||||
DC012: { // generates scan counts for the Video Processor
|
||||
PORT: 0xA2, // write-only
|
||||
|
|
@ -220,8 +231,8 @@ ChipSet.VT100 = {
|
|||
*
|
||||
* And on p. 4-62, timings are provided for the LBA0 through LBA7 when the VT100 is in 80-column mode; in particular:
|
||||
*
|
||||
* LBA6: 16.82353us (when LBA6 is low, for a period is 33.64706us)
|
||||
* LBA7: 31.77778us (when LBA7 is high, for a period is 63.55556us)
|
||||
* LBA6: 16.82353us (when LBA6 is low, for a period of 33.64706us)
|
||||
* LBA7: 31.77778us (when LBA7 is high, for a period of 63.55556us)
|
||||
*
|
||||
* If we assume that the CPU cycle count increments once every 361.69ns, it will increment roughly 88 times every
|
||||
* time LBA7 toggles. So we can divide the CPU cycle count by 88 and set LBA to the low bit of that truncated
|
||||
|
|
@ -345,11 +356,13 @@ ChipSet.SI1978.init = [
|
|||
|
||||
ChipSet.VT100.init = [
|
||||
[
|
||||
ChipSet.VT100.BRIGHTNESS_LATCH.INIT,
|
||||
ChipSet.VT100.NVR_LATCH.INIT,
|
||||
ChipSet.VT100.BRIGHTNESS.INIT,
|
||||
ChipSet.VT100.FLAGS_BUFFER.NO_AVO | ChipSet.VT100.FLAGS_BUFFER.NO_GFX,
|
||||
ChipSet.VT100.DC012.INIT,
|
||||
ChipSet.VT100.DC011.INIT
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0, new Array(100)
|
||||
]
|
||||
];
|
||||
|
||||
|
|
@ -381,7 +394,8 @@ ChipSet.prototype.save = function()
|
|||
state.set(0, [this.bStatus0, this.bStatus1, this.bStatus2, this.wShiftData, this.bShiftCount, this.bSound1, this.bSound2]);
|
||||
break;
|
||||
case ChipSet.VT100.MODEL:
|
||||
state.set(0, [this.bBrightnessLatch, this.bNVRLatch, this.bFlagsBuffer, this.bDC012, this.bDC011]);
|
||||
state.set(0, [this.bBrightness, this.bFlagsBuffer, this.bDC012, this.bDC011]);
|
||||
state.set(1, [this.dNVRAddr, this.wNVRData, this.bNVRLatch, this.bNVROut, this.aNVRWords]);
|
||||
break;
|
||||
}
|
||||
return state.data();
|
||||
|
|
@ -411,11 +425,16 @@ ChipSet.prototype.restore = function(data)
|
|||
this.bSound2 = a[6];
|
||||
return true;
|
||||
case ChipSet.VT100.MODEL:
|
||||
this.bBrightnessLatch = a[0];
|
||||
this.bNVRLatch = a[1];
|
||||
this.bBrightness = a[0];
|
||||
this.bFlagsBuffer = a[2];
|
||||
this.bDC012 = a[3];
|
||||
this.bDC011 = a[4];
|
||||
a = data[1];
|
||||
this.dNVRAddr = a[0]; // 20-bit address
|
||||
this.wNVRData = a[1]; // 14-bit word
|
||||
this.bNVRLatch = a[2]; // 1 byte
|
||||
this.bNVROut = a[3]; // 1 bit
|
||||
this.aNVRWords = a[4]; // 100 14-bit words
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -636,6 +655,88 @@ ChipSet.prototype.getVT100LBA = function(nBit)
|
|||
return (this.cpu.getCycles() & (1 << (nBit - 1))) << 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* getNVRAddr()
|
||||
*
|
||||
* @return {number}
|
||||
*/
|
||||
ChipSet.prototype.getNVRAddr = function()
|
||||
{
|
||||
var i;
|
||||
var tens = 0, ones = 0;
|
||||
var addr = ~this.dNVRAddr;
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (addr & 0x1) tens = 9-i;
|
||||
addr >>= 1;
|
||||
}
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (addr & 0x1) ones = 9-i;
|
||||
addr >>= 1;
|
||||
}
|
||||
addr = tens*10 + ones;
|
||||
this.assert(addr >= 0 && addr < this.aNVRWords.length);
|
||||
return addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* doNVRCommand()
|
||||
*/
|
||||
ChipSet.prototype.doNVRCommand = function()
|
||||
{
|
||||
var addr, data;
|
||||
var bit = this.bNVRLatch & 0x1;
|
||||
var bCmd = (this.bNVRLatch >> 1) & 0x7;
|
||||
|
||||
switch(bCmd) {
|
||||
case ChipSet.VT100.NVR.CMD.STANDBY:
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.ACCEPT_ADDR:
|
||||
this.dNVRAddr = (this.dNVRAddr << 1) | bit;
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.ERASE:
|
||||
addr = this.getNVRAddr();
|
||||
this.aNVRWords[addr] = ChipSet.VT100.NVR.WORDMASK;
|
||||
this.printMessage("doNVRCommand(): erase data at addr " + str.toHexWord(addr));
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.ACCEPT_DATA:
|
||||
this.wNVRData = (this.wNVRData << 1) | bit;
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.WRITE:
|
||||
addr = this.getNVRAddr();
|
||||
data = this.wNVRData & ChipSet.VT100.NVR.WORDMASK;
|
||||
this.aNVRWords[addr] = data;
|
||||
this.printMessage("doNVRCommand(): write data " + str.toHexWord(data) + " to addr " + str.toHexWord(addr));
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.READ:
|
||||
addr = this.getNVRAddr();
|
||||
data = this.aNVRWords[addr];
|
||||
/*
|
||||
* Since we don't explicitly initialize aNVRWords[], we pretend any uninitialized words contains WORDMASK.
|
||||
*/
|
||||
if (data == null) data = ChipSet.VT100.NVR.WORDMASK;
|
||||
this.wNVRData = data;
|
||||
this.printMessage("doNVRCommand(): read data " + str.toHexWord(data) + " from addr " + str.toHexWord(addr));
|
||||
break;
|
||||
|
||||
case ChipSet.VT100.NVR.CMD.SHIFT_OUT:
|
||||
this.wNVRData <<= 1;
|
||||
/*
|
||||
* Since WORDMASK is 0x3fff, this will mask the shifted data with 0x4000, which is the bit we want to isolate.
|
||||
*/
|
||||
this.bNVROut = this.wNVRData & (ChipSet.VT100.NVR.WORDMASK + 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
this.printMessage("doNVRCommand(): unrecognized command " + str.toHexByte(bCmd));
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* inVT100FlagsBuffer(port, addrFrom)
|
||||
*
|
||||
|
|
@ -649,23 +750,35 @@ ChipSet.prototype.inVT100FlagsBuffer = function(port, addrFrom)
|
|||
/*
|
||||
* The NVR_CLK bit is driven by LBA7 (ie, bit 7 from Line Buffer Address generation); see the DC011 discussion above.
|
||||
*/
|
||||
var b = this.bFlagsBuffer = (this.bFlagsBuffer & ~ChipSet.VT100.FLAGS_BUFFER.NVR_CLK) | (this.getVT100LBA(7)? ChipSet.VT100.FLAGS_BUFFER.NVR_CLK : 0);
|
||||
var b = this.bFlagsBuffer;
|
||||
b &= ~ChipSet.VT100.FLAGS_BUFFER.NVR_CLK;
|
||||
if (this.getVT100LBA(7)) {
|
||||
b |= ChipSet.VT100.FLAGS_BUFFER.NVR_CLK;
|
||||
if (b != this.bFlagsBuffer) {
|
||||
this.doNVRCommand();
|
||||
}
|
||||
}
|
||||
b &= ~ChipSet.VT100.FLAGS_BUFFER.NVR_DATA;
|
||||
if (this.bNVROut) {
|
||||
b |= ChipSet.VT100.FLAGS_BUFFER.NVR_DATA;
|
||||
}
|
||||
this.bFlagsBuffer = b;
|
||||
this.printMessageIO(port, null, addrFrom, "FLAGS.BUFFER", b, true);
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
* outVT100BrightnessLatch(port, b, addrFrom)
|
||||
* outVT100Brightness(port, b, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @param {number} port (0x42)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
ChipSet.prototype.outVT100BrightnessLatch = function(port, b, addrFrom)
|
||||
ChipSet.prototype.outVT100Brightness = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "BRIGHTNESS.LATCH", null, true);
|
||||
this.bBrightnessLatch = b;
|
||||
this.printMessageIO(port, b, addrFrom, "BRIGHTNESS", null, true);
|
||||
this.bBrightness = b;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -733,7 +846,7 @@ ChipSet.VT100.portsInput = {
|
|||
};
|
||||
|
||||
ChipSet.VT100.portsOutput = {
|
||||
0x42: ChipSet.prototype.outVT100BrightnessLatch,
|
||||
0x42: ChipSet.prototype.outVT100Brightness,
|
||||
0x62: ChipSet.prototype.outVT100NVRLatch,
|
||||
0xA2: ChipSet.prototype.outVT100DC012,
|
||||
0xC2: ChipSet.prototype.outVT100DC011
|
||||
|
|
|
|||
|
|
@ -241,6 +241,7 @@ if (DEBUGGER) {
|
|||
'h': "halt",
|
||||
'i [#]': "input port #",
|
||||
'if': "eval expression",
|
||||
'int [#]': "request interrupt",
|
||||
'k': "stack trace",
|
||||
"ln": "list nearest symbol(s)",
|
||||
'm': "messages",
|
||||
|
|
@ -3288,7 +3289,7 @@ if (DEBUGGER) {
|
|||
{
|
||||
var s = "commands:";
|
||||
for (var sCommand in Debugger.COMMANDS) {
|
||||
s += '\n' + str.pad(sCommand, 7) + Debugger.COMMANDS[sCommand];
|
||||
s += '\n' + str.pad(sCommand, 9) + Debugger.COMMANDS[sCommand];
|
||||
}
|
||||
if (!this.checksEnabled()) s += "\nnote: frequency/history disabled if no exec breakpoints";
|
||||
this.println(s);
|
||||
|
|
@ -3799,6 +3800,26 @@ if (DEBUGGER) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* doInt(sLevel)
|
||||
*
|
||||
* @this {Debugger}
|
||||
* @param {string} sLevel
|
||||
* @return {boolean} true if success, false if error
|
||||
*/
|
||||
Debugger.prototype.doInt = function(sLevel)
|
||||
{
|
||||
if (!this.cpu.getIF()) {
|
||||
this.println("interrupts disabled (use rif=1 to enable)");
|
||||
return false;
|
||||
}
|
||||
var nLevel = this.parseExpression(sLevel);
|
||||
if (nLevel == null) return false;
|
||||
this.println("requesting interrupt level " + nLevel);
|
||||
this.cpu.requestINTR(nLevel);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* doVar(sCmd)
|
||||
*
|
||||
|
|
@ -4686,6 +4707,12 @@ if (DEBUGGER) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
if (asArgs[0] == "int") {
|
||||
if (!this.doInt(asArgs[1])) {
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.doInput(asArgs[1]);
|
||||
break;
|
||||
case 'k':
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue