B. Emulated Devices
by
Douglas W. Jones
|
B.1. The Keyboard
B.1.1. Keyboard Data Register, FF10000016
B.1.2. Keyboard Status Register, FF10000416
B.1.3. Keyboard Example
B.2. The Display
B.2.1. Display Rows and Columns, FF00000016
B.2.2. Display Area, FF00010016
Programs on the Hawk communicate with devices through device interface registers. Each device interface register appears, to software, as if it is a word in the memory address space. Unlike other memory addresses, the contents of a device interface register may change in direct response to events in the outside world, and changes made by software may cause the associate device to take action.
The following devices are supported by the Hawk emulator; if someone builds a physical Hawk, it need not support these devices.
; keyboard interface register memory addresses KBDDATA =: #FF100000 ; data KBDSTAT =: #FF100004 ; status ; bits in KBSTAT with defined meanings KBDRD =: #01 ; ready KBDER =: #40 ; error KBDIE =: #80 ; interrupt enable
This interface is somewhat simpler than but based on the interfaces offered by several USART chips, those chip designs typically include from 8 to 16 interface registers.
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
unused | data |
The keyboard data register KBDDATA holds the most recent key pressed on the keyboard, encoded as an 8-bit ASCII value. The contents of this register will remain unchanged until some other key is pressed.
Load instructions moving data from KBDDATA get the most recent character and, as a side effect, clear the keyboard ready bit (KBDRD) in the keyboard status register (KBDSTAT), preparing the interface to read another character.
Store instructions to KBDDATA have no effect.
For bi-directional devices such as asynchronous communications lines, storing to KBDDATA could be used to send data to the device. For devices supporting large character sets, this register could be widened to support more than 8-bits of data.
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
unused | ie | er | unused | rd |
The keyboard status and control register KBDSTAT contains the following fields:
The most rudimentary way to read from the keyboard involves polling the KBDRD bit waiting for a keypress and then reading KBDDATA, as in the following example:
; JSR R1,GETCHAR gets one character from the keyboard into R3 GETCHAR: LIW R4,KBDSTAT ; set up to poll keyboard status POLL: ; polling loop LOADS R3,R4 ; get keyboard status BITTST R3,KBDRD ; test ready bit BBR POLL ; loop while not ready LIW R4,KBDDATA ; set up to read keyboard data LOADS R3,R3 ; read it JUMPS R1 ; return
In general, the above approach to keyboard input should be avoided in all but the most rudimentary applications; instead, a keyboard interrupt service routine should be used and the processor should be run with interrupts enabled. Typically, the interrupt service routine will place data into a FIFO queue where application software can pick out characters as needed.
; the range of addresses used for the display interface DSPBASE =: #FF000000 DSPLIM =: #FF0FFFFF ; addresses in the above range DSPROWS =: #FF000000 ; number of rows on the display DSPCOLS =: #FF000004 ; number of columns per row DSPAREA =: #FF000100 ; base of rows x cols array
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
unused | rows | ||||||||||||||||||||||||||||||
unused | columns |
The two consecutive words at the start of the display interface area hold the number of rows (DSPROWS) and columns (DSPCOLS) on the display. Using the Hawk emulator, these are constants set by the emulated display hardware to describe the dimensions of the display window. These dimensions are fixed at the time the emulator is launched.
Because the emulator's display interface is limited to 1 megabyte of memory, between DSPBASE and DSPLIM, the product of rows and columns must not exceed FFF0016.
For some potential display interfaces, these could be variables set by the software. It is also possible adding additional control variables after rows and columns to control display mode (pixels versus text), color mapping and the memory location of the display buffer.
The display area is a block of video RAM holding rows × columns bytes of display data. The display screen is refreshed from this area on a continuous basis.
The area is constructed as an array of rows consecutive blocks of bytes, where each block represents one row of the display. Each row consists of columns of bytes, each representing one displayed character or pixel.
Under the Hawk emulator, the display uses monospace text, where each byte holds one ASCII character. It is possible to approximate limited monochrome pixel graphics under the emulator by launching a terminal window with a very small font and using characters with different numbers of pixels set to represent a range of gray levels. Consider, for example, using " .:+oIZW" to get 8 levels; of course, the effective grey level will be a function of the font used.
It is conceivable that some later version of the display interface could support pixel-based graphics.