Various simulators: Set line endings to CRLF for consistency, remove stray tabs

Project standard source code has tabs converted to spaces and CRLF line
endings.

Other text files have CRLF line endings.
This commit is contained in:
Mark Pizzolato 2023-03-11 13:20:50 -10:00 committed by Paul Koning
parent f1f8cf9cb1
commit decbe5b76b
53 changed files with 39065 additions and 39065 deletions

View file

@ -1183,7 +1183,7 @@ static void ha_cmd(uint8 op, uint8 subdev, uint32 addr, int32 len, t_bool expres
void ha_ctrl(uint8 tc) void ha_ctrl(uint8 tc)
{ {
volatile t_bool txn_done; volatile t_bool txn_done;
uint32 i, j; uint32 i, j;
uint32 plen, ha_ptr; uint32 plen, ha_ptr;
uint32 in_len, out_len; uint32 in_len, out_len;
uint8 lu, status; uint8 lu, status;

View file

@ -1771,12 +1771,12 @@ static int32 simh_out(const int32 port, const int32 data) {
if (genInterruptPos == 0) { if (genInterruptPos == 0) {
genInterruptVec = data; genInterruptVec = data;
genInterruptPos = 1; genInterruptPos = 1;
sim_printf("genInterruptVec=%d genInterruptPos=%d\n", genInterruptVec, genInterruptPos); sim_printf("genInterruptVec=%d genInterruptPos=%d\n", genInterruptVec, genInterruptPos);
} else { } else {
vectorInterrupt |= (1 << genInterruptVec); vectorInterrupt |= (1 << genInterruptVec);
dataBus[genInterruptVec] = data; dataBus[genInterruptVec] = data;
genInterruptPos = lastCommand = 0; genInterruptPos = lastCommand = 0;
sim_printf("genInterruptVec=%d vectorInterrupt=%X dataBus=%02X genInterruptPos=%d\n", genInterruptVec, vectorInterrupt, data, genInterruptPos); sim_printf("genInterruptVec=%d vectorInterrupt=%X dataBus=%02X genInterruptPos=%d\n", genInterruptVec, vectorInterrupt, data, genInterruptPos);
} }
break; break;
case setFCBAddressCmd: case setFCBAddressCmd:

View file

@ -1,313 +1,313 @@
Example M68k Program Example M68k Program
==================== ====================
As an example, I'll build an imaginary hardware platform. As an example, I'll build an imaginary hardware platform.
The system is fairly simple, comprising a 68000, an input device, an output The system is fairly simple, comprising a 68000, an input device, an output
device, a non-maskable-interrupt device, and an interrupt controller. device, a non-maskable-interrupt device, and an interrupt controller.
The input device receives input from the user and asserts its interrupt The input device receives input from the user and asserts its interrupt
request line until its value is read. Reading from the input device's request line until its value is read. Reading from the input device's
memory-mapped port will both clear its interrupt request and read an ASCII memory-mapped port will both clear its interrupt request and read an ASCII
representation (8 bits) of what the user entered. representation (8 bits) of what the user entered.
The output device reads value when it is selected through its memory-mapped The output device reads value when it is selected through its memory-mapped
port and outputs it to a display. The value it reads will be interpreted as port and outputs it to a display. The value it reads will be interpreted as
an ASCII value and output to the display. The output device is fairly slow an ASCII value and output to the display. The output device is fairly slow
(it can only process 1 byte per second), and so it asserts its interrupt (it can only process 1 byte per second), and so it asserts its interrupt
request line when it is ready to receive a byte. Writing to the output device request line when it is ready to receive a byte. Writing to the output device
sends a byte to it. If the output device is not ready, the write is ignored. sends a byte to it. If the output device is not ready, the write is ignored.
Reading from the output device returns 0 and clears its interrupt request line Reading from the output device returns 0 and clears its interrupt request line
until another byte is written to it and 1 second elapses. until another byte is written to it and 1 second elapses.
The non-maskable-interrupt (NMI) device, as can be surmised from the name, The non-maskable-interrupt (NMI) device, as can be surmised from the name,
generates a non-maskable-interrupt. This is connected to some kind of external generates a non-maskable-interrupt. This is connected to some kind of external
switch that the user can push to generate a NMI. switch that the user can push to generate a NMI.
Since there are 3 devices interrupting the CPU, an interrupt controller is Since there are 3 devices interrupting the CPU, an interrupt controller is
needed. The interrupt controller takes 7 inputs and encodes the highest needed. The interrupt controller takes 7 inputs and encodes the highest
priority asserted line on the 3 output pins. the input device is wired to IN2 priority asserted line on the 3 output pins. the input device is wired to IN2
and the output device is wired to IN1 on the controller. The NMI device is and the output device is wired to IN1 on the controller. The NMI device is
wired to IN7 and all the other inputs are wired low. wired to IN7 and all the other inputs are wired low.
The bus is also connected to a 1K ROM and a 256 byte RAM. The bus is also connected to a 1K ROM and a 256 byte RAM.
Beware: This platform places ROM and RAM in the same address range and uses Beware: This platform places ROM and RAM in the same address range and uses
the FC pins to select the correct address space! the FC pins to select the correct address space!
(You didn't expect me to make it easy, did you? =) (You didn't expect me to make it easy, did you? =)
Schematic Schematic
--------- ---------
NMI TIED NMI TIED
SWITCH LOW SWITCH LOW
| | | |
| +-+-+-+ | +-+-+-+
| | | | | +------------------------------------------------+ | | | | | +------------------------------------------------+
| | | | | | +------------------------------------+ | | | | | | | +------------------------------------+ |
| | | | | | | | | | | | | | | | | |
+-------------+ | | +-------------+ | |
|7 6 5 4 3 2 1| | | |7 6 5 4 3 2 1| | |
| | | | | | | |
| INT CONTRLR | | | | INT CONTRLR | | |
| | | | | | | |
|i i i | | | |i i i | | |
|2 1 0 | | | |2 1 0 | | |
+-------------+ | | +-------------+ | |
| | | | | | | | | |
| | | +--------------------------------+--+ | | | | | +--------------------------------+--+ | |
o o o | | | | | o o o | | | | |
+--------------+ +-------+ +----------+ +---------+ +----------+ +--------------+ +-------+ +----------+ +---------+ +----------+
| I I I a | | | | | | r a i | | i | | I I I a | | | | | | r a i | | i |
| 2 1 0 23 | | | | | | e c | | | | 2 1 0 23 | | | | | | e c | | |
| | | | | | | a k | | | | | | | | | | a k | | |
| | | | | | | d | | | | | | | | | | d | | |
| | | | | | | | | | | | | | | | | | | |
| M68000 | | ROM | | RAM | | IN | | OUT | | M68000 | | ROM | | RAM | | IN | | OUT |
| | | | | | | | | | | | | | | | | | | |
| a9|--|a9 |--| |--| |--| | | a9|--|a9 |--| |--| |--| |
| a8|--|a8 |--| |--| |--| | | a8|--|a8 |--| |--| |--| |
| a7|--|a7 |--|a7 |--| |--| | | a7|--|a7 |--|a7 |--| |--| |
| a6|--|a6 |--|a6 |--| |--| | | a6|--|a6 |--|a6 |--| |--| |
| a5|--|a5 |--|a5 |--| |--| | | a5|--|a5 |--|a5 |--| |--| |
| a4|--|a4 |--|a4 |--| |--| | | a4|--|a4 |--|a4 |--| |--| |
| a3|--|a3 |--|a3 |--| |--| | | a3|--|a3 |--|a3 |--| |--| |
| a2|--|a2 |--|a2 |--| |--| | | a2|--|a2 |--|a2 |--| |--| |
| a1|--|a1 |--|a1 |--| |--| | | a1|--|a1 |--|a1 |--| |--| |
| a0|--|a0 |--|a0 |--| |--| | | a0|--|a0 |--|a0 |--| |--| |
| | | | | | | | | | | | | | | | | | | |
| d15|--|d15 |--|d15 |--| |--| | | d15|--|d15 |--|d15 |--| |--| |
| d14|--|d14 |--|d14 |--| |--| | | d14|--|d14 |--|d14 |--| |--| |
| d13|--|d13 |--|d13 |--| |--| | | d13|--|d13 |--|d13 |--| |--| |
| d12|--|d12 |--|d12 |--| |--| | | d12|--|d12 |--|d12 |--| |--| |
| d11|--|d11 |--|d11 |--| |--| | | d11|--|d11 |--|d11 |--| |--| |
| d10|--|d10 |--|d10 |--| |--| | | d10|--|d10 |--|d10 |--| |--| |
| d9|--|d9 |--|d9 |--| |--| | | d9|--|d9 |--|d9 |--| |--| |
| d8|--|d8 |--|d8 |--| |--| | | d8|--|d8 |--|d8 |--| |--| |
| d7|--|d7 |--|d7 |--|d7 |--|d7 | | d7|--|d7 |--|d7 |--|d7 |--|d7 |
| d6|--|d6 |--|d6 |--|d6 |--|d6 | | d6|--|d6 |--|d6 |--|d6 |--|d6 |
| d5|--|d5 |--|d5 |--|d5 |--|d5 | | d5|--|d5 |--|d5 |--|d5 |--|d5 |
| d4|--|d4 |--|d4 |--|d4 |--|d4 | | d4|--|d4 |--|d4 |--|d4 |--|d4 |
| d3|--|d3 |--|d3 |--|d3 |--|d3 | | d3|--|d3 |--|d3 |--|d3 |--|d3 |
| d2|--|d2 |--|d2 |--|d2 |--|d2 | | d2|--|d2 |--|d2 |--|d2 |--|d2 |
| d1|--|d1 |--|d1 |--|d1 |--|d1 w | | d1|--|d1 |--|d1 |--|d1 |--|d1 w |
| d0|--|d0 |--|d0 |--|d0 |--|d0 r | | d0|--|d0 |--|d0 |--|d0 |--|d0 r |
| | | | | | | | | i a | | | | | | | | | | i a |
| a F F F | | | | | | | | t c | | a F F F | | | | | | | | t c |
|22 rW 2 1 0 | | cs | | cs rW | | | | e k | |22 rW 2 1 0 | | cs | | cs rW | | | | e k |
+--------------+ +-------+ +----------+ +---------+ +----------+ +--------------+ +-------+ +----------+ +---------+ +----------+
| | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | |
| | | | | +-------+ +-----+ | +---+ | | | | | | +-------+ +-----+ | +---+ |
| | | | | | IC1 | | IC2 | | |AND| | | | | | | | IC1 | | IC2 | | |AND| |
| | | | | |a b c d| |a b c| | +---+ | | | | | | |a b c d| |a b c| | +---+ |
| | | | | +-------+ +-----+ | | | | | | | | | +-------+ +-----+ | | | |
| | | | | | | | | | | | | | +--+ | | | | | | | | | | | | | | +--+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +-----)-)-+-)----)-)-+ | | | | | | | +-----)-)-+-)----)-)-+ | | |
| | | +-------)-+---)----)-+ | | | | | | +-------)-+---)----)-+ | | |
| | +---------+-----)----+ | | | | | +---------+-----)----+ | | |
| | | | | | | | | | | |
| +------------------+-----------+----------------------+ | | +------------------+-----------+----------------------+ |
| | | |
+-----------------------------------------------------------+ +-----------------------------------------------------------+
IC1: output=1 if a=0 and b=1 and c=0 and d=0 IC1: output=1 if a=0 and b=1 and c=0 and d=0
IC2: output=1 if a=0 and b=0 and c=1 IC2: output=1 if a=0 and b=0 and c=1
Program Listing (program.bin) Program Listing (program.bin)
----------------------------- -----------------------------
``` ```
INPUT_ADDRESS equ $800000 INPUT_ADDRESS equ $800000
OUTPUT_ADDRESS equ $400000 OUTPUT_ADDRESS equ $400000
CIRCULAR_BUFFER equ $c0 CIRCULAR_BUFFER equ $c0
CAN_OUTPUT equ $d0 CAN_OUTPUT equ $d0
STACK_AREA equ $100 STACK_AREA equ $100
vector_table: vector_table:
00000000 0000 0100 dc.l STACK_AREA * 0: SP 00000000 0000 0100 dc.l STACK_AREA * 0: SP
00000004 0000 00c0 dc.l init * 1: PC 00000004 0000 00c0 dc.l init * 1: PC
00000008 0000 0148 dc.l unhandled_exception * 2: bus error 00000008 0000 0148 dc.l unhandled_exception * 2: bus error
0000000c 0000 0148 dc.l unhandled_exception * 3: address error 0000000c 0000 0148 dc.l unhandled_exception * 3: address error
00000010 0000 0148 dc.l unhandled_exception * 4: illegal instruction 00000010 0000 0148 dc.l unhandled_exception * 4: illegal instruction
00000014 0000 0148 dc.l unhandled_exception * 5: zero divide 00000014 0000 0148 dc.l unhandled_exception * 5: zero divide
00000018 0000 0148 dc.l unhandled_exception * 6: chk 00000018 0000 0148 dc.l unhandled_exception * 6: chk
0000001c 0000 0148 dc.l unhandled_exception * 7: trapv 0000001c 0000 0148 dc.l unhandled_exception * 7: trapv
00000020 0000 0148 dc.l unhandled_exception * 8: privilege violation 00000020 0000 0148 dc.l unhandled_exception * 8: privilege violation
00000024 0000 0148 dc.l unhandled_exception * 9: trace 00000024 0000 0148 dc.l unhandled_exception * 9: trace
00000028 0000 0148 dc.l unhandled_exception * 10: 1010 00000028 0000 0148 dc.l unhandled_exception * 10: 1010
0000002c 0000 0148 dc.l unhandled_exception * 11: 1111 0000002c 0000 0148 dc.l unhandled_exception * 11: 1111
00000030 0000 0148 dc.l unhandled_exception * 12: - 00000030 0000 0148 dc.l unhandled_exception * 12: -
00000034 0000 0148 dc.l unhandled_exception * 13: - 00000034 0000 0148 dc.l unhandled_exception * 13: -
00000038 0000 0148 dc.l unhandled_exception * 14: - 00000038 0000 0148 dc.l unhandled_exception * 14: -
0000003c 0000 0148 dc.l unhandled_exception * 15: uninitialized interrupt 0000003c 0000 0148 dc.l unhandled_exception * 15: uninitialized interrupt
00000040 0000 0148 dc.l unhandled_exception * 16: - 00000040 0000 0148 dc.l unhandled_exception * 16: -
00000044 0000 0148 dc.l unhandled_exception * 17: - 00000044 0000 0148 dc.l unhandled_exception * 17: -
00000048 0000 0148 dc.l unhandled_exception * 18: - 00000048 0000 0148 dc.l unhandled_exception * 18: -
0000004c 0000 0148 dc.l unhandled_exception * 19: - 0000004c 0000 0148 dc.l unhandled_exception * 19: -
00000050 0000 0148 dc.l unhandled_exception * 20: - 00000050 0000 0148 dc.l unhandled_exception * 20: -
00000054 0000 0148 dc.l unhandled_exception * 21: - 00000054 0000 0148 dc.l unhandled_exception * 21: -
00000058 0000 0148 dc.l unhandled_exception * 22: - 00000058 0000 0148 dc.l unhandled_exception * 22: -
0000005c 0000 0148 dc.l unhandled_exception * 23: - 0000005c 0000 0148 dc.l unhandled_exception * 23: -
00000060 0000 0148 dc.l unhandled_exception * 24: spurious interrupt 00000060 0000 0148 dc.l unhandled_exception * 24: spurious interrupt
00000064 0000 0136 dc.l output_ready * 25: l1 irq 00000064 0000 0136 dc.l output_ready * 25: l1 irq
00000068 0000 010e dc.l input_ready * 26: l2 irq 00000068 0000 010e dc.l input_ready * 26: l2 irq
0000006c 0000 0148 dc.l unhandled_exception * 27: l3 irq 0000006c 0000 0148 dc.l unhandled_exception * 27: l3 irq
00000070 0000 0148 dc.l unhandled_exception * 28: l4 irq 00000070 0000 0148 dc.l unhandled_exception * 28: l4 irq
00000074 0000 0148 dc.l unhandled_exception * 29: l5 irq 00000074 0000 0148 dc.l unhandled_exception * 29: l5 irq
00000078 0000 0148 dc.l unhandled_exception * 30: l6 irq 00000078 0000 0148 dc.l unhandled_exception * 30: l6 irq
0000007c 0000 014e dc.l nmi * 31: l7 irq 0000007c 0000 014e dc.l nmi * 31: l7 irq
00000080 0000 0148 dc.l unhandled_exception * 32: trap 0 00000080 0000 0148 dc.l unhandled_exception * 32: trap 0
00000084 0000 0148 dc.l unhandled_exception * 33: trap 1 00000084 0000 0148 dc.l unhandled_exception * 33: trap 1
00000088 0000 0148 dc.l unhandled_exception * 34: trap 2 00000088 0000 0148 dc.l unhandled_exception * 34: trap 2
0000008c 0000 0148 dc.l unhandled_exception * 35: trap 3 0000008c 0000 0148 dc.l unhandled_exception * 35: trap 3
00000090 0000 0148 dc.l unhandled_exception * 36: trap 4 00000090 0000 0148 dc.l unhandled_exception * 36: trap 4
00000094 0000 0148 dc.l unhandled_exception * 37: trap 5 00000094 0000 0148 dc.l unhandled_exception * 37: trap 5
00000098 0000 0148 dc.l unhandled_exception * 38: trap 6 00000098 0000 0148 dc.l unhandled_exception * 38: trap 6
0000009c 0000 0148 dc.l unhandled_exception * 39: trap 7 0000009c 0000 0148 dc.l unhandled_exception * 39: trap 7
000000a0 0000 0148 dc.l unhandled_exception * 40: trap 8 000000a0 0000 0148 dc.l unhandled_exception * 40: trap 8
000000a4 0000 0148 dc.l unhandled_exception * 41: trap 9 000000a4 0000 0148 dc.l unhandled_exception * 41: trap 9
000000a8 0000 0148 dc.l unhandled_exception * 42: trap 10 000000a8 0000 0148 dc.l unhandled_exception * 42: trap 10
000000ac 0000 0148 dc.l unhandled_exception * 43: trap 11 000000ac 0000 0148 dc.l unhandled_exception * 43: trap 11
000000b0 0000 0148 dc.l unhandled_exception * 44: trap 12 000000b0 0000 0148 dc.l unhandled_exception * 44: trap 12
000000b4 0000 0148 dc.l unhandled_exception * 45: trap 13 000000b4 0000 0148 dc.l unhandled_exception * 45: trap 13
000000b8 0000 0148 dc.l unhandled_exception * 46: trap 14 000000b8 0000 0148 dc.l unhandled_exception * 46: trap 14
000000bc 0000 0148 dc.l unhandled_exception * 47: trap 15 000000bc 0000 0148 dc.l unhandled_exception * 47: trap 15
* This is the end of the useful part of the table. * This is the end of the useful part of the table.
* We will now do the Capcom thing and put code starting at $c0. * We will now do the Capcom thing and put code starting at $c0.
init: init:
* Copy the exception vector table to RAM. * Copy the exception vector table to RAM.
000000c0 227c 0000 0000 move.l #0, a1 * a1 is RAM index 000000c0 227c 0000 0000 move.l #0, a1 * a1 is RAM index
000000c6 303c 002f move.w #47, d0 * d0 is counter (48 vectors) 000000c6 303c 002f move.w #47, d0 * d0 is counter (48 vectors)
000000ca 41fa 0006 lea.l (copy_table,PC), a0 * a0 is scratch 000000ca 41fa 0006 lea.l (copy_table,PC), a0 * a0 is scratch
000000ce 2208 move.l a0, d1 * d1 is ROM index 000000ce 2208 move.l a0, d1 * d1 is ROM index
000000d0 4481 neg.l d1 000000d0 4481 neg.l d1
copy_table: copy_table:
000000d2 22fb 18fe dc.l $22fb18fe * stoopid as68k generates 020 code here 000000d2 22fb 18fe dc.l $22fb18fe * stoopid as68k generates 020 code here
* move.l (copy_table,PC,d1.l), (a1)+ * move.l (copy_table,PC,d1.l), (a1)+
000000d6 5841 addq #4, d1 000000d6 5841 addq #4, d1
000000d8 51c8 fff8 dbf d0, copy_table 000000d8 51c8 fff8 dbf d0, copy_table
main_init: main_init:
* Initialize main program * Initialize main program
000000dc 11fc 0000 00d0 move.b #0, CAN_OUTPUT 000000dc 11fc 0000 00d0 move.b #0, CAN_OUTPUT
000000e2 4df8 00c0 lea.l CIRCULAR_BUFFER, a6 000000e2 4df8 00c0 lea.l CIRCULAR_BUFFER, a6
000000e6 7c00 moveq #0, d6 * output buffer ptr 000000e6 7c00 moveq #0, d6 * output buffer ptr
000000e8 7e00 moveq #0, d7 * input buffer ptr 000000e8 7e00 moveq #0, d7 * input buffer ptr
000000ea 027c f8ff andi #$f8ff, SR * clear interrupt mask 000000ea 027c f8ff andi #$f8ff, SR * clear interrupt mask
main: main:
* Main program * Main program
000000ee 4a38 00d0 tst.b CAN_OUTPUT * can we output? 000000ee 4a38 00d0 tst.b CAN_OUTPUT * can we output?
000000f2 67fa beq main 000000f2 67fa beq main
000000f4 be06 cmp.b d6, d7 * is there data? 000000f4 be06 cmp.b d6, d7 * is there data?
000000f6 67f6 beq main 000000f6 67f6 beq main
000000f8 11fc 0000 00d0 move.b #0, CAN_OUTPUT 000000f8 11fc 0000 00d0 move.b #0, CAN_OUTPUT
000000fe 13f6 6000 0040 move.b (0,a6,d6.w), OUTPUT_ADDRESS * write data 000000fe 13f6 6000 0040 move.b (0,a6,d6.w), OUTPUT_ADDRESS * write data
0000 0000
00000106 5246 addq #1, d6 00000106 5246 addq #1, d6
00000108 0206 000f andi.b #15, d6 * update circular buffer 00000108 0206 000f andi.b #15, d6 * update circular buffer
0000010c 60e0 bra main 0000010c 60e0 bra main
input_ready: input_ready:
0000010e 2f00 move.l d0, -(a7) 0000010e 2f00 move.l d0, -(a7)
00000110 2f01 move.l d1, -(a7) 00000110 2f01 move.l d1, -(a7)
00000112 1239 0080 0000 move.b INPUT_ADDRESS, d1 * read data 00000112 1239 0080 0000 move.b INPUT_ADDRESS, d1 * read data
00000118 1007 move.b d7, d0 * check if buffer full 00000118 1007 move.b d7, d0 * check if buffer full
0000011a 5240 addq #1, d0 0000011a 5240 addq #1, d0
0000011c 0200 000f andi.b #15, d0 0000011c 0200 000f andi.b #15, d0
00000120 bc00 cmp.b d0, d6 00000120 bc00 cmp.b d0, d6
00000122 6700 000c beq input_ready_quit * throw away if full 00000122 6700 000c beq input_ready_quit * throw away if full
00000126 1d81 7000 move.b d1, (0,a6,d7.w) * store the data 00000126 1d81 7000 move.b d1, (0,a6,d7.w) * store the data
0000012a 5247 addq #1, d7 0000012a 5247 addq #1, d7
0000012c 0207 000f andi.b #15, d7 * update circular buffer 0000012c 0207 000f andi.b #15, d7 * update circular buffer
input_ready_quit: input_ready_quit:
00000130 221f move.l (a7)+, d1 00000130 221f move.l (a7)+, d1
00000132 201f move.l (a7)+, d0 00000132 201f move.l (a7)+, d0
00000134 4e73 rte 00000134 4e73 rte
output_ready: output_ready:
00000136 2f00 move.l d0, -(a7) 00000136 2f00 move.l d0, -(a7)
00000138 11fc 0001 00d0 move.b #1, CAN_OUTPUT 00000138 11fc 0001 00d0 move.b #1, CAN_OUTPUT
0000013e 1039 0040 0000 move.b OUTPUT_ADDRESS, d0 * acknowledge the interrupt 0000013e 1039 0040 0000 move.b OUTPUT_ADDRESS, d0 * acknowledge the interrupt
00000144 201f move.l (a7)+, d0 00000144 201f move.l (a7)+, d0
00000146 4e73 rte 00000146 4e73 rte
unhandled_exception: unhandled_exception:
00000148 4e72 2700 stop #$2700 * wait for NMI 00000148 4e72 2700 stop #$2700 * wait for NMI
0000014c 60fa bra unhandled_exception * shouldn't get here 0000014c 60fa bra unhandled_exception * shouldn't get here
nmi: nmi:
* perform a soft reset * perform a soft reset
0000014e 46fc 2700 move #$2700, SR * set status register 0000014e 46fc 2700 move #$2700, SR * set status register
00000152 2e7a feac move.l (vector_table,PC), a7 * reset stack pointer 00000152 2e7a feac move.l (vector_table,PC), a7 * reset stack pointer
00000156 4e70 reset * reset peripherals 00000156 4e70 reset * reset peripherals
00000158 4efa feaa jmp (vector_table+4,PC) * reset program counter 00000158 4efa feaa jmp (vector_table+4,PC) * reset program counter
END END
``` ```
Compiling the example host environment Compiling the example host environment
-------------------------------------- --------------------------------------
### DOS ### DOS
`osd_dos.c` `osd_dos.c`
This code was written a long time ago, in another era when DOS environments This code was written a long time ago, in another era when DOS environments
were still a thing. Thus, the primary interface was designed around the DOS were still a thing. Thus, the primary interface was designed around the DOS
console, which allowed easy control over keyboard input and console echo. If console, which allowed easy control over keyboard input and console echo. If
you still have such an environment, compilers such as mingw or djgpp are you still have such an environment, compilers such as mingw or djgpp are
enough to compile it. enough to compile it.
### Linux ### Linux
`osd_linux.c` `osd_linux.c`
There's now a Linux interface but it's very **very** basic. The terminal echoes There's now a Linux interface but it's very **very** basic. The terminal echoes
back everything you type immediately, which makes the output look weird as the back everything you type immediately, which makes the output look weird as the
program output mixes with the terminal echo. program output mixes with the terminal echo.
Unfortunately, I don't have enough free time to sort through the Unfortunately, I don't have enough free time to sort through the
termios/ncurses minefield to make it behave better. If you happen to know how termios/ncurses minefield to make it behave better. If you happen to know how
to do this sort of thing, please help out by submitting a PR! to do this sort of thing, please help out by submitting a PR!
### Other Platforms ### Other Platforms
You'll need to make an `osd_xyz.c` for your particular platform to implement You'll need to make an `osd_xyz.c` for your particular platform to implement
`osd_get_key()`, and update the Makefile to handle your particular environment. `osd_get_key()`, and update the Makefile to handle your particular environment.
### Building and running ### Building and running
You'll need a C compiler. GCC or Clang should work fine. MSVC will require you You'll need a C compiler. GCC or Clang should work fine. MSVC will require you
to set up a project (use the makefile as a guide). to set up a project (use the makefile as a guide).
- Type `make` - Type `make`
- Type `./sim program.bin` - Type `./sim program.bin`
- Interact with program.bin using the keyboard. - Interact with program.bin using the keyboard.
#### Keys: #### Keys:
ESC - quits the simulator ESC - quits the simulator
~ - generates an NMI interrupt ~ - generates an NMI interrupt
Any other key - Genearate input for the input device Any other key - Genearate input for the input device
### Note ### Note
I've cheated a bit in the emulation. There is no speed control to set the I've cheated a bit in the emulation. There is no speed control to set the
speed the CPU runs at; it simply runs as fast as your processor can run it. speed the CPU runs at; it simply runs as fast as your processor can run it.
To add speed control, you will need a high-precision timestamp function To add speed control, you will need a high-precision timestamp function
(like the RDTSC instruction for newer Pentium CPUs) and a bit of arithmetic (like the RDTSC instruction for newer Pentium CPUs) and a bit of arithmetic
to make the cycles argument for m68k_execute(). I'll leave that as an to make the cycles argument for m68k_execute(). I'll leave that as an
excercise to the reader. excercise to the reader.

View file

@ -1,78 +1,78 @@
MAME note: this package is derived from the following original SoftFloat MAME note: this package is derived from the following original SoftFloat
package and has been "re-packaged" to work with MAME's conventions and package and has been "re-packaged" to work with MAME's conventions and
build system. The source files come from bits64/ and bits64/templates build system. The source files come from bits64/ and bits64/templates
in the original distribution as MAME requires a compiler with a 64-bit in the original distribution as MAME requires a compiler with a 64-bit
integer type. integer type.
Package Overview for SoftFloat Release 2b Package Overview for SoftFloat Release 2b
John R. Hauser John R. Hauser
2002 May 27 2002 May 27
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
Overview Overview
SoftFloat is a software implementation of floating-point that conforms to SoftFloat is a software implementation of floating-point that conforms to
the IEC/IEEE Standard for Binary Floating-Point Arithmetic. SoftFloat is the IEC/IEEE Standard for Binary Floating-Point Arithmetic. SoftFloat is
distributed in the form of C source code. Compiling the SoftFloat sources distributed in the form of C source code. Compiling the SoftFloat sources
generates two things: generates two things:
-- A SoftFloat object file (typically `softfloat.o') containing the complete -- A SoftFloat object file (typically `softfloat.o') containing the complete
set of IEC/IEEE floating-point routines. set of IEC/IEEE floating-point routines.
-- A `timesoftfloat' program for evaluating the speed of the SoftFloat -- A `timesoftfloat' program for evaluating the speed of the SoftFloat
routines. (The SoftFloat module is linked into this program.) routines. (The SoftFloat module is linked into this program.)
The SoftFloat package is documented in four text files: The SoftFloat package is documented in four text files:
SoftFloat.txt Documentation for using the SoftFloat functions. SoftFloat.txt Documentation for using the SoftFloat functions.
SoftFloat-source.txt Documentation for compiling SoftFloat. SoftFloat-source.txt Documentation for compiling SoftFloat.
SoftFloat-history.txt History of major changes to SoftFloat. SoftFloat-history.txt History of major changes to SoftFloat.
timesoftfloat.txt Documentation for using `timesoftfloat'. timesoftfloat.txt Documentation for using `timesoftfloat'.
Other files in the package comprise the source code for SoftFloat. Other files in the package comprise the source code for SoftFloat.
Please be aware that some work is involved in porting this software to other Please be aware that some work is involved in porting this software to other
targets. It is not just a matter of getting `make' to complete without targets. It is not just a matter of getting `make' to complete without
error messages. I would have written the code that way if I could, but error messages. I would have written the code that way if I could, but
there are fundamental differences between systems that can't be hidden. there are fundamental differences between systems that can't be hidden.
You should not attempt to compile SoftFloat without first reading both You should not attempt to compile SoftFloat without first reading both
`SoftFloat.txt' and `SoftFloat-source.txt'. `SoftFloat.txt' and `SoftFloat-source.txt'.
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
Legal Notice Legal Notice
SoftFloat was written by me, John R. Hauser. This work was made possible in SoftFloat was written by me, John R. Hauser. This work was made possible in
part by the International Computer Science Institute, located at Suite 600, part by the International Computer Science Institute, located at Suite 600,
1947 Center Street, Berkeley, California 94704. Funding was partially 1947 Center Street, Berkeley, California 94704. Funding was partially
provided by the National Science Foundation under grant MIP-9311980. The provided by the National Science Foundation under grant MIP-9311980. The
original version of this code was written as part of a project to build original version of this code was written as part of a project to build
a fixed-point vector processor in collaboration with the University of a fixed-point vector processor in collaboration with the University of
California at Berkeley, overseen by Profs. Nelson Morgan and John Wawrzynek. California at Berkeley, overseen by Profs. Nelson Morgan and John Wawrzynek.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL
LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO
FURTHERMORE EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER FURTHERMORE EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER
SCIENCE INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, SCIENCE INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES,
COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE
SOFTWARE. SOFTWARE.
Derivative works are acceptable, even for commercial purposes, provided Derivative works are acceptable, even for commercial purposes, provided
that the minimal documentation requirements stated in the source code are that the minimal documentation requirements stated in the source code are
satisfied. satisfied.
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
Contact Information Contact Information
At the time of this writing, the most up-to-date information about At the time of this writing, the most up-to-date information about
SoftFloat and the latest release can be found at the Web page `http:// SoftFloat and the latest release can be found at the Web page `http://
www.cs.berkeley.edu/~jhauser/arithmetic/SoftFloat.html'. www.cs.berkeley.edu/~jhauser/arithmetic/SoftFloat.html'.

View file

@ -1,61 +1,61 @@
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined. | One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef LSB_FIRST #ifdef LSB_FIRST
#define LITTLEENDIAN #define LITTLEENDIAN
#else #else
#define BIGENDIAN #define BIGENDIAN
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The macro `BITS64' can be defined to indicate that 64-bit integer types are | The macro `BITS64' can be defined to indicate that 64-bit integer types are
| supported by the compiler. | supported by the compiler.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define BITS64 #define BITS64
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Each of the following `typedef's defines the most convenient type that holds | Each of the following `typedef's defines the most convenient type that holds
| integers of at least as many bits as specified. For example, `uint8' should | integers of at least as many bits as specified. For example, `uint8' should
| be the most convenient type that can hold unsigned integers of as many as | be the most convenient type that can hold unsigned integers of as many as
| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most | 8 bits. The `flag' type must be able to hold either a 0 or 1. For most
| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed | implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
| to the same as `int'. | to the same as `int'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
typedef sint8 flag; typedef sint8 flag;
typedef sint8 int8; typedef sint8 int8;
typedef sint16 int16; typedef sint16 int16;
typedef sint32 int32; typedef sint32 int32;
typedef sint64 int64; typedef sint64 int64;
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Each of the following `typedef's defines a type that holds integers | Each of the following `typedef's defines a type that holds integers
| of _exactly_ the number of bits specified. For instance, for most | of _exactly_ the number of bits specified. For instance, for most
| implementation of C, `bits16' and `sbits16' should be `typedef'ed to | implementation of C, `bits16' and `sbits16' should be `typedef'ed to
| `unsigned short int' and `signed short int' (or `short int'), respectively. | `unsigned short int' and `signed short int' (or `short int'), respectively.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
typedef uint8 bits8; typedef uint8 bits8;
typedef sint8 sbits8; typedef sint8 sbits8;
typedef uint16 bits16; typedef uint16 bits16;
typedef sint16 sbits16; typedef sint16 sbits16;
typedef uint32 bits32; typedef uint32 bits32;
typedef sint32 sbits32; typedef sint32 sbits32;
typedef uint64 bits64; typedef uint64 bits64;
typedef sint64 sbits64; typedef sint64 sbits64;
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The `LIT64' macro takes as its argument a textual integer literal and | The `LIT64' macro takes as its argument a textual integer literal and
| if necessary ``marks'' the literal as having a 64-bit integer type. | if necessary ``marks'' the literal as having a 64-bit integer type.
| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be | For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
| appended with the letters `LL' standing for `long long', which is `gcc's | appended with the letters `LL' standing for `long long', which is `gcc's
| name for the 64-bit integer type. Some compilers may allow `LIT64' to be | name for the 64-bit integer type. Some compilers may allow `LIT64' to be
| defined as the identity macro: `#define LIT64( a ) a'. | defined as the identity macro: `#define LIT64( a ) a'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define LIT64( a ) a##ULL #define LIT64( a ) a##ULL
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The macro `INLINE' can be used before functions that should be inlined. If | The macro `INLINE' can be used before functions that should be inlined. If
| a compiler does not support explicit inlining, this macro should be defined | a compiler does not support explicit inlining, this macro should be defined
| to be `static'. | to be `static'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
// MAME defines INLINE // MAME defines INLINE

View file

@ -1,42 +1,42 @@
/*============================================================================ /*============================================================================
This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
Package, Release 2b. Package, Release 2b.
Written by John R. Hauser. This work was made possible in part by the Written by John R. Hauser. This work was made possible in part by the
International Computer Science Institute, located at Suite 600, 1947 Center International Computer Science Institute, located at Suite 600, 1947 Center
Street, Berkeley, California 94704. Funding was partially provided by the Street, Berkeley, California 94704. Funding was partially provided by the
National Science Foundation under grant MIP-9311980. The original version National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley, processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information overseen by Profs. Nelson Morgan and John Wawrzynek. More information
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
arithmetic/SoftFloat.html'. arithmetic/SoftFloat.html'.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that (1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained. these four paragraphs for those parts of this code that are retained.
=============================================================================*/ =============================================================================*/
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Include common integer types and flags. | Include common integer types and flags.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#include "mamesf.h" #include "mamesf.h"
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Symbolic Boolean literals. | Symbolic Boolean literals.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define FALSE 0 #define FALSE 0
#define TRUE 1 #define TRUE 1

File diff suppressed because it is too large Load diff

View file

@ -1,476 +1,476 @@
/*============================================================================ /*============================================================================
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b. Arithmetic Package, Release 2b.
Written by John R. Hauser. This work was made possible in part by the Written by John R. Hauser. This work was made possible in part by the
International Computer Science Institute, located at Suite 600, 1947 Center International Computer Science Institute, located at Suite 600, 1947 Center
Street, Berkeley, California 94704. Funding was partially provided by the Street, Berkeley, California 94704. Funding was partially provided by the
National Science Foundation under grant MIP-9311980. The original version National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley, processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information overseen by Profs. Nelson Morgan and John Wawrzynek. More information
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
arithmetic/SoftFloat.html'. arithmetic/SoftFloat.html'.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that (1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained. these four paragraphs for those parts of this code that are retained.
=============================================================================*/ =============================================================================*/
flag float32_is_nan( float32 a ); flag float32_is_nan( float32 a );
flag float64_is_nan( float64 a ); flag float64_is_nan( float64 a );
flag floatx80_is_nan( floatx80 a ); flag floatx80_is_nan( floatx80 a );
floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ); floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b );
flag float128_is_nan( float128 a ); flag float128_is_nan( float128 a );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Underflow tininess-detection mode, statically initialized to default value. | Underflow tininess-detection mode, statically initialized to default value.
| (The declaration in `softfloat.h' must match the `int8' type here.) | (The declaration in `softfloat.h' must match the `int8' type here.)
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
int8 float_detect_tininess = float_tininess_after_rounding; int8 float_detect_tininess = float_tininess_after_rounding;
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Raises the exceptions specified by `flags'. Floating-point traps can be | Raises the exceptions specified by `flags'. Floating-point traps can be
| defined here if desired. It is currently not possible for such a trap to | defined here if desired. It is currently not possible for such a trap to
| substitute a result value. If traps are not implemented, this routine | substitute a result value. If traps are not implemented, this routine
| should be simply `float_exception_flags |= flags;'. | should be simply `float_exception_flags |= flags;'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void float_raise( int8 flags ) void float_raise( int8 flags )
{ {
float_exception_flags |= flags; float_exception_flags |= flags;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Internal canonical NaN format. | Internal canonical NaN format.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
typedef struct { typedef struct {
flag sign; flag sign;
bits64 high, low; bits64 high, low;
} commonNaNT; } commonNaNT;
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The pattern for a default generated single-precision NaN. | The pattern for a default generated single-precision NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define float32_default_nan 0xFFFFFFFF #define float32_default_nan 0xFFFFFFFF
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is a NaN; | Returns 1 if the single-precision floating-point value `a' is a NaN;
| otherwise returns 0. | otherwise returns 0.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
flag float32_is_nan( float32 a ) flag float32_is_nan( float32 a )
{ {
return ( 0xFF000000 < (bits32) ( a<<1 ) ); return ( 0xFF000000 < (bits32) ( a<<1 ) );
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is a signaling | Returns 1 if the single-precision floating-point value `a' is a signaling
| NaN; otherwise returns 0. | NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
flag float32_is_signaling_nan( float32 a ) flag float32_is_signaling_nan( float32 a )
{ {
return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point NaN | Returns the result of converting the single-precision floating-point NaN
| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static commonNaNT float32ToCommonNaN( float32 a ) static commonNaNT float32ToCommonNaN( float32 a )
{ {
commonNaNT z; commonNaNT z;
if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
z.sign = a>>31; z.sign = a>>31;
z.low = 0; z.low = 0;
z.high = ( (bits64) a )<<41; z.high = ( (bits64) a )<<41;
return z; return z;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the single- | Returns the result of converting the canonical NaN `a' to the single-
| precision floating-point format. | precision floating-point format.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static float32 commonNaNToFloat32( commonNaNT a ) static float32 commonNaNToFloat32( commonNaNT a )
{ {
return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Takes two single-precision floating-point values `a' and `b', one of which | Takes two single-precision floating-point values `a' and `b', one of which
| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static float32 propagateFloat32NaN( float32 a, float32 b ) static float32 propagateFloat32NaN( float32 a, float32 b )
{ {
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
aIsNaN = float32_is_nan( a ); aIsNaN = float32_is_nan( a );
aIsSignalingNaN = float32_is_signaling_nan( a ); aIsSignalingNaN = float32_is_signaling_nan( a );
bIsNaN = float32_is_nan( b ); bIsNaN = float32_is_nan( b );
bIsSignalingNaN = float32_is_signaling_nan( b ); bIsSignalingNaN = float32_is_signaling_nan( b );
a |= 0x00400000; a |= 0x00400000;
b |= 0x00400000; b |= 0x00400000;
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
if ( aIsNaN ) { if ( aIsNaN ) {
return ( aIsSignalingNaN & bIsNaN ) ? b : a; return ( aIsSignalingNaN & bIsNaN ) ? b : a;
} }
else { else {
return b; return b;
} }
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The pattern for a default generated double-precision NaN. | The pattern for a default generated double-precision NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is a NaN; | Returns 1 if the double-precision floating-point value `a' is a NaN;
| otherwise returns 0. | otherwise returns 0.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
flag float64_is_nan( float64 a ) flag float64_is_nan( float64 a )
{ {
return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is a signaling | Returns 1 if the double-precision floating-point value `a' is a signaling
| NaN; otherwise returns 0. | NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
flag float64_is_signaling_nan( float64 a ) flag float64_is_signaling_nan( float64 a )
{ {
return return
( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
&& ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point NaN | Returns the result of converting the double-precision floating-point NaN
| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static commonNaNT float64ToCommonNaN( float64 a ) static commonNaNT float64ToCommonNaN( float64 a )
{ {
commonNaNT z; commonNaNT z;
if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
z.sign = a>>63; z.sign = a>>63;
z.low = 0; z.low = 0;
z.high = a<<12; z.high = a<<12;
return z; return z;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the double- | Returns the result of converting the canonical NaN `a' to the double-
| precision floating-point format. | precision floating-point format.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static float64 commonNaNToFloat64( commonNaNT a ) static float64 commonNaNToFloat64( commonNaNT a )
{ {
return return
( ( (bits64) a.sign )<<63 ) ( ( (bits64) a.sign )<<63 )
| LIT64( 0x7FF8000000000000 ) | LIT64( 0x7FF8000000000000 )
| ( a.high>>12 ); | ( a.high>>12 );
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Takes two double-precision floating-point values `a' and `b', one of which | Takes two double-precision floating-point values `a' and `b', one of which
| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static float64 propagateFloat64NaN( float64 a, float64 b ) static float64 propagateFloat64NaN( float64 a, float64 b )
{ {
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
aIsNaN = float64_is_nan( a ); aIsNaN = float64_is_nan( a );
aIsSignalingNaN = float64_is_signaling_nan( a ); aIsSignalingNaN = float64_is_signaling_nan( a );
bIsNaN = float64_is_nan( b ); bIsNaN = float64_is_nan( b );
bIsSignalingNaN = float64_is_signaling_nan( b ); bIsSignalingNaN = float64_is_signaling_nan( b );
a |= LIT64( 0x0008000000000000 ); a |= LIT64( 0x0008000000000000 );
b |= LIT64( 0x0008000000000000 ); b |= LIT64( 0x0008000000000000 );
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
if ( aIsNaN ) { if ( aIsNaN ) {
return ( aIsSignalingNaN & bIsNaN ) ? b : a; return ( aIsSignalingNaN & bIsNaN ) ? b : a;
} }
else { else {
return b; return b;
} }
} }
#ifdef FLOATX80 #ifdef FLOATX80
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN. The | The pattern for a default generated extended double-precision NaN. The
| `high' and `low' values hold the most- and least-significant bits, | `high' and `low' values hold the most- and least-significant bits,
| respectively. | respectively.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define floatx80_default_nan_high 0xFFFF #define floatx80_default_nan_high 0xFFFF
#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is a | Returns 1 if the extended double-precision floating-point value `a' is a
| NaN; otherwise returns 0. | NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
flag floatx80_is_nan( floatx80 a ) flag floatx80_is_nan( floatx80 a )
{ {
return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is a | Returns 1 if the extended double-precision floating-point value `a' is a
| signaling NaN; otherwise returns 0. | signaling NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
flag floatx80_is_signaling_nan( floatx80 a ) flag floatx80_is_signaling_nan( floatx80 a )
{ {
bits64 aLow; bits64 aLow;
aLow = a.low & ~ LIT64( 0x4000000000000000 ); aLow = a.low & ~ LIT64( 0x4000000000000000 );
return return
( ( a.high & 0x7FFF ) == 0x7FFF ) ( ( a.high & 0x7FFF ) == 0x7FFF )
&& (bits64) ( aLow<<1 ) && (bits64) ( aLow<<1 )
&& ( a.low == aLow ); && ( a.low == aLow );
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating- | Returns the result of converting the extended double-precision floating-
| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
| invalid exception is raised. | invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static commonNaNT floatx80ToCommonNaN( floatx80 a ) static commonNaNT floatx80ToCommonNaN( floatx80 a )
{ {
commonNaNT z; commonNaNT z;
if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
z.sign = a.high>>15; z.sign = a.high>>15;
z.low = 0; z.low = 0;
z.high = a.low<<1; z.high = a.low<<1;
return z; return z;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the extended | Returns the result of converting the canonical NaN `a' to the extended
| double-precision floating-point format. | double-precision floating-point format.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static floatx80 commonNaNToFloatx80( commonNaNT a ) static floatx80 commonNaNToFloatx80( commonNaNT a )
{ {
floatx80 z; floatx80 z;
z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
return z; return z;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Takes two extended double-precision floating-point values `a' and `b', one | Takes two extended double-precision floating-point values `a' and `b', one
| of which is a NaN, and returns the appropriate NaN result. If either `a' or | of which is a NaN, and returns the appropriate NaN result. If either `a' or
| `b' is a signaling NaN, the invalid exception is raised. | `b' is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
{ {
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
aIsNaN = floatx80_is_nan( a ); aIsNaN = floatx80_is_nan( a );
aIsSignalingNaN = floatx80_is_signaling_nan( a ); aIsSignalingNaN = floatx80_is_signaling_nan( a );
bIsNaN = floatx80_is_nan( b ); bIsNaN = floatx80_is_nan( b );
bIsSignalingNaN = floatx80_is_signaling_nan( b ); bIsSignalingNaN = floatx80_is_signaling_nan( b );
a.low |= LIT64( 0xC000000000000000 ); a.low |= LIT64( 0xC000000000000000 );
b.low |= LIT64( 0xC000000000000000 ); b.low |= LIT64( 0xC000000000000000 );
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
if ( aIsNaN ) { if ( aIsNaN ) {
return ( aIsSignalingNaN & bIsNaN ) ? b : a; return ( aIsSignalingNaN & bIsNaN ) ? b : a;
} }
else { else {
return b; return b;
} }
} }
#define EXP_BIAS 0x3FFF #define EXP_BIAS 0x3FFF
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the fraction bits of the extended double-precision floating-point | Returns the fraction bits of the extended double-precision floating-point
| value `a'. | value `a'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static inline bits64 extractFloatx80Frac( floatx80 a ) static inline bits64 extractFloatx80Frac( floatx80 a )
{ {
return a.low; return a.low;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the exponent bits of the extended double-precision floating-point | Returns the exponent bits of the extended double-precision floating-point
| value `a'. | value `a'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static inline int32 extractFloatx80Exp( floatx80 a ) static inline int32 extractFloatx80Exp( floatx80 a )
{ {
return a.high & 0x7FFF; return a.high & 0x7FFF;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the sign bit of the extended double-precision floating-point value | Returns the sign bit of the extended double-precision floating-point value
| `a'. | `a'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static inline flag extractFloatx80Sign( floatx80 a ) static inline flag extractFloatx80Sign( floatx80 a )
{ {
return a.high>>15; return a.high>>15;
} }
#endif #endif
#ifdef FLOAT128 #ifdef FLOAT128
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The pattern for a default generated quadruple-precision NaN. The `high' and | The pattern for a default generated quadruple-precision NaN. The `high' and
| `low' values hold the most- and least-significant bits, respectively. | `low' values hold the most- and least-significant bits, respectively.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF ) #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is a NaN; | Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
| otherwise returns 0. | otherwise returns 0.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
flag float128_is_nan( float128 a ) flag float128_is_nan( float128 a )
{ {
return return
( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
&& ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is a | Returns 1 if the quadruple-precision floating-point value `a' is a
| signaling NaN; otherwise returns 0. | signaling NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
flag float128_is_signaling_nan( float128 a ) flag float128_is_signaling_nan( float128 a )
{ {
return return
( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
&& ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the result of converting the quadruple-precision floating-point NaN | Returns the result of converting the quadruple-precision floating-point NaN
| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static commonNaNT float128ToCommonNaN( float128 a ) static commonNaNT float128ToCommonNaN( float128 a )
{ {
commonNaNT z; commonNaNT z;
if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
z.sign = a.high>>63; z.sign = a.high>>63;
shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
return z; return z;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the quadruple- | Returns the result of converting the canonical NaN `a' to the quadruple-
| precision floating-point format. | precision floating-point format.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static float128 commonNaNToFloat128( commonNaNT a ) static float128 commonNaNToFloat128( commonNaNT a )
{ {
float128 z; float128 z;
shift128Right( a.high, a.low, 16, &z.high, &z.low ); shift128Right( a.high, a.low, 16, &z.high, &z.low );
z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
return z; return z;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Takes two quadruple-precision floating-point values `a' and `b', one of | Takes two quadruple-precision floating-point values `a' and `b', one of
| which is a NaN, and returns the appropriate NaN result. If either `a' or | which is a NaN, and returns the appropriate NaN result. If either `a' or
| `b' is a signaling NaN, the invalid exception is raised. | `b' is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static float128 propagateFloat128NaN( float128 a, float128 b ) static float128 propagateFloat128NaN( float128 a, float128 b )
{ {
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
aIsNaN = float128_is_nan( a ); aIsNaN = float128_is_nan( a );
aIsSignalingNaN = float128_is_signaling_nan( a ); aIsSignalingNaN = float128_is_signaling_nan( a );
bIsNaN = float128_is_nan( b ); bIsNaN = float128_is_nan( b );
bIsSignalingNaN = float128_is_signaling_nan( b ); bIsSignalingNaN = float128_is_signaling_nan( b );
a.high |= LIT64( 0x0000800000000000 ); a.high |= LIT64( 0x0000800000000000 );
b.high |= LIT64( 0x0000800000000000 ); b.high |= LIT64( 0x0000800000000000 );
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
if ( aIsNaN ) { if ( aIsNaN ) {
return ( aIsSignalingNaN & bIsNaN ) ? b : a; return ( aIsSignalingNaN & bIsNaN ) ? b : a;
} }
else { else {
return b; return b;
} }
} }
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,460 +1,460 @@
/*============================================================================ /*============================================================================
This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
Package, Release 2b. Package, Release 2b.
Written by John R. Hauser. This work was made possible in part by the Written by John R. Hauser. This work was made possible in part by the
International Computer Science Institute, located at Suite 600, 1947 Center International Computer Science Institute, located at Suite 600, 1947 Center
Street, Berkeley, California 94704. Funding was partially provided by the Street, Berkeley, California 94704. Funding was partially provided by the
National Science Foundation under grant MIP-9311980. The original version National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley, processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information overseen by Profs. Nelson Morgan and John Wawrzynek. More information
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
arithmetic/SoftFloat.html'. arithmetic/SoftFloat.html'.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that (1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained. these four paragraphs for those parts of this code that are retained.
=============================================================================*/ =============================================================================*/
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The macro `FLOATX80' must be defined to enable the extended double-precision | The macro `FLOATX80' must be defined to enable the extended double-precision
| floating-point format `floatx80'. If this macro is not defined, the | floating-point format `floatx80'. If this macro is not defined, the
| `floatx80' type will not be defined, and none of the functions that either | `floatx80' type will not be defined, and none of the functions that either
| input or output the `floatx80' type will be defined. The same applies to | input or output the `floatx80' type will be defined. The same applies to
| the `FLOAT128' macro and the quadruple-precision format `float128'. | the `FLOAT128' macro and the quadruple-precision format `float128'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define FLOATX80 #define FLOATX80
#define FLOAT128 #define FLOAT128
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE floating-point types. | Software IEC/IEEE floating-point types.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
typedef bits32 float32; typedef bits32 float32;
typedef bits64 float64; typedef bits64 float64;
#ifdef FLOATX80 #ifdef FLOATX80
typedef struct { typedef struct {
bits16 high; bits16 high;
bits64 low; bits64 low;
} floatx80; } floatx80;
#endif #endif
#ifdef FLOAT128 #ifdef FLOAT128
typedef struct { typedef struct {
bits64 high, low; bits64 high, low;
} float128; } float128;
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Primitive arithmetic functions, including multi-word arithmetic, and | Primitive arithmetic functions, including multi-word arithmetic, and
| division and square root approximations. (Can be specialized to target if | division and square root approximations. (Can be specialized to target if
| desired.) | desired.)
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#include "softfloat-macros" #include "softfloat-macros"
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE floating-point underflow tininess-detection mode. | Software IEC/IEEE floating-point underflow tininess-detection mode.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
extern int8 float_detect_tininess; extern int8 float_detect_tininess;
enum { enum {
float_tininess_after_rounding = 0, float_tininess_after_rounding = 0,
float_tininess_before_rounding = 1 float_tininess_before_rounding = 1
}; };
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE floating-point rounding mode. | Software IEC/IEEE floating-point rounding mode.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
extern int8 float_rounding_mode; extern int8 float_rounding_mode;
enum { enum {
float_round_nearest_even = 0, float_round_nearest_even = 0,
float_round_to_zero = 1, float_round_to_zero = 1,
float_round_down = 2, float_round_down = 2,
float_round_up = 3 float_round_up = 3
}; };
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE floating-point exception flags. | Software IEC/IEEE floating-point exception flags.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
extern int8 float_exception_flags; extern int8 float_exception_flags;
enum { enum {
float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08, float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08,
float_flag_underflow = 0x10, float_flag_inexact = 0x20 float_flag_underflow = 0x10, float_flag_inexact = 0x20
}; };
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Routine to raise any or all of the software IEC/IEEE floating-point | Routine to raise any or all of the software IEC/IEEE floating-point
| exception flags. | exception flags.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void float_raise( int8 ); void float_raise( int8 );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE integer-to-floating-point conversion routines. | Software IEC/IEEE integer-to-floating-point conversion routines.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
float32 int32_to_float32( int32 ); float32 int32_to_float32( int32 );
float64 int32_to_float64( int32 ); float64 int32_to_float64( int32 );
#ifdef FLOATX80 #ifdef FLOATX80
floatx80 int32_to_floatx80( int32 ); floatx80 int32_to_floatx80( int32 );
#endif #endif
#ifdef FLOAT128 #ifdef FLOAT128
float128 int32_to_float128( int32 ); float128 int32_to_float128( int32 );
#endif #endif
float32 int64_to_float32( int64 ); float32 int64_to_float32( int64 );
float64 int64_to_float64( int64 ); float64 int64_to_float64( int64 );
#ifdef FLOATX80 #ifdef FLOATX80
floatx80 int64_to_floatx80( int64 ); floatx80 int64_to_floatx80( int64 );
#endif #endif
#ifdef FLOAT128 #ifdef FLOAT128
float128 int64_to_float128( int64 ); float128 int64_to_float128( int64 );
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE single-precision conversion routines. | Software IEC/IEEE single-precision conversion routines.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
int32 float32_to_int32( float32 ); int32 float32_to_int32( float32 );
int32 float32_to_int32_round_to_zero( float32 ); int32 float32_to_int32_round_to_zero( float32 );
int64 float32_to_int64( float32 ); int64 float32_to_int64( float32 );
int64 float32_to_int64_round_to_zero( float32 ); int64 float32_to_int64_round_to_zero( float32 );
float64 float32_to_float64( float32 ); float64 float32_to_float64( float32 );
#ifdef FLOATX80 #ifdef FLOATX80
floatx80 float32_to_floatx80( float32 ); floatx80 float32_to_floatx80( float32 );
#endif #endif
#ifdef FLOAT128 #ifdef FLOAT128
float128 float32_to_float128( float32 ); float128 float32_to_float128( float32 );
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE single-precision operations. | Software IEC/IEEE single-precision operations.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
float32 float32_round_to_int( float32 ); float32 float32_round_to_int( float32 );
float32 float32_add( float32, float32 ); float32 float32_add( float32, float32 );
float32 float32_sub( float32, float32 ); float32 float32_sub( float32, float32 );
float32 float32_mul( float32, float32 ); float32 float32_mul( float32, float32 );
float32 float32_div( float32, float32 ); float32 float32_div( float32, float32 );
float32 float32_rem( float32, float32 ); float32 float32_rem( float32, float32 );
float32 float32_sqrt( float32 ); float32 float32_sqrt( float32 );
flag float32_eq( float32, float32 ); flag float32_eq( float32, float32 );
flag float32_le( float32, float32 ); flag float32_le( float32, float32 );
flag float32_lt( float32, float32 ); flag float32_lt( float32, float32 );
flag float32_eq_signaling( float32, float32 ); flag float32_eq_signaling( float32, float32 );
flag float32_le_quiet( float32, float32 ); flag float32_le_quiet( float32, float32 );
flag float32_lt_quiet( float32, float32 ); flag float32_lt_quiet( float32, float32 );
flag float32_is_signaling_nan( float32 ); flag float32_is_signaling_nan( float32 );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision conversion routines. | Software IEC/IEEE double-precision conversion routines.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
int32 float64_to_int32( float64 ); int32 float64_to_int32( float64 );
int32 float64_to_int32_round_to_zero( float64 ); int32 float64_to_int32_round_to_zero( float64 );
int64 float64_to_int64( float64 ); int64 float64_to_int64( float64 );
int64 float64_to_int64_round_to_zero( float64 ); int64 float64_to_int64_round_to_zero( float64 );
float32 float64_to_float32( float64 ); float32 float64_to_float32( float64 );
#ifdef FLOATX80 #ifdef FLOATX80
floatx80 float64_to_floatx80( float64 ); floatx80 float64_to_floatx80( float64 );
#endif #endif
#ifdef FLOAT128 #ifdef FLOAT128
float128 float64_to_float128( float64 ); float128 float64_to_float128( float64 );
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision operations. | Software IEC/IEEE double-precision operations.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
float64 float64_round_to_int( float64 ); float64 float64_round_to_int( float64 );
float64 float64_add( float64, float64 ); float64 float64_add( float64, float64 );
float64 float64_sub( float64, float64 ); float64 float64_sub( float64, float64 );
float64 float64_mul( float64, float64 ); float64 float64_mul( float64, float64 );
float64 float64_div( float64, float64 ); float64 float64_div( float64, float64 );
float64 float64_rem( float64, float64 ); float64 float64_rem( float64, float64 );
float64 float64_sqrt( float64 ); float64 float64_sqrt( float64 );
flag float64_eq( float64, float64 ); flag float64_eq( float64, float64 );
flag float64_le( float64, float64 ); flag float64_le( float64, float64 );
flag float64_lt( float64, float64 ); flag float64_lt( float64, float64 );
flag float64_eq_signaling( float64, float64 ); flag float64_eq_signaling( float64, float64 );
flag float64_le_quiet( float64, float64 ); flag float64_le_quiet( float64, float64 );
flag float64_lt_quiet( float64, float64 ); flag float64_lt_quiet( float64, float64 );
flag float64_is_signaling_nan( float64 ); flag float64_is_signaling_nan( float64 );
#ifdef FLOATX80 #ifdef FLOATX80
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE extended double-precision conversion routines. | Software IEC/IEEE extended double-precision conversion routines.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
int32 floatx80_to_int32( floatx80 ); int32 floatx80_to_int32( floatx80 );
int32 floatx80_to_int32_round_to_zero( floatx80 ); int32 floatx80_to_int32_round_to_zero( floatx80 );
int64 floatx80_to_int64( floatx80 ); int64 floatx80_to_int64( floatx80 );
int64 floatx80_to_int64_round_to_zero( floatx80 ); int64 floatx80_to_int64_round_to_zero( floatx80 );
float32 floatx80_to_float32( floatx80 ); float32 floatx80_to_float32( floatx80 );
float64 floatx80_to_float64( floatx80 ); float64 floatx80_to_float64( floatx80 );
#ifdef FLOAT128 #ifdef FLOAT128
float128 floatx80_to_float128( floatx80 ); float128 floatx80_to_float128( floatx80 );
#endif #endif
floatx80 floatx80_scale(floatx80 a, floatx80 b); floatx80 floatx80_scale(floatx80 a, floatx80 b);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an | Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
| extended double-precision floating-point value, returning the result. | extended double-precision floating-point value, returning the result.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static inline floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) static inline floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
{ {
floatx80 z; floatx80 z;
z.low = zSig; z.low = zSig;
z.high = ( ( (bits16) zSign )<<15 ) + zExp; z.high = ( ( (bits16) zSign )<<15 ) + zExp;
return z; return z;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE extended double-precision rounding precision. Valid | Software IEC/IEEE extended double-precision rounding precision. Valid
| values are 32, 64, and 80. | values are 32, 64, and 80.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
extern int8 floatx80_rounding_precision; extern int8 floatx80_rounding_precision;
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE extended double-precision operations. | Software IEC/IEEE extended double-precision operations.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
floatx80 floatx80_round_to_int( floatx80 ); floatx80 floatx80_round_to_int( floatx80 );
floatx80 floatx80_add( floatx80, floatx80 ); floatx80 floatx80_add( floatx80, floatx80 );
floatx80 floatx80_sub( floatx80, floatx80 ); floatx80 floatx80_sub( floatx80, floatx80 );
floatx80 floatx80_mul( floatx80, floatx80 ); floatx80 floatx80_mul( floatx80, floatx80 );
floatx80 floatx80_div( floatx80, floatx80 ); floatx80 floatx80_div( floatx80, floatx80 );
floatx80 floatx80_rem( floatx80, floatx80 ); floatx80 floatx80_rem( floatx80, floatx80 );
floatx80 floatx80_sqrt( floatx80 ); floatx80 floatx80_sqrt( floatx80 );
flag floatx80_eq( floatx80, floatx80 ); flag floatx80_eq( floatx80, floatx80 );
flag floatx80_le( floatx80, floatx80 ); flag floatx80_le( floatx80, floatx80 );
flag floatx80_lt( floatx80, floatx80 ); flag floatx80_lt( floatx80, floatx80 );
flag floatx80_eq_signaling( floatx80, floatx80 ); flag floatx80_eq_signaling( floatx80, floatx80 );
flag floatx80_le_quiet( floatx80, floatx80 ); flag floatx80_le_quiet( floatx80, floatx80 );
flag floatx80_lt_quiet( floatx80, floatx80 ); flag floatx80_lt_quiet( floatx80, floatx80 );
flag floatx80_is_signaling_nan( floatx80 ); flag floatx80_is_signaling_nan( floatx80 );
/* int floatx80_fsin(floatx80 &a); /* int floatx80_fsin(floatx80 &a);
int floatx80_fcos(floatx80 &a); int floatx80_fcos(floatx80 &a);
int floatx80_ftan(floatx80 &a); */ int floatx80_ftan(floatx80 &a); */
floatx80 floatx80_flognp1(floatx80 a); floatx80 floatx80_flognp1(floatx80 a);
floatx80 floatx80_flogn(floatx80 a); floatx80 floatx80_flogn(floatx80 a);
floatx80 floatx80_flog2(floatx80 a); floatx80 floatx80_flog2(floatx80 a);
floatx80 floatx80_flog10(floatx80 a); floatx80 floatx80_flog10(floatx80 a);
// roundAndPackFloatx80 used to be in softfloat-round-pack, is now in softfloat.c // roundAndPackFloatx80 used to be in softfloat-round-pack, is now in softfloat.c
floatx80 roundAndPackFloatx80(int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1); floatx80 roundAndPackFloatx80(int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1);
#endif #endif
#ifdef FLOAT128 #ifdef FLOAT128
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE quadruple-precision conversion routines. | Software IEC/IEEE quadruple-precision conversion routines.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
int32 float128_to_int32( float128 ); int32 float128_to_int32( float128 );
int32 float128_to_int32_round_to_zero( float128 ); int32 float128_to_int32_round_to_zero( float128 );
int64 float128_to_int64( float128 ); int64 float128_to_int64( float128 );
int64 float128_to_int64_round_to_zero( float128 ); int64 float128_to_int64_round_to_zero( float128 );
float32 float128_to_float32( float128 ); float32 float128_to_float32( float128 );
float64 float128_to_float64( float128 ); float64 float128_to_float64( float128 );
#ifdef FLOATX80 #ifdef FLOATX80
floatx80 float128_to_floatx80( float128 ); floatx80 float128_to_floatx80( float128 );
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software IEC/IEEE quadruple-precision operations. | Software IEC/IEEE quadruple-precision operations.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
float128 float128_round_to_int( float128 ); float128 float128_round_to_int( float128 );
float128 float128_add( float128, float128 ); float128 float128_add( float128, float128 );
float128 float128_sub( float128, float128 ); float128 float128_sub( float128, float128 );
float128 float128_mul( float128, float128 ); float128 float128_mul( float128, float128 );
float128 float128_div( float128, float128 ); float128 float128_div( float128, float128 );
float128 float128_rem( float128, float128 ); float128 float128_rem( float128, float128 );
float128 float128_sqrt( float128 ); float128 float128_sqrt( float128 );
flag float128_eq( float128, float128 ); flag float128_eq( float128, float128 );
flag float128_le( float128, float128 ); flag float128_le( float128, float128 );
flag float128_lt( float128, float128 ); flag float128_lt( float128, float128 );
flag float128_eq_signaling( float128, float128 ); flag float128_eq_signaling( float128, float128 );
flag float128_le_quiet( float128, float128 ); flag float128_le_quiet( float128, float128 );
flag float128_lt_quiet( float128, float128 ); flag float128_lt_quiet( float128, float128 );
flag float128_is_signaling_nan( float128 ); flag float128_is_signaling_nan( float128 );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Packs the sign `zSign', the exponent `zExp', and the significand formed | Packs the sign `zSign', the exponent `zExp', and the significand formed
| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision | by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
| floating-point value, returning the result. After being shifted into the | floating-point value, returning the result. After being shifted into the
| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply | proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
| added together to form the most significant 32 bits of the result. This | added together to form the most significant 32 bits of the result. This
| means that any integer portion of `zSig0' will be added into the exponent. | means that any integer portion of `zSig0' will be added into the exponent.
| Since a properly normalized significand will have an integer portion equal | Since a properly normalized significand will have an integer portion equal
| to 1, the `zExp' input should be 1 less than the desired result exponent | to 1, the `zExp' input should be 1 less than the desired result exponent
| whenever `zSig0' and `zSig1' concatenated form a complete, normalized | whenever `zSig0' and `zSig1' concatenated form a complete, normalized
| significand. | significand.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static inline float128 static inline float128
packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
{ {
float128 z; float128 z;
z.low = zSig1; z.low = zSig1;
z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0; z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0;
return z; return z;
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp', | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and extended significand formed by the concatenation of `zSig0', `zSig1', | and extended significand formed by the concatenation of `zSig0', `zSig1',
| and `zSig2', and returns the proper quadruple-precision floating-point value | and `zSig2', and returns the proper quadruple-precision floating-point value
| corresponding to the abstract input. Ordinarily, the abstract value is | corresponding to the abstract input. Ordinarily, the abstract value is
| simply rounded and packed into the quadruple-precision format, with the | simply rounded and packed into the quadruple-precision format, with the
| inexact exception raised if the abstract input cannot be represented | inexact exception raised if the abstract input cannot be represented
| exactly. However, if the abstract value is too large, the overflow and | exactly. However, if the abstract value is too large, the overflow and
| inexact exceptions are raised and an infinity or maximal finite value is | inexact exceptions are raised and an infinity or maximal finite value is
| returned. If the abstract value is too small, the input value is rounded to | returned. If the abstract value is too small, the input value is rounded to
| a subnormal number, and the underflow and inexact exceptions are raised if | a subnormal number, and the underflow and inexact exceptions are raised if
| the abstract input cannot be represented exactly as a subnormal quadruple- | the abstract input cannot be represented exactly as a subnormal quadruple-
| precision floating-point number. | precision floating-point number.
| The input significand must be normalized or smaller. If the input | The input significand must be normalized or smaller. If the input
| significand is not normalized, `zExp' must be 0; in that case, the result | significand is not normalized, `zExp' must be 0; in that case, the result
| returned is a subnormal number, and it must not require rounding. In the | returned is a subnormal number, and it must not require rounding. In the
| usual case that the input significand is normalized, `zExp' must be 1 less | usual case that the input significand is normalized, `zExp' must be 1 less
| than the ``true'' floating-point exponent. The handling of underflow and | than the ``true'' floating-point exponent. The handling of underflow and
| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic. | overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static inline float128 static inline float128
roundAndPackFloat128( roundAndPackFloat128(
flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 ) flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 )
{ {
int8 roundingMode; int8 roundingMode;
flag roundNearestEven, increment, isTiny; flag roundNearestEven, increment, isTiny;
roundingMode = float_rounding_mode; roundingMode = float_rounding_mode;
roundNearestEven = ( roundingMode == float_round_nearest_even ); roundNearestEven = ( roundingMode == float_round_nearest_even );
increment = ( (sbits64) zSig2 < 0 ); increment = ( (sbits64) zSig2 < 0 );
if ( ! roundNearestEven ) { if ( ! roundNearestEven ) {
if ( roundingMode == float_round_to_zero ) { if ( roundingMode == float_round_to_zero ) {
increment = 0; increment = 0;
} }
else { else {
if ( zSign ) { if ( zSign ) {
increment = ( roundingMode == float_round_down ) && zSig2; increment = ( roundingMode == float_round_down ) && zSig2;
} }
else { else {
increment = ( roundingMode == float_round_up ) && zSig2; increment = ( roundingMode == float_round_up ) && zSig2;
} }
} }
} }
if ( 0x7FFD <= (bits32) zExp ) { if ( 0x7FFD <= (bits32) zExp ) {
if ( ( 0x7FFD < zExp ) if ( ( 0x7FFD < zExp )
|| ( ( zExp == 0x7FFD ) || ( ( zExp == 0x7FFD )
&& eq128( && eq128(
LIT64( 0x0001FFFFFFFFFFFF ), LIT64( 0x0001FFFFFFFFFFFF ),
LIT64( 0xFFFFFFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ),
zSig0, zSig0,
zSig1 zSig1
) )
&& increment && increment
) )
) { ) {
float_raise( float_flag_overflow | float_flag_inexact ); float_raise( float_flag_overflow | float_flag_inexact );
if ( ( roundingMode == float_round_to_zero ) if ( ( roundingMode == float_round_to_zero )
|| ( zSign && ( roundingMode == float_round_up ) ) || ( zSign && ( roundingMode == float_round_up ) )
|| ( ! zSign && ( roundingMode == float_round_down ) ) || ( ! zSign && ( roundingMode == float_round_down ) )
) { ) {
return return
packFloat128( packFloat128(
zSign, zSign,
0x7FFE, 0x7FFE,
LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x0000FFFFFFFFFFFF ),
LIT64( 0xFFFFFFFFFFFFFFFF ) LIT64( 0xFFFFFFFFFFFFFFFF )
); );
} }
return packFloat128( zSign, 0x7FFF, 0, 0 ); return packFloat128( zSign, 0x7FFF, 0, 0 );
} }
if ( zExp < 0 ) { if ( zExp < 0 ) {
isTiny = isTiny =
( float_detect_tininess == float_tininess_before_rounding ) ( float_detect_tininess == float_tininess_before_rounding )
|| ( zExp < -1 ) || ( zExp < -1 )
|| ! increment || ! increment
|| lt128( || lt128(
zSig0, zSig0,
zSig1, zSig1,
LIT64( 0x0001FFFFFFFFFFFF ), LIT64( 0x0001FFFFFFFFFFFF ),
LIT64( 0xFFFFFFFFFFFFFFFF ) LIT64( 0xFFFFFFFFFFFFFFFF )
); );
shift128ExtraRightJamming( shift128ExtraRightJamming(
zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 ); zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
zExp = 0; zExp = 0;
if ( isTiny && zSig2 ) float_raise( float_flag_underflow ); if ( isTiny && zSig2 ) float_raise( float_flag_underflow );
if ( roundNearestEven ) { if ( roundNearestEven ) {
increment = ( (sbits64) zSig2 < 0 ); increment = ( (sbits64) zSig2 < 0 );
} }
else { else {
if ( zSign ) { if ( zSign ) {
increment = ( roundingMode == float_round_down ) && zSig2; increment = ( roundingMode == float_round_down ) && zSig2;
} }
else { else {
increment = ( roundingMode == float_round_up ) && zSig2; increment = ( roundingMode == float_round_up ) && zSig2;
} }
} }
} }
} }
if ( zSig2 ) float_exception_flags |= float_flag_inexact; if ( zSig2 ) float_exception_flags |= float_flag_inexact;
if ( increment ) { if ( increment ) {
add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 ); add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven ); zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
} }
else { else {
if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0; if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
} }
return packFloat128( zSign, zExp, zSig0, zSig1 ); return packFloat128( zSign, zExp, zSig0, zSig1 );
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp', | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and significand formed by the concatenation of `zSig0' and `zSig1', and | and significand formed by the concatenation of `zSig0' and `zSig1', and
| returns the proper quadruple-precision floating-point value corresponding | returns the proper quadruple-precision floating-point value corresponding
| to the abstract input. This routine is just like `roundAndPackFloat128' | to the abstract input. This routine is just like `roundAndPackFloat128'
| except that the input significand has fewer bits and does not have to be | except that the input significand has fewer bits and does not have to be
| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating- | normalized. In all cases, `zExp' must be 1 less than the ``true'' floating-
| point exponent. | point exponent.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static inline float128 static inline float128
normalizeRoundAndPackFloat128( normalizeRoundAndPackFloat128(
flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
{ {
int8 shiftCount; int8 shiftCount;
bits64 zSig2; bits64 zSig2;
if ( zSig0 == 0 ) { if ( zSig0 == 0 ) {
zSig0 = zSig1; zSig0 = zSig1;
zSig1 = 0; zSig1 = 0;
zExp -= 64; zExp -= 64;
} }
shiftCount = countLeadingZeros64( zSig0 ) - 15; shiftCount = countLeadingZeros64( zSig0 ) - 15;
if ( 0 <= shiftCount ) { if ( 0 <= shiftCount ) {
zSig2 = 0; zSig2 = 0;
shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
} }
else { else {
shift128ExtraRightJamming( shift128ExtraRightJamming(
zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 ); zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
} }
zExp -= shiftCount; zExp -= shiftCount;
return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
} }
#endif #endif

View file

@ -93,62 +93,62 @@ extern "C" {
/* CPU types for use in m68k_set_cpu_type() */ /* CPU types for use in m68k_set_cpu_type() */
enum enum
{ {
M68K_CPU_TYPE_INVALID, M68K_CPU_TYPE_INVALID,
M68K_CPU_TYPE_68000, M68K_CPU_TYPE_68000,
M68K_CPU_TYPE_68010, M68K_CPU_TYPE_68010,
M68K_CPU_TYPE_68EC020, M68K_CPU_TYPE_68EC020,
M68K_CPU_TYPE_68020, M68K_CPU_TYPE_68020,
M68K_CPU_TYPE_68EC030, M68K_CPU_TYPE_68EC030,
M68K_CPU_TYPE_68030, M68K_CPU_TYPE_68030,
M68K_CPU_TYPE_68EC040, M68K_CPU_TYPE_68EC040,
M68K_CPU_TYPE_68LC040, M68K_CPU_TYPE_68LC040,
M68K_CPU_TYPE_68040, M68K_CPU_TYPE_68040,
M68K_CPU_TYPE_SCC68070 M68K_CPU_TYPE_SCC68070
}; };
/* Registers used by m68k_get_reg() and m68k_set_reg() */ /* Registers used by m68k_get_reg() and m68k_set_reg() */
typedef enum typedef enum
{ {
/* Real registers */ /* Real registers */
M68K_REG_D0, /* Data registers */ M68K_REG_D0, /* Data registers */
M68K_REG_D1, M68K_REG_D1,
M68K_REG_D2, M68K_REG_D2,
M68K_REG_D3, M68K_REG_D3,
M68K_REG_D4, M68K_REG_D4,
M68K_REG_D5, M68K_REG_D5,
M68K_REG_D6, M68K_REG_D6,
M68K_REG_D7, M68K_REG_D7,
M68K_REG_A0, /* Address registers */ M68K_REG_A0, /* Address registers */
M68K_REG_A1, M68K_REG_A1,
M68K_REG_A2, M68K_REG_A2,
M68K_REG_A3, M68K_REG_A3,
M68K_REG_A4, M68K_REG_A4,
M68K_REG_A5, M68K_REG_A5,
M68K_REG_A6, M68K_REG_A6,
M68K_REG_A7, M68K_REG_A7,
M68K_REG_PC, /* Program Counter */ M68K_REG_PC, /* Program Counter */
M68K_REG_SR, /* Status Register */ M68K_REG_SR, /* Status Register */
M68K_REG_SP, /* The current Stack Pointer (located in A7) */ M68K_REG_SP, /* The current Stack Pointer (located in A7) */
M68K_REG_USP, /* User Stack Pointer */ M68K_REG_USP, /* User Stack Pointer */
M68K_REG_ISP, /* Interrupt Stack Pointer */ M68K_REG_ISP, /* Interrupt Stack Pointer */
M68K_REG_MSP, /* Master Stack Pointer */ M68K_REG_MSP, /* Master Stack Pointer */
M68K_REG_SFC, /* Source Function Code */ M68K_REG_SFC, /* Source Function Code */
M68K_REG_DFC, /* Destination Function Code */ M68K_REG_DFC, /* Destination Function Code */
M68K_REG_VBR, /* Vector Base Register */ M68K_REG_VBR, /* Vector Base Register */
M68K_REG_CACR, /* Cache Control Register */ M68K_REG_CACR, /* Cache Control Register */
M68K_REG_CAAR, /* Cache Address Register */ M68K_REG_CAAR, /* Cache Address Register */
/* Assumed registers */ /* Assumed registers */
/* These are cheat registers which emulate the 1-longword prefetch /* These are cheat registers which emulate the 1-longword prefetch
* present in the 68000 and 68010. * present in the 68000 and 68010.
*/ */
M68K_REG_PREF_ADDR, /* Last prefetch address */ M68K_REG_PREF_ADDR, /* Last prefetch address */
M68K_REG_PREF_DATA, /* Last prefetch data */ M68K_REG_PREF_DATA, /* Last prefetch data */
/* Convenience registers */ /* Convenience registers */
M68K_REG_PPC, /* Previous value in the program counter */ M68K_REG_PPC, /* Previous value in the program counter */
M68K_REG_IR, /* Instruction register */ M68K_REG_IR, /* Instruction register */
M68K_REG_CPU_TYPE /* Type of CPU being run */ M68K_REG_CPU_TYPE /* Type of CPU being run */
} m68k_register_t; } m68k_register_t;
/* ======================================================================== */ /* ======================================================================== */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -142,7 +142,7 @@
* You should put OPT_SPECIFY_HANDLER here if you cant to use it, otherwise it will * You should put OPT_SPECIFY_HANDLER here if you cant to use it, otherwise it will
* use a dummy default handler and you'll have to call m68k_set_illg_instr_callback explicitely * use a dummy default handler and you'll have to call m68k_set_illg_instr_callback explicitely
*/ */
#define M68K_ILLG_HAS_CALLBACK OPT_OFF #define M68K_ILLG_HAS_CALLBACK OPT_OFF
#define M68K_ILLG_CALLBACK(opcode) op_illg(opcode) #define M68K_ILLG_CALLBACK(opcode) op_illg(opcode)
/* If ON, CPU will call the set fc callback on every memory access to /* If ON, CPU will call the set fc callback on every memory access to

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,321 +1,321 @@
/* /*
m68kmmu.h - PMMU implementation for 68851/68030/68040 m68kmmu.h - PMMU implementation for 68851/68030/68040
By R. Belmont By R. Belmont
Copyright Nicola Salmoria and the MAME Team. Copyright Nicola Salmoria and the MAME Team.
Visit http://mamedev.org for licensing and usage restrictions. Visit http://mamedev.org for licensing and usage restrictions.
*/ */
/* /*
pmmu_translate_addr: perform 68851/68030-style PMMU address translation pmmu_translate_addr: perform 68851/68030-style PMMU address translation
*/ */
uint pmmu_translate_addr(uint addr_in) uint pmmu_translate_addr(uint addr_in)
{ {
uint32 addr_out, tbl_entry = 0, tbl_entry2, tamode = 0, tbmode = 0, tcmode = 0; uint32 addr_out, tbl_entry = 0, tbl_entry2, tamode = 0, tbmode = 0, tcmode = 0;
uint root_aptr, root_limit, tofs, is, abits, bbits, cbits; uint root_aptr, root_limit, tofs, is, abits, bbits, cbits;
uint resolved, tptr, shift; uint resolved, tptr, shift;
resolved = 0; resolved = 0;
addr_out = addr_in; addr_out = addr_in;
// if SRP is enabled and we're in supervisor mode, use it // if SRP is enabled and we're in supervisor mode, use it
if ((m68ki_cpu.mmu_tc & 0x02000000) && (m68ki_get_sr() & 0x2000)) if ((m68ki_cpu.mmu_tc & 0x02000000) && (m68ki_get_sr() & 0x2000))
{ {
root_aptr = m68ki_cpu.mmu_srp_aptr; root_aptr = m68ki_cpu.mmu_srp_aptr;
root_limit = m68ki_cpu.mmu_srp_limit; root_limit = m68ki_cpu.mmu_srp_limit;
} }
else // else use the CRP else // else use the CRP
{ {
root_aptr = m68ki_cpu.mmu_crp_aptr; root_aptr = m68ki_cpu.mmu_crp_aptr;
root_limit = m68ki_cpu.mmu_crp_limit; root_limit = m68ki_cpu.mmu_crp_limit;
} }
// get initial shift (# of top bits to ignore) // get initial shift (# of top bits to ignore)
is = (m68ki_cpu.mmu_tc>>16) & 0xf; is = (m68ki_cpu.mmu_tc>>16) & 0xf;
abits = (m68ki_cpu.mmu_tc>>12)&0xf; abits = (m68ki_cpu.mmu_tc>>12)&0xf;
bbits = (m68ki_cpu.mmu_tc>>8)&0xf; bbits = (m68ki_cpu.mmu_tc>>8)&0xf;
cbits = (m68ki_cpu.mmu_tc>>4)&0xf; cbits = (m68ki_cpu.mmu_tc>>4)&0xf;
// fprintf(stderr,"PMMU: tcr %08x limit %08x aptr %08x is %x abits %d bbits %d cbits %d\n", m68ki_cpu.mmu_tc, root_limit, root_aptr, is, abits, bbits, cbits); // fprintf(stderr,"PMMU: tcr %08x limit %08x aptr %08x is %x abits %d bbits %d cbits %d\n", m68ki_cpu.mmu_tc, root_limit, root_aptr, is, abits, bbits, cbits);
// get table A offset // get table A offset
tofs = (addr_in<<is)>>(32-abits); tofs = (addr_in<<is)>>(32-abits);
// find out what format table A is // find out what format table A is
switch (root_limit & 3) switch (root_limit & 3)
{ {
case 0: // invalid, should cause MMU exception case 0: // invalid, should cause MMU exception
case 1: // page descriptor, should cause direct mapping case 1: // page descriptor, should cause direct mapping
fatalerror("680x0 PMMU: Unhandled root mode\n"); fatalerror("680x0 PMMU: Unhandled root mode\n");
break; break;
case 2: // valid 4 byte descriptors case 2: // valid 4 byte descriptors
tofs *= 4; tofs *= 4;
// fprintf(stderr,"PMMU: reading table A entry at %08x\n", tofs + (root_aptr & 0xfffffffc)); // fprintf(stderr,"PMMU: reading table A entry at %08x\n", tofs + (root_aptr & 0xfffffffc));
tbl_entry = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc)); tbl_entry = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc));
tamode = tbl_entry & 3; tamode = tbl_entry & 3;
// fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tamode, tofs); // fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tamode, tofs);
break; break;
case 3: // valid 8 byte descriptors case 3: // valid 8 byte descriptors
tofs *= 8; tofs *= 8;
// fprintf(stderr,"PMMU: reading table A entries at %08x\n", tofs + (root_aptr & 0xfffffffc)); // fprintf(stderr,"PMMU: reading table A entries at %08x\n", tofs + (root_aptr & 0xfffffffc));
tbl_entry2 = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc)); tbl_entry2 = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc));
tbl_entry = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc)+4); tbl_entry = m68k_read_memory_32( tofs + (root_aptr & 0xfffffffc)+4);
tamode = tbl_entry2 & 3; tamode = tbl_entry2 & 3;
// fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tamode, tofs); // fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tamode, tofs);
break; break;
} }
// get table B offset and pointer // get table B offset and pointer
tofs = (addr_in<<(is+abits))>>(32-bbits); tofs = (addr_in<<(is+abits))>>(32-bbits);
tptr = tbl_entry & 0xfffffff0; tptr = tbl_entry & 0xfffffff0;
// find out what format table B is, if any // find out what format table B is, if any
switch (tamode) switch (tamode)
{ {
case 0: // invalid, should cause MMU exception case 0: // invalid, should cause MMU exception
fatalerror("680x0 PMMU: Unhandled Table A mode %d (addr_in %08x)\n", tamode, addr_in); fatalerror("680x0 PMMU: Unhandled Table A mode %d (addr_in %08x)\n", tamode, addr_in);
break; break;
case 2: // 4-byte table B descriptor case 2: // 4-byte table B descriptor
tofs *= 4; tofs *= 4;
// fprintf(stderr,"PMMU: reading table B entry at %08x\n", tofs + tptr); // fprintf(stderr,"PMMU: reading table B entry at %08x\n", tofs + tptr);
tbl_entry = m68k_read_memory_32( tofs + tptr); tbl_entry = m68k_read_memory_32( tofs + tptr);
tbmode = tbl_entry & 3; tbmode = tbl_entry & 3;
// fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs); // fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs);
break; break;
case 3: // 8-byte table B descriptor case 3: // 8-byte table B descriptor
tofs *= 8; tofs *= 8;
// fprintf(stderr,"PMMU: reading table B entries at %08x\n", tofs + tptr); // fprintf(stderr,"PMMU: reading table B entries at %08x\n", tofs + tptr);
tbl_entry2 = m68k_read_memory_32( tofs + tptr); tbl_entry2 = m68k_read_memory_32( tofs + tptr);
tbl_entry = m68k_read_memory_32( tofs + tptr + 4); tbl_entry = m68k_read_memory_32( tofs + tptr + 4);
tbmode = tbl_entry2 & 3; tbmode = tbl_entry2 & 3;
// fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs); // fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs);
break; break;
case 1: // early termination descriptor case 1: // early termination descriptor
tbl_entry &= 0xffffff00; tbl_entry &= 0xffffff00;
shift = is+abits; shift = is+abits;
addr_out = ((addr_in<<shift)>>shift) + tbl_entry; addr_out = ((addr_in<<shift)>>shift) + tbl_entry;
resolved = 1; resolved = 1;
break; break;
} }
// if table A wasn't early-out, continue to process table B // if table A wasn't early-out, continue to process table B
if (!resolved) if (!resolved)
{ {
// get table C offset and pointer // get table C offset and pointer
tofs = (addr_in<<(is+abits+bbits))>>(32-cbits); tofs = (addr_in<<(is+abits+bbits))>>(32-cbits);
tptr = tbl_entry & 0xfffffff0; tptr = tbl_entry & 0xfffffff0;
switch (tbmode) switch (tbmode)
{ {
case 0: // invalid, should cause MMU exception case 0: // invalid, should cause MMU exception
fatalerror("680x0 PMMU: Unhandled Table B mode %d (addr_in %08x PC %x)\n", tbmode, addr_in, REG_PC); fatalerror("680x0 PMMU: Unhandled Table B mode %d (addr_in %08x PC %x)\n", tbmode, addr_in, REG_PC);
break; break;
case 2: // 4-byte table C descriptor case 2: // 4-byte table C descriptor
tofs *= 4; tofs *= 4;
// fprintf(stderr,"PMMU: reading table C entry at %08x\n", tofs + tptr); // fprintf(stderr,"PMMU: reading table C entry at %08x\n", tofs + tptr);
tbl_entry = m68k_read_memory_32(tofs + tptr); tbl_entry = m68k_read_memory_32(tofs + tptr);
tcmode = tbl_entry & 3; tcmode = tbl_entry & 3;
// fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs); // fprintf(stderr,"PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs);
break; break;
case 3: // 8-byte table C descriptor case 3: // 8-byte table C descriptor
tofs *= 8; tofs *= 8;
// fprintf(stderr,"PMMU: reading table C entries at %08x\n", tofs + tptr); // fprintf(stderr,"PMMU: reading table C entries at %08x\n", tofs + tptr);
tbl_entry2 = m68k_read_memory_32(tofs + tptr); tbl_entry2 = m68k_read_memory_32(tofs + tptr);
tbl_entry = m68k_read_memory_32(tofs + tptr + 4); tbl_entry = m68k_read_memory_32(tofs + tptr + 4);
tcmode = tbl_entry2 & 3; tcmode = tbl_entry2 & 3;
// fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs); // fprintf(stderr,"PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs);
break; break;
case 1: // termination descriptor case 1: // termination descriptor
tbl_entry &= 0xffffff00; tbl_entry &= 0xffffff00;
shift = is+abits+bbits; shift = is+abits+bbits;
addr_out = ((addr_in<<shift)>>shift) + tbl_entry; addr_out = ((addr_in<<shift)>>shift) + tbl_entry;
resolved = 1; resolved = 1;
break; break;
} }
} }
if (!resolved) if (!resolved)
{ {
switch (tcmode) switch (tcmode)
{ {
case 0: // invalid, should cause MMU exception case 0: // invalid, should cause MMU exception
case 2: // 4-byte ??? descriptor case 2: // 4-byte ??? descriptor
case 3: // 8-byte ??? descriptor case 3: // 8-byte ??? descriptor
fatalerror("680x0 PMMU: Unhandled Table B mode %d (addr_in %08x PC %x)\n", tbmode, addr_in, REG_PC); fatalerror("680x0 PMMU: Unhandled Table B mode %d (addr_in %08x PC %x)\n", tbmode, addr_in, REG_PC);
break; break;
case 1: // termination descriptor case 1: // termination descriptor
tbl_entry &= 0xffffff00; tbl_entry &= 0xffffff00;
shift = is+abits+bbits+cbits; shift = is+abits+bbits+cbits;
addr_out = ((addr_in<<shift)>>shift) + tbl_entry; addr_out = ((addr_in<<shift)>>shift) + tbl_entry;
resolved = 1; resolved = 1;
break; break;
} }
} }
// fprintf(stderr,"PMMU: [%08x] => [%08x]\n", addr_in, addr_out); // fprintf(stderr,"PMMU: [%08x] => [%08x]\n", addr_in, addr_out);
return addr_out; return addr_out;
} }
/* /*
m68881_mmu_ops: COP 0 MMU opcode handling m68881_mmu_ops: COP 0 MMU opcode handling
*/ */
void m68881_mmu_ops(void) void m68881_mmu_ops(void)
{ {
uint16 modes; uint16 modes;
uint32 ea = m68ki_cpu.ir & 0x3f; uint32 ea = m68ki_cpu.ir & 0x3f;
uint64 temp64; uint64 temp64;
// catch the 2 "weird" encodings up front (PBcc) // catch the 2 "weird" encodings up front (PBcc)
if ((m68ki_cpu.ir & 0xffc0) == 0xf0c0) if ((m68ki_cpu.ir & 0xffc0) == 0xf0c0)
{ {
fprintf(stderr,"680x0: unhandled PBcc\n"); fprintf(stderr,"680x0: unhandled PBcc\n");
return; return;
} }
else if ((m68ki_cpu.ir & 0xffc0) == 0xf080) else if ((m68ki_cpu.ir & 0xffc0) == 0xf080)
{ {
fprintf(stderr,"680x0: unhandled PBcc\n"); fprintf(stderr,"680x0: unhandled PBcc\n");
return; return;
} }
else // the rest are 1111000xxxXXXXXX where xxx is the instruction family else // the rest are 1111000xxxXXXXXX where xxx is the instruction family
{ {
switch ((m68ki_cpu.ir>>9) & 0x7) switch ((m68ki_cpu.ir>>9) & 0x7)
{ {
case 0: case 0:
modes = OPER_I_16(); modes = OPER_I_16();
if ((modes & 0xfde0) == 0x2000) // PLOAD if ((modes & 0xfde0) == 0x2000) // PLOAD
{ {
fprintf(stderr,"680x0: unhandled PLOAD\n"); fprintf(stderr,"680x0: unhandled PLOAD\n");
return; return;
} }
else if ((modes & 0xe200) == 0x2000) // PFLUSH else if ((modes & 0xe200) == 0x2000) // PFLUSH
{ {
fprintf(stderr,"680x0: unhandled PFLUSH PC=%x\n", REG_PC); fprintf(stderr,"680x0: unhandled PFLUSH PC=%x\n", REG_PC);
return; return;
} }
else if (modes == 0xa000) // PFLUSHR else if (modes == 0xa000) // PFLUSHR
{ {
fprintf(stderr,"680x0: unhandled PFLUSHR\n"); fprintf(stderr,"680x0: unhandled PFLUSHR\n");
return; return;
} }
else if (modes == 0x2800) // PVALID (FORMAT 1) else if (modes == 0x2800) // PVALID (FORMAT 1)
{ {
fprintf(stderr,"680x0: unhandled PVALID1\n"); fprintf(stderr,"680x0: unhandled PVALID1\n");
return; return;
} }
else if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2) else if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2)
{ {
fprintf(stderr,"680x0: unhandled PVALID2\n"); fprintf(stderr,"680x0: unhandled PVALID2\n");
return; return;
} }
else if ((modes & 0xe000) == 0x8000) // PTEST else if ((modes & 0xe000) == 0x8000) // PTEST
{ {
fprintf(stderr,"680x0: unhandled PTEST\n"); fprintf(stderr,"680x0: unhandled PTEST\n");
return; return;
} }
else else
{ {
switch ((modes>>13) & 0x7) switch ((modes>>13) & 0x7)
{ {
case 0: // MC68030/040 form with FD bit case 0: // MC68030/040 form with FD bit
case 2: // MC68881 form, FD never set case 2: // MC68881 form, FD never set
if (modes & 0x200) if (modes & 0x200)
{ {
switch ((modes>>10) & 7) switch ((modes>>10) & 7)
{ {
case 0: // translation control register case 0: // translation control register
WRITE_EA_32(ea, m68ki_cpu.mmu_tc); WRITE_EA_32(ea, m68ki_cpu.mmu_tc);
break; break;
case 2: // supervisor root pointer case 2: // supervisor root pointer
WRITE_EA_64(ea, (uint64)m68ki_cpu.mmu_srp_limit<<32 | (uint64)m68ki_cpu.mmu_srp_aptr); WRITE_EA_64(ea, (uint64)m68ki_cpu.mmu_srp_limit<<32 | (uint64)m68ki_cpu.mmu_srp_aptr);
break; break;
case 3: // CPU root pointer case 3: // CPU root pointer
WRITE_EA_64(ea, (uint64)m68ki_cpu.mmu_crp_limit<<32 | (uint64)m68ki_cpu.mmu_crp_aptr); WRITE_EA_64(ea, (uint64)m68ki_cpu.mmu_crp_limit<<32 | (uint64)m68ki_cpu.mmu_crp_aptr);
break; break;
default: default:
fprintf(stderr,"680x0: PMOVE from unknown MMU register %x, PC %x\n", (modes>>10) & 7, REG_PC); fprintf(stderr,"680x0: PMOVE from unknown MMU register %x, PC %x\n", (modes>>10) & 7, REG_PC);
break; break;
} }
} }
else else
{ {
switch ((modes>>10) & 7) switch ((modes>>10) & 7)
{ {
case 0: // translation control register case 0: // translation control register
m68ki_cpu.mmu_tc = READ_EA_32(ea); m68ki_cpu.mmu_tc = READ_EA_32(ea);
if (m68ki_cpu.mmu_tc & 0x80000000) if (m68ki_cpu.mmu_tc & 0x80000000)
{ {
m68ki_cpu.pmmu_enabled = 1; m68ki_cpu.pmmu_enabled = 1;
} }
else else
{ {
m68ki_cpu.pmmu_enabled = 0; m68ki_cpu.pmmu_enabled = 0;
} }
break; break;
case 2: // supervisor root pointer case 2: // supervisor root pointer
temp64 = READ_EA_64(ea); temp64 = READ_EA_64(ea);
m68ki_cpu.mmu_srp_limit = (temp64>>32) & 0xffffffff; m68ki_cpu.mmu_srp_limit = (temp64>>32) & 0xffffffff;
m68ki_cpu.mmu_srp_aptr = temp64 & 0xffffffff; m68ki_cpu.mmu_srp_aptr = temp64 & 0xffffffff;
break; break;
case 3: // CPU root pointer case 3: // CPU root pointer
temp64 = READ_EA_64(ea); temp64 = READ_EA_64(ea);
m68ki_cpu.mmu_crp_limit = (temp64>>32) & 0xffffffff; m68ki_cpu.mmu_crp_limit = (temp64>>32) & 0xffffffff;
m68ki_cpu.mmu_crp_aptr = temp64 & 0xffffffff; m68ki_cpu.mmu_crp_aptr = temp64 & 0xffffffff;
break; break;
default: default:
fprintf(stderr,"680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, REG_PC); fprintf(stderr,"680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, REG_PC);
break; break;
} }
} }
break; break;
case 3: // MC68030 to/from status reg case 3: // MC68030 to/from status reg
if (modes & 0x200) if (modes & 0x200)
{ {
WRITE_EA_32(ea, m68ki_cpu.mmu_sr); WRITE_EA_32(ea, m68ki_cpu.mmu_sr);
} }
else else
{ {
m68ki_cpu.mmu_sr = READ_EA_32(ea); m68ki_cpu.mmu_sr = READ_EA_32(ea);
} }
break; break;
default: default:
fprintf(stderr,"680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes>>13) & 0x7, modes, REG_PC); fprintf(stderr,"680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes>>13) & 0x7, modes, REG_PC);
break; break;
} }
} }
break; break;
default: default:
fprintf(stderr,"680x0: unknown PMMU instruction group %d\n", (m68ki_cpu.ir>>9) & 0x7); fprintf(stderr,"680x0: unknown PMMU instruction group %d\n", (m68ki_cpu.ir>>9) & 0x7);
break; break;
} }
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -47,13 +47,13 @@ typedef bits32 float32;
typedef bits64 float64; typedef bits64 float64;
#ifdef FLOATX80 #ifdef FLOATX80
typedef struct { typedef struct {
bits16 high; bits16 high;
bits64 low; bits64 low;
} floatx80; } floatx80;
#endif #endif
#ifdef FLOAT128 #ifdef FLOAT128
typedef struct { typedef struct {
bits64 high, low; bits64 high, low;
} float128; } float128;
#endif #endif
@ -69,8 +69,8 @@ typedef struct {
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
extern int8 float_detect_tininess; extern int8 float_detect_tininess;
enum { enum {
float_tininess_after_rounding = 0, float_tininess_after_rounding = 0,
float_tininess_before_rounding = 1 float_tininess_before_rounding = 1
}; };
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -78,10 +78,10 @@ enum {
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
extern int8 float_rounding_mode; extern int8 float_rounding_mode;
enum { enum {
float_round_nearest_even = 0, float_round_nearest_even = 0,
float_round_to_zero = 1, float_round_to_zero = 1,
float_round_down = 2, float_round_down = 2,
float_round_up = 3 float_round_up = 3
}; };
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -89,8 +89,8 @@ enum {
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
extern int8 float_exception_flags; extern int8 float_exception_flags;
enum { enum {
float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08, float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08,
float_flag_underflow = 0x10, float_flag_inexact = 0x20 float_flag_underflow = 0x10, float_flag_inexact = 0x20
}; };
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -208,11 +208,11 @@ floatx80 floatx80_scale(floatx80 a, floatx80 b);
static inline floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) static inline floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
{ {
floatx80 z; floatx80 z;
z.low = zSig; z.low = zSig;
z.high = ( ( (bits16) zSign )<<15 ) + zExp; z.high = ( ( (bits16) zSign )<<15 ) + zExp;
return z; return z;
} }
@ -301,13 +301,13 @@ flag float128_is_signaling_nan( float128 );
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static inline float128 static inline float128
packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
{ {
float128 z; float128 z;
z.low = zSig1; z.low = zSig1;
z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0; z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0;
return z; return z;
} }
@ -333,92 +333,92 @@ static inline float128
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static inline float128 static inline float128
roundAndPackFloat128( roundAndPackFloat128(
flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 ) flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 )
{ {
int8 roundingMode; int8 roundingMode;
flag roundNearestEven, increment, isTiny; flag roundNearestEven, increment, isTiny;
roundingMode = float_rounding_mode; roundingMode = float_rounding_mode;
roundNearestEven = ( roundingMode == float_round_nearest_even ); roundNearestEven = ( roundingMode == float_round_nearest_even );
increment = ( (sbits64) zSig2 < 0 ); increment = ( (sbits64) zSig2 < 0 );
if ( ! roundNearestEven ) { if ( ! roundNearestEven ) {
if ( roundingMode == float_round_to_zero ) { if ( roundingMode == float_round_to_zero ) {
increment = 0; increment = 0;
} }
else { else {
if ( zSign ) { if ( zSign ) {
increment = ( roundingMode == float_round_down ) && zSig2; increment = ( roundingMode == float_round_down ) && zSig2;
} }
else { else {
increment = ( roundingMode == float_round_up ) && zSig2; increment = ( roundingMode == float_round_up ) && zSig2;
} }
} }
} }
if ( 0x7FFD <= (bits32) zExp ) { if ( 0x7FFD <= (bits32) zExp ) {
if ( ( 0x7FFD < zExp ) if ( ( 0x7FFD < zExp )
|| ( ( zExp == 0x7FFD ) || ( ( zExp == 0x7FFD )
&& eq128( && eq128(
LIT64( 0x0001FFFFFFFFFFFF ), LIT64( 0x0001FFFFFFFFFFFF ),
LIT64( 0xFFFFFFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ),
zSig0, zSig0,
zSig1 zSig1
) )
&& increment && increment
) )
) { ) {
float_raise( float_flag_overflow | float_flag_inexact ); float_raise( float_flag_overflow | float_flag_inexact );
if ( ( roundingMode == float_round_to_zero ) if ( ( roundingMode == float_round_to_zero )
|| ( zSign && ( roundingMode == float_round_up ) ) || ( zSign && ( roundingMode == float_round_up ) )
|| ( ! zSign && ( roundingMode == float_round_down ) ) || ( ! zSign && ( roundingMode == float_round_down ) )
) { ) {
return return
packFloat128( packFloat128(
zSign, zSign,
0x7FFE, 0x7FFE,
LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x0000FFFFFFFFFFFF ),
LIT64( 0xFFFFFFFFFFFFFFFF ) LIT64( 0xFFFFFFFFFFFFFFFF )
); );
} }
return packFloat128( zSign, 0x7FFF, 0, 0 ); return packFloat128( zSign, 0x7FFF, 0, 0 );
} }
if ( zExp < 0 ) { if ( zExp < 0 ) {
isTiny = isTiny =
( float_detect_tininess == float_tininess_before_rounding ) ( float_detect_tininess == float_tininess_before_rounding )
|| ( zExp < -1 ) || ( zExp < -1 )
|| ! increment || ! increment
|| lt128( || lt128(
zSig0, zSig0,
zSig1, zSig1,
LIT64( 0x0001FFFFFFFFFFFF ), LIT64( 0x0001FFFFFFFFFFFF ),
LIT64( 0xFFFFFFFFFFFFFFFF ) LIT64( 0xFFFFFFFFFFFFFFFF )
); );
shift128ExtraRightJamming( shift128ExtraRightJamming(
zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 ); zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
zExp = 0; zExp = 0;
if ( isTiny && zSig2 ) float_raise( float_flag_underflow ); if ( isTiny && zSig2 ) float_raise( float_flag_underflow );
if ( roundNearestEven ) { if ( roundNearestEven ) {
increment = ( (sbits64) zSig2 < 0 ); increment = ( (sbits64) zSig2 < 0 );
} }
else { else {
if ( zSign ) { if ( zSign ) {
increment = ( roundingMode == float_round_down ) && zSig2; increment = ( roundingMode == float_round_down ) && zSig2;
} }
else { else {
increment = ( roundingMode == float_round_up ) && zSig2; increment = ( roundingMode == float_round_up ) && zSig2;
} }
} }
} }
} }
if ( zSig2 ) float_exception_flags |= float_flag_inexact; if ( zSig2 ) float_exception_flags |= float_flag_inexact;
if ( increment ) { if ( increment ) {
add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 ); add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven ); zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
} }
else { else {
if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0; if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
} }
return packFloat128( zSign, zExp, zSig0, zSig1 ); return packFloat128( zSign, zExp, zSig0, zSig1 );
} }
@ -433,28 +433,28 @@ static inline float128
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static inline float128 static inline float128
normalizeRoundAndPackFloat128( normalizeRoundAndPackFloat128(
flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
{ {
int8 shiftCount; int8 shiftCount;
bits64 zSig2; bits64 zSig2;
if ( zSig0 == 0 ) { if ( zSig0 == 0 ) {
zSig0 = zSig1; zSig0 = zSig1;
zSig1 = 0; zSig1 = 0;
zExp -= 64; zExp -= 64;
} }
shiftCount = countLeadingZeros64( zSig0 ) - 15; shiftCount = countLeadingZeros64( zSig0 ) - 15;
if ( 0 <= shiftCount ) { if ( 0 <= shiftCount ) {
zSig2 = 0; zSig2 = 0;
shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
} }
else { else {
shift128ExtraRightJamming( shift128ExtraRightJamming(
zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 ); zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
} }
zExp -= shiftCount; zExp -= shiftCount;
return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
} }
#endif #endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,180 +1,180 @@
/************************************************************************* /*************************************************************************
* * * *
* Copyright (c) 2022 Howard M. Harte. * * Copyright (c) 2022 Howard M. Harte. *
* https://github.com/hharte * * https://github.com/hharte *
* * * *
* Permission is hereby granted, free of charge, to any person obtaining * * Permission is hereby granted, free of charge, to any person obtaining *
* a copy of this software and associated documentation files (the * * a copy of this software and associated documentation files (the *
* "Software"), to deal in the Software without restriction, including * * "Software"), to deal in the Software without restriction, including *
* without limitation the rights to use, copy, modify, merge, publish, * * without limitation the rights to use, copy, modify, merge, publish, *
* distribute, sublicense, and/or sell copies of the Software, and to * * distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to * * permit persons to whom the Software is furnished to do so, subject to *
* the following conditions: * * the following conditions: *
* * * *
* The above copyright notice and this permission notice shall be * * The above copyright notice and this permission notice shall be *
* included in all copies or substantial portions of the Software. * * included in all copies or substantial portions of the Software. *
* * * *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON- * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON- *
* INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * * INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE *
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN *
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN *
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. * * SOFTWARE. *
* * * *
* Except as contained in this notice, the names of The Authors shall * * Except as contained in this notice, the names of The Authors shall *
* not be used in advertising or otherwise to promote the sale, use or * * not be used in advertising or otherwise to promote the sale, use or *
* other dealings in this Software without prior written authorization * * other dealings in this Software without prior written authorization *
* from the Authors. * * from the Authors. *
* * * *
* Based on s100_64fdc.c * * Based on s100_64fdc.c *
* * * *
* Module Description: * * Module Description: *
* Tarbell Double-Density Floppy Controller module for SIMH. * * Tarbell Double-Density Floppy Controller module for SIMH. *
* This module is a wrapper around the wd179x FDC module. * * This module is a wrapper around the wd179x FDC module. *
* * * *
* Reference: * * Reference: *
* http://www.bitsavers.org/pdf/tarbell/Tarbell_Double_Density_Floppy_Disk_Interface_Jul81.pdf * http://www.bitsavers.org/pdf/tarbell/Tarbell_Double_Density_Floppy_Disk_Interface_Jul81.pdf
* * * *
*************************************************************************/ *************************************************************************/
#include "altairz80_defs.h" #include "altairz80_defs.h"
#include "sim_defs.h" #include "sim_defs.h"
#include "wd179x.h" #include "wd179x.h"
#define DEV_NAME "TDD" #define DEV_NAME "TDD"
/* Debug flags */ /* Debug flags */
#define STATUS_MSG (1 << 0) #define STATUS_MSG (1 << 0)
#define DRIVE_MSG (1 << 1) #define DRIVE_MSG (1 << 1)
#define VERBOSE_MSG (1 << 2) #define VERBOSE_MSG (1 << 2)
#define IRQ_MSG (1 << 3) #define IRQ_MSG (1 << 3)
#define TDD_MAX_DRIVES 4 #define TDD_MAX_DRIVES 4
#define TDD_IO_BASE 0x7C #define TDD_IO_BASE 0x7C
#define TDD_IO_SIZE 0x2 #define TDD_IO_SIZE 0x2
#define TDD_IO_MASK (TDD_IO_SIZE - 1) #define TDD_IO_MASK (TDD_IO_SIZE - 1)
typedef struct { typedef struct {
PNP_INFO pnp; /* Plug and Play */ PNP_INFO pnp; /* Plug and Play */
} TDD_INFO; } TDD_INFO;
extern WD179X_INFO_PUB *wd179x_infop; extern WD179X_INFO_PUB *wd179x_infop;
static TDD_INFO tdd_info_data = { { 0x0000, 0, TDD_IO_BASE, TDD_IO_SIZE } }; static TDD_INFO tdd_info_data = { { 0x0000, 0, TDD_IO_BASE, TDD_IO_SIZE } };
extern t_stat set_iobase(UNIT *uptr, int32 val, CONST char *cptr, void *desc); extern t_stat set_iobase(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, CONST void *desc); extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
extern uint32 sim_map_resource(uint32 baseaddr, uint32 size, uint32 resource_type, extern uint32 sim_map_resource(uint32 baseaddr, uint32 size, uint32 resource_type,
int32 (*routine)(const int32, const int32, const int32), const char* name, uint8 unmap); int32 (*routine)(const int32, const int32, const int32), const char* name, uint8 unmap);
extern uint32 PCX; /* external view of PC */ extern uint32 PCX; /* external view of PC */
#define TDD_CAPACITY (77*1*26*128) /* Default SSSD 8" (IBM 3740) Disk Capacity */ #define TDD_CAPACITY (77*1*26*128) /* Default SSSD 8" (IBM 3740) Disk Capacity */
static t_stat tdd_reset(DEVICE *tdd_dev); static t_stat tdd_reset(DEVICE *tdd_dev);
static int32 tdd_control(const int32 port, const int32 io, const int32 data); static int32 tdd_control(const int32 port, const int32 io, const int32 data);
static const char* tdd_description(DEVICE *dptr); static const char* tdd_description(DEVICE *dptr);
#define TDD_FLAG_EOJ (1 << 7) /* End of Job (INTRQ) */ #define TDD_FLAG_EOJ (1 << 7) /* End of Job (INTRQ) */
static UNIT tdd_unit[] = { static UNIT tdd_unit[] = {
{ UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) }, { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) },
{ UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) }, { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) },
{ UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) }, { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) },
{ UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) } { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) }
}; };
static REG tdd_reg[] = { static REG tdd_reg[] = {
{ NULL } { NULL }
}; };
#define TDD_NAME "Tarbell Double-Density FDC" #define TDD_NAME "Tarbell Double-Density FDC"
static const char* tdd_description(DEVICE *dptr) { static const char* tdd_description(DEVICE *dptr) {
if (dptr == NULL) { if (dptr == NULL) {
return NULL; return NULL;
} }
return TDD_NAME; return TDD_NAME;
} }
static MTAB tdd_mod[] = { static MTAB tdd_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IOBASE", "IOBASE", { MTAB_XTD|MTAB_VDV, 0, "IOBASE", "IOBASE",
&set_iobase, &show_iobase, NULL, "Sets disk controller I/O base address" }, &set_iobase, &show_iobase, NULL, "Sets disk controller I/O base address" },
{ 0 } { 0 }
}; };
/* Debug Flags */ /* Debug Flags */
static DEBTAB tdd_dt[] = { static DEBTAB tdd_dt[] = {
{ "STATUS", STATUS_MSG, "Status messages" }, { "STATUS", STATUS_MSG, "Status messages" },
{ "DRIVE", DRIVE_MSG, "Drive messages" }, { "DRIVE", DRIVE_MSG, "Drive messages" },
{ "VERBOSE", VERBOSE_MSG, "Verbose messages" }, { "VERBOSE", VERBOSE_MSG, "Verbose messages" },
{ "IRQ", IRQ_MSG, "IRQ messages" }, { "IRQ", IRQ_MSG, "IRQ messages" },
{ NULL, 0 } { NULL, 0 }
}; };
DEVICE tdd_dev = { DEVICE tdd_dev = {
DEV_NAME, tdd_unit, tdd_reg, tdd_mod, DEV_NAME, tdd_unit, tdd_reg, tdd_mod,
TDD_MAX_DRIVES, 10, 31, 1, TDD_MAX_DRIVES, TDD_MAX_DRIVES, TDD_MAX_DRIVES, 10, 31, 1, TDD_MAX_DRIVES, TDD_MAX_DRIVES,
NULL, NULL, &tdd_reset, NULL, NULL, &tdd_reset,
NULL, &wd179x_attach, &wd179x_detach, NULL, &wd179x_attach, &wd179x_detach,
&tdd_info_data, (DEV_DISABLE | DEV_DIS | DEV_DEBUG), 0, &tdd_info_data, (DEV_DISABLE | DEV_DIS | DEV_DEBUG), 0,
tdd_dt, NULL, NULL, NULL, NULL, NULL, &tdd_description tdd_dt, NULL, NULL, NULL, NULL, NULL, &tdd_description
}; };
/* Reset routine */ /* Reset routine */
static t_stat tdd_reset(DEVICE *dptr) static t_stat tdd_reset(DEVICE *dptr)
{ {
PNP_INFO *pnp = (PNP_INFO *)dptr->ctxt; PNP_INFO *pnp = (PNP_INFO *)dptr->ctxt;
if(dptr->flags & DEV_DIS) { /* Disconnect ROM and I/O Ports */ if(dptr->flags & DEV_DIS) { /* Disconnect ROM and I/O Ports */
/* Unmap I/O Ports */ /* Unmap I/O Ports */
sim_map_resource(pnp->io_base, 1, RESOURCE_TYPE_IO, &tdd_control, "tdd_control", TRUE); sim_map_resource(pnp->io_base, 1, RESOURCE_TYPE_IO, &tdd_control, "tdd_control", TRUE);
} else { } else {
/* Connect TDD Disk Flags and Control Register */ /* Connect TDD Disk Flags and Control Register */
if(sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &tdd_control, "tdd_control", FALSE) != 0) { if(sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &tdd_control, "tdd_control", FALSE) != 0) {
sim_printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp->io_base); sim_printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp->io_base);
return SCPE_ARG; return SCPE_ARG;
} }
} }
return SCPE_OK; return SCPE_OK;
} }
/* Tarbell pp. 12-5 Disk Control/Status */ /* Tarbell pp. 12-5 Disk Control/Status */
static int32 tdd_control(const int32 port, const int32 io, const int32 data) static int32 tdd_control(const int32 port, const int32 io, const int32 data)
{ {
int32 result = 0; int32 result = 0;
if(io) { /* I/O Write */ if(io) { /* I/O Write */
if ((port & TDD_IO_MASK) == 0) { if ((port & TDD_IO_MASK) == 0) {
wd179x_infop->fdc_head = (data & 0x40) >> 6; wd179x_infop->fdc_head = (data & 0x40) >> 6;
wd179x_infop->sel_drive = (data & 0x30) >> 4; wd179x_infop->sel_drive = (data & 0x30) >> 4;
wd179x_infop->ddens = (data & 0x08) >> 3; wd179x_infop->ddens = (data & 0x08) >> 3;
sim_debug(DRIVE_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT " WR CTRL(0x%02x) = 0x%02x: Drive: %d, Head: %d, %s-Density.\n", sim_debug(DRIVE_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT " WR CTRL(0x%02x) = 0x%02x: Drive: %d, Head: %d, %s-Density.\n",
PCX, port, PCX, port,
data & 0xFF, data & 0xFF,
wd179x_infop->sel_drive, wd179x_infop->sel_drive,
wd179x_infop->fdc_head, wd179x_infop->fdc_head,
wd179x_infop->ddens == 1 ? "Double" : "Single"); wd179x_infop->ddens == 1 ? "Double" : "Single");
} else { } else {
sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT
" Write Extended Address, Port 0x%02x=0x%02x\n", PCX, port, data); " Write Extended Address, Port 0x%02x=0x%02x\n", PCX, port, data);
} }
} else { /* I/O Read */ } else { /* I/O Read */
if ((port & TDD_IO_MASK) == 0) { if ((port & TDD_IO_MASK) == 0) {
result = (wd179x_infop->intrq) ? 0 : TDD_FLAG_EOJ; result = (wd179x_infop->intrq) ? 0 : TDD_FLAG_EOJ;
sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT
" Read EOJ, Port 0x%02x Result 0x%02x\n", PCX, port, result); " Read EOJ, Port 0x%02x Result 0x%02x\n", PCX, port, result);
} else { } else {
result = (wd179x_infop->drq) ? TDD_FLAG_EOJ : 0; result = (wd179x_infop->drq) ? TDD_FLAG_EOJ : 0;
sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT
" Read DRQ, Port 0x%02x Result 0x%02x\n", PCX, port, result); " Read DRQ, Port 0x%02x Result 0x%02x\n", PCX, port, result);
} }
} }
return result; return result;
} }

View file

@ -1203,15 +1203,15 @@ static uint8 Do1793Command(uint8 cCommand)
" Verify ", wd179x_info->sel_drive, PCX); " Verify ", wd179x_info->sel_drive, PCX);
if (pDrive->uptr->u3 == IMAGE_TYPE_IMD) { if (pDrive->uptr->u3 == IMAGE_TYPE_IMD) {
if (sectSeek(pDrive->imd, pDrive->track, wd179x_info->fdc_head) != SCPE_OK) { if (sectSeek(pDrive->imd, pDrive->track, wd179x_info->fdc_head) != SCPE_OK) {
sim_debug(SEEK_MSG, &wd179x_dev, "FAILED\n"); sim_debug(SEEK_MSG, &wd179x_dev, "FAILED\n");
wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */ wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */
} else if (testMode(pDrive)) { } else if (testMode(pDrive)) {
wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */ wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */
sim_debug(SEEK_MSG, &wd179x_dev, "NOT FOUND\n"); sim_debug(SEEK_MSG, &wd179x_dev, "NOT FOUND\n");
} else { } else {
sim_debug(SEEK_MSG, &wd179x_dev, "Ok\n"); sim_debug(SEEK_MSG, &wd179x_dev, "Ok\n");
} }
} }
} }
if (pDrive->track == 0) { if (pDrive->track == 0) {

View file

@ -1252,7 +1252,7 @@ void vt_receive()
* <enter>HYC<enter> needs to be typed * <enter>HYC<enter> needs to be typed
* to re-initialize the line * to re-initialize the line
*/ */
TTY_IN |= mask; /* "long start" */ TTY_IN |= mask; /* "long start" */
break; break;
} }
switch (tty_unit[num].flags & TTY_CHARSET_MASK) { switch (tty_unit[num].flags & TTY_CHARSET_MASK) {

View file

@ -1,31 +1,31 @@
# Attaching the input device # Attaching the input device
at -t fs0 input.txt at -t fs0 input.txt
# Waiting for the end of initial setup # Waiting for the end of initial setup
expect -r "ДATA.*\n" expect -r "ДATA.*\n"
do dispak.ini do dispak.ini
# Now we're ready to send commands from the front panel # Now we're ready to send commands from the front panel
echo Requesting input from the punch tape reader (FS8), it takes a few seconds echo Requesting input from the punch tape reader (FS8), it takes a few seconds
d 6 1 d 6 1
d 5 10 d 5 10
set cpu req set cpu req
expect -r "Л0.*\n" expect -r "Л0.*\n"
go go
# The process had been started, check state every 10 model seconds # The process had been started, check state every 10 model seconds
send after=1000000 "WCPP\r" send after=1000000 "WCPP\r"
expect -p -r "4199.*\n" send after=10000000 "WCPP\r"; go expect -p -r "4199.*\n" send after=10000000 "WCPP\r"; go
expect -c "KЗ" step 10000000 expect -c "KЗ" step 10000000
expect -c "HET\r\n" step 10000 expect -c "HET\r\n" step 10000
go go
echo Enabling the printer (ONL A0) echo Enabling the printer (ONL A0)
d 6 10 d 6 10
d 5 1 d 5 1
set cpu req set cpu req
expect -r "ECT.*\n" expect -r "ECT.*\n"
go go
echo Checking for the printing to finish echo Checking for the printing to finish
send "HOMB\r" send "HOMB\r"
expect -p -r "A0.*\n" send "HOMB\r"; go expect -p -r "A0.*\n" send "HOMB\r"; go
expect -c "HET\r\n" expect -c "HET\r\n"
go go
echo Done echo Done

View file

@ -1363,12 +1363,12 @@ int32 sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
chk -= addr >> 8; chk -= addr >> 8;
for (i=0; i<HLEN; i++) { for (i=0; i<HLEN; i++) {
byte = get_mbyte(addr + i); byte = get_mbyte(addr + i);
fprintf(fileref, "%02X", byte & BYTEMASK); fprintf(fileref, "%02X", byte & BYTEMASK);
chk -= byte; chk &= BYTEMASK; chk -= byte; chk &= BYTEMASK;
cnt++; cnt++;
} }
fprintf(fileref,"%02X\n", chk & BYTEMASK); fprintf(fileref,"%02X\n", chk & BYTEMASK);
addr += HLEN; addr += HLEN;
} }
if(addr < end) { //last record if(addr < end) { //last record
fprintf(fileref, ":%02X%04X00", end - addr, addr); fprintf(fileref, ":%02X%04X00", end - addr, addr);
@ -1378,12 +1378,12 @@ int32 sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
chk -= addr >> 8; chk -= addr >> 8;
for (i=0; i<=(end - addr); i++) { for (i=0; i<=(end - addr); i++) {
byte = get_mbyte(addr + i); byte = get_mbyte(addr + i);
fprintf(fileref, "%02X", byte & BYTEMASK); fprintf(fileref, "%02X", byte & BYTEMASK);
chk -= byte; chk &= BYTEMASK; chk -= byte; chk &= BYTEMASK;
cnt++; cnt++;
} }
fprintf(fileref, "%02X\n", chk); fprintf(fileref, "%02X\n", chk);
addr = end; addr = end;
} }
fprintf(fileref,":00000001FF\n"); //EOF record fprintf(fileref,":00000001FF\n"); //EOF record
} else { //binary } else { //binary

View file

@ -1,299 +1,299 @@
/* nova_pt.c: NOVA paper tape read/punch simulator /* nova_pt.c: NOVA paper tape read/punch simulator
Copyright (c) 1993-2016, Robert M. Supnik Copyright (c) 1993-2016, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not be Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
ptr paper tape reader ptr paper tape reader
ptp paper tape punch ptp paper tape punch
13-May-16 RMS Lengthened wait time for DCC BASIC timing error 13-May-16 RMS Lengthened wait time for DCC BASIC timing error
28-Mar-15 RMS Revised to use sim_printf 28-Mar-15 RMS Revised to use sim_printf
04-Jul-07 BKR added PTR and PTP device DISABLE capability, 04-Jul-07 BKR added PTR and PTP device DISABLE capability,
added 7B/8B support PTR and PTP (default is 8B), added 7B/8B support PTR and PTP (default is 8B),
DEV_SET/CLR macros now used, DEV_SET/CLR macros now used,
PTR and PTP can now be DISABLED PTR and PTP can now be DISABLED
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
03-Oct-02 RMS Added DIBs 03-Oct-02 RMS Added DIBs
30-May-02 RMS Widened POS to 32b 30-May-02 RMS Widened POS to 32b
29-Nov-01 RMS Added read only unit support 29-Nov-01 RMS Added read only unit support
Notes: Notes:
- data masked to 7- or 8- bits, based on 7B or 8B, default is 8-bits - data masked to 7- or 8- bits, based on 7B or 8B, default is 8-bits
- register TIME is the delay between character read or write operations - register TIME is the delay between character read or write operations
- register POS show the number of characters read from or sent to the PTR or PTP - register POS show the number of characters read from or sent to the PTR or PTP
- register STOP_IOE determines return value issued if output to unattached PTR or PTP is attempted - register STOP_IOE determines return value issued if output to unattached PTR or PTP is attempted
*/ */
#include "nova_defs.h" #include "nova_defs.h"
extern int32 int_req, dev_busy, dev_done, dev_disable ; extern int32 int_req, dev_busy, dev_done, dev_disable ;
extern int32 SR ; extern int32 SR ;
extern t_stat cpu_boot(int32 unitno, DEVICE * dptr ) ; extern t_stat cpu_boot(int32 unitno, DEVICE * dptr ) ;
int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */ int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */
int32 ptr (int32 pulse, int32 code, int32 AC); int32 ptr (int32 pulse, int32 code, int32 AC);
int32 ptp (int32 pulse, int32 code, int32 AC); int32 ptp (int32 pulse, int32 code, int32 AC);
t_stat ptr_svc (UNIT *uptr); t_stat ptr_svc (UNIT *uptr);
t_stat ptp_svc (UNIT *uptr); t_stat ptp_svc (UNIT *uptr);
t_stat ptr_reset (DEVICE *dptr); t_stat ptr_reset (DEVICE *dptr);
t_stat ptp_reset (DEVICE *dptr); t_stat ptp_reset (DEVICE *dptr);
t_stat ptr_boot (int32 unitno, DEVICE *dptr); t_stat ptr_boot (int32 unitno, DEVICE *dptr);
/* 7 or 8 bit data mask support for either device */ /* 7 or 8 bit data mask support for either device */
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */ #define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */
#define UNIT_8B (1 << UNIT_V_8B) #define UNIT_8B (1 << UNIT_V_8B)
/* PTR data structures /* PTR data structures
ptr_dev PTR device descriptor ptr_dev PTR device descriptor
ptr_unit PTR unit descriptor ptr_unit PTR unit descriptor
ptr_reg PTR register list ptr_reg PTR register list
*/ */
DIB ptr_dib = { DEV_PTR, INT_PTR, PI_PTR, &ptr }; DIB ptr_dib = { DEV_PTR, INT_PTR, PI_PTR, &ptr };
UNIT ptr_unit = { /* 2007-May-30, bkr */ UNIT ptr_unit = { /* 2007-May-30, bkr */
UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE+UNIT_8B, 0), 300 UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE+UNIT_8B, 0), 300
}; };
REG ptr_reg[] = { REG ptr_reg[] = {
{ ORDATA (BUF, ptr_unit.buf, 8) }, { ORDATA (BUF, ptr_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_PTR) }, { FLDATA (BUSY, dev_busy, INT_V_PTR) },
{ FLDATA (DONE, dev_done, INT_V_PTR) }, { FLDATA (DONE, dev_done, INT_V_PTR) },
{ FLDATA (DISABLE, dev_disable, INT_V_PTR) }, { FLDATA (DISABLE, dev_disable, INT_V_PTR) },
{ FLDATA (INT, int_req, INT_V_PTR) }, { FLDATA (INT, int_req, INT_V_PTR) },
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptr_stopioe, 0) }, { FLDATA (STOP_IOE, ptr_stopioe, 0) },
{ NULL } { NULL }
}; };
MTAB ptr_mod[] = /* 2007-May-30, bkr */ MTAB ptr_mod[] = /* 2007-May-30, bkr */
{ {
{ UNIT_8B, 0, "7b", "7B", NULL }, { UNIT_8B, 0, "7b", "7B", NULL },
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL }, { UNIT_8B, UNIT_8B, "8b", "8B", NULL },
{ 0, 0, NULL, NULL, NULL } { 0, 0, NULL, NULL, NULL }
} ; } ;
DEVICE ptr_dev = { DEVICE ptr_dev = {
"PTR", &ptr_unit, ptr_reg, ptr_mod /* 2007-May-30, bkr */, "PTR", &ptr_unit, ptr_reg, ptr_mod /* 2007-May-30, bkr */,
1, 10, 31, 1, 8, 8, 1, 10, 31, 1, 8, 8,
NULL, NULL, &ptr_reset, NULL, NULL, &ptr_reset,
&ptr_boot, NULL, NULL, &ptr_boot, NULL, NULL,
&ptr_dib, DEV_DISABLE /* 2007-May-30, bkr */ &ptr_dib, DEV_DISABLE /* 2007-May-30, bkr */
}; };
/* PTP data structures /* PTP data structures
ptp_dev PTP device descriptor ptp_dev PTP device descriptor
ptp_unit PTP unit descriptor ptp_unit PTP unit descriptor
ptp_reg PTP register list ptp_reg PTP register list
*/ */
DIB ptp_dib = { DEV_PTP, INT_PTP, PI_PTP, &ptp }; DIB ptp_dib = { DEV_PTP, INT_PTP, PI_PTP, &ptp };
UNIT ptp_unit = UNIT ptp_unit =
{ {
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_8B, 0), SERIAL_OUT_WAIT UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_8B, 0), SERIAL_OUT_WAIT
}; };
REG ptp_reg[] = { REG ptp_reg[] = {
{ ORDATA (BUF, ptp_unit.buf, 8) }, { ORDATA (BUF, ptp_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_PTP) }, { FLDATA (BUSY, dev_busy, INT_V_PTP) },
{ FLDATA (DONE, dev_done, INT_V_PTP) }, { FLDATA (DONE, dev_done, INT_V_PTP) },
{ FLDATA (DISABLE, dev_disable, INT_V_PTP) }, { FLDATA (DISABLE, dev_disable, INT_V_PTP) },
{ FLDATA (INT, int_req, INT_V_PTP) }, { FLDATA (INT, int_req, INT_V_PTP) },
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptp_stopioe, 0) }, { FLDATA (STOP_IOE, ptp_stopioe, 0) },
{ NULL } { NULL }
}; };
MTAB ptp_mod[] = MTAB ptp_mod[] =
{ {
{ UNIT_8B, 0, "7b", "7B", NULL }, { UNIT_8B, 0, "7b", "7B", NULL },
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL }, { UNIT_8B, UNIT_8B, "8b", "8B", NULL },
{ 0, 0, NULL, NULL, NULL } { 0, 0, NULL, NULL, NULL }
} ; } ;
DEVICE ptp_dev = DEVICE ptp_dev =
{ {
"PTP", &ptp_unit, ptp_reg, ptp_mod /* 2007-May-30, bkr */, "PTP", &ptp_unit, ptp_reg, ptp_mod /* 2007-May-30, bkr */,
1, 10, 31, 1, 8, 8, 1, 10, 31, 1, 8, 8,
NULL, NULL, &ptp_reset, NULL, NULL, &ptp_reset,
NULL, NULL, NULL, NULL, NULL, NULL,
&ptp_dib, DEV_DISABLE /* 2007-May-30, bkr */ &ptp_dib, DEV_DISABLE /* 2007-May-30, bkr */
}; };
/* Paper tape reader: IOT routine */ /* Paper tape reader: IOT routine */
int32 ptr (int32 pulse, int32 code, int32 AC) int32 ptr (int32 pulse, int32 code, int32 AC)
{ {
int32 iodata; int32 iodata;
iodata = (code == ioDIA)? iodata = (code == ioDIA)?
ptr_unit.buf & 0377 ptr_unit.buf & 0377
: 0; : 0;
switch (pulse) switch (pulse)
{ /* decode IR<8:9> */ { /* decode IR<8:9> */
case iopS: /* start */ case iopS: /* start */
DEV_SET_BUSY( INT_PTR ) ; DEV_SET_BUSY( INT_PTR ) ;
DEV_CLR_DONE( INT_PTR ) ; DEV_CLR_DONE( INT_PTR ) ;
DEV_UPDATE_INTR ; DEV_UPDATE_INTR ;
sim_activate (&ptr_unit, ptr_unit.wait); /* activate unit */ sim_activate (&ptr_unit, ptr_unit.wait); /* activate unit */
break; break;
case iopC: /* clear */ case iopC: /* clear */
DEV_CLR_BUSY( INT_PTR ) ; DEV_CLR_BUSY( INT_PTR ) ;
DEV_CLR_DONE( INT_PTR ) ; DEV_CLR_DONE( INT_PTR ) ;
DEV_UPDATE_INTR ; DEV_UPDATE_INTR ;
sim_cancel (&ptr_unit); /* deactivate unit */ sim_cancel (&ptr_unit); /* deactivate unit */
break; break;
} /* end switch */ } /* end switch */
return iodata; return iodata;
} }
/* Unit service */ /* Unit service */
t_stat ptr_svc (UNIT *uptr) t_stat ptr_svc (UNIT *uptr)
{ {
int32 temp; int32 temp;
if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */ if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptr_stopioe, SCPE_UNATT); return IORETURN (ptr_stopioe, SCPE_UNATT);
if ((temp = getc (ptr_unit.fileref)) == EOF) { /* end of file? */ if ((temp = getc (ptr_unit.fileref)) == EOF) { /* end of file? */
if (feof (ptr_unit.fileref)) { if (feof (ptr_unit.fileref)) {
if (ptr_stopioe) if (ptr_stopioe)
sim_printf ("PTR end of file\n"); sim_printf ("PTR end of file\n");
else return SCPE_OK; else return SCPE_OK;
} }
else sim_perror ("PTR I/O error"); else sim_perror ("PTR I/O error");
clearerr (ptr_unit.fileref); clearerr (ptr_unit.fileref);
return SCPE_IOERR; return SCPE_IOERR;
} }
DEV_CLR_BUSY( INT_PTR ) ; DEV_CLR_BUSY( INT_PTR ) ;
DEV_SET_DONE( INT_PTR ) ; DEV_SET_DONE( INT_PTR ) ;
DEV_UPDATE_INTR ; DEV_UPDATE_INTR ;
ptr_unit.buf = temp & ((ptr_unit.flags & UNIT_8B)? 0377: 0177); ptr_unit.buf = temp & ((ptr_unit.flags & UNIT_8B)? 0377: 0177);
++(ptr_unit.pos); ++(ptr_unit.pos);
return SCPE_OK; return SCPE_OK;
} }
/* Reset routine */ /* Reset routine */
t_stat ptr_reset (DEVICE *dptr) t_stat ptr_reset (DEVICE *dptr)
{ {
ptr_unit.buf = 0; /* <not DG compatible> */ ptr_unit.buf = 0; /* <not DG compatible> */
DEV_CLR_BUSY( INT_PTR ) ; DEV_CLR_BUSY( INT_PTR ) ;
DEV_CLR_DONE( INT_PTR ) ; DEV_CLR_DONE( INT_PTR ) ;
DEV_UPDATE_INTR ; DEV_UPDATE_INTR ;
sim_cancel (&ptr_unit); /* deactivate unit */ sim_cancel (&ptr_unit); /* deactivate unit */
return SCPE_OK; return SCPE_OK;
} }
/* Boot routine */ /* Boot routine */
t_stat ptr_boot (int32 unitno, DEVICE *dptr) t_stat ptr_boot (int32 unitno, DEVICE *dptr)
{ {
ptr_reset( dptr ) ; ptr_reset( dptr ) ;
/* set position to 0? */ /* set position to 0? */
cpu_boot( unitno, dptr ) ; cpu_boot( unitno, dptr ) ;
SR = /* low-speed: no high-order bit set */ DEV_PTR ; SR = /* low-speed: no high-order bit set */ DEV_PTR ;
return ( SCPE_OK ); return ( SCPE_OK );
} /* end of 'ptr_boot' */ } /* end of 'ptr_boot' */
/* Paper tape punch: IOT routine */ /* Paper tape punch: IOT routine */
int32 ptp (int32 pulse, int32 code, int32 AC) int32 ptp (int32 pulse, int32 code, int32 AC)
{ {
if (code == ioDOA) if (code == ioDOA)
ptp_unit.buf = AC & 0377; ptp_unit.buf = AC & 0377;
switch (pulse) switch (pulse)
{ /* decode IR<8:9> */ { /* decode IR<8:9> */
case iopS: /* start */ case iopS: /* start */
DEV_SET_BUSY( INT_PTP ) ; DEV_SET_BUSY( INT_PTP ) ;
DEV_CLR_DONE( INT_PTP ) ; DEV_CLR_DONE( INT_PTP ) ;
DEV_UPDATE_INTR ; DEV_UPDATE_INTR ;
sim_activate (&ptp_unit, ptp_unit.wait); /* activate unit */ sim_activate (&ptp_unit, ptp_unit.wait); /* activate unit */
break; break;
case iopC: /* clear */ case iopC: /* clear */
DEV_CLR_BUSY( INT_PTP ) ; DEV_CLR_BUSY( INT_PTP ) ;
DEV_CLR_DONE( INT_PTP ) ; DEV_CLR_DONE( INT_PTP ) ;
DEV_UPDATE_INTR ; DEV_UPDATE_INTR ;
sim_cancel (&ptp_unit); /* deactivate unit */ sim_cancel (&ptp_unit); /* deactivate unit */
break; break;
} /* end switch */ } /* end switch */
return 0; return 0;
} }
/* Unit service */ /* Unit service */
t_stat ptp_svc (UNIT *uptr) t_stat ptp_svc (UNIT *uptr)
{ {
DEV_CLR_BUSY( INT_PTP ) ; DEV_CLR_BUSY( INT_PTP ) ;
DEV_SET_DONE( INT_PTP ) ; DEV_SET_DONE( INT_PTP ) ;
DEV_UPDATE_INTR ; DEV_UPDATE_INTR ;
if ((ptp_unit.flags & UNIT_ATT) == 0) /* attached? */ if ((ptp_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptp_stopioe, SCPE_UNATT); return IORETURN (ptp_stopioe, SCPE_UNATT);
if (putc ((ptp_unit.buf & ((ptp_unit.flags & UNIT_8B)? 0377: 0177)), ptp_unit.fileref) == EOF) { if (putc ((ptp_unit.buf & ((ptp_unit.flags & UNIT_8B)? 0377: 0177)), ptp_unit.fileref) == EOF) {
sim_perror ("PTP I/O error"); sim_perror ("PTP I/O error");
clearerr (ptp_unit.fileref); clearerr (ptp_unit.fileref);
return SCPE_IOERR; return SCPE_IOERR;
} }
++(ptp_unit.pos); ++(ptp_unit.pos);
return SCPE_OK; return SCPE_OK;
} }
/* Reset routine */ /* Reset routine */
t_stat ptp_reset (DEVICE *dptr) t_stat ptp_reset (DEVICE *dptr)
{ {
ptp_unit.buf = 0; /* <not DG compatible> */ ptp_unit.buf = 0; /* <not DG compatible> */
DEV_CLR_BUSY( INT_PTP ) ; DEV_CLR_BUSY( INT_PTP ) ;
DEV_CLR_DONE( INT_PTP ) ; DEV_CLR_DONE( INT_PTP ) ;
DEV_UPDATE_INTR ; DEV_UPDATE_INTR ;
sim_cancel (&ptp_unit); /* deactivate unit */ sim_cancel (&ptp_unit); /* deactivate unit */
return SCPE_OK; return SCPE_OK;
} }

View file

@ -1,9 +1,9 @@
# DDCMP synchronous line interface # DDCMP synchronous line interface
The DDCMP synchronous interface supported by the DUP and DMC device emulations, is a USB connected device that implements synchronous links for use by DDCMP. The DDCMP synchronous interface supported by the DUP and DMC device emulations, is a USB connected device that implements synchronous links for use by DDCMP.
When used with SIMH, the synchronous interface allows an emulated DMC-11 or DUP-11 (including KMC/DUP) to be connected to a system that uses a real synchronous link for DDCMP, for example an actual DMC-11 device. The interface can support either RS-232 connectons for the DUP-11 or DMC-11 "remote" line cards, or the "integral modem" coaxial cable connection implemented in the DMC "local" line card. Speeds in the range 500 to 56k bits per second (for RS-232) or 56k to 1M bits per second (for integral modem) are supported. When used with SIMH, the synchronous interface allows an emulated DMC-11 or DUP-11 (including KMC/DUP) to be connected to a system that uses a real synchronous link for DDCMP, for example an actual DMC-11 device. The interface can support either RS-232 connectons for the DUP-11 or DMC-11 "remote" line cards, or the "integral modem" coaxial cable connection implemented in the DMC "local" line card. Speeds in the range 500 to 56k bits per second (for RS-232) or 56k to 1M bits per second (for integral modem) are supported.
The DDCMP synchronous line interface is an open source design. All the design files (schematics, circuit board layout, firmware, and documentation) may be found on GitHub at [this link](https://github.com/pkoning2/ddcmp "DDCMP Framer on GitHub"). The DDCMP synchronous line interface is an open source design. All the design files (schematics, circuit board layout, firmware, and documentation) may be found on GitHub at [this link](https://github.com/pkoning2/ddcmp "DDCMP Framer on GitHub").
Note that at the moment, no boards, kits, or assembled units are offered. If you want a framer, you would need to obtain a circuit board and assemble it. The documentation in the GitHub design files explains how to do this. The design uses all "through hole" parts, so modest electronics assembly skills suffice to build a unit. Note that at the moment, no boards, kits, or assembled units are offered. If you want a framer, you would need to obtain a circuit board and assemble it. The documentation in the GitHub design files explains how to do this. The design uses all "through hole" parts, so modest electronics assembly skills suffice to build a unit.

View file

@ -844,8 +844,8 @@ for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) {
for (muxln = 0; muxln < DZ_LINES; muxln++) { for (muxln = 0; muxln < DZ_LINES; muxln++) {
TMLN *lp = &dz_ldsc[(dz * DZ_LINES) + muxln]; TMLN *lp = &dz_ldsc[(dz * DZ_LINES) + muxln];
if (lp->serconfig) if (lp->serconfig)
tmxr_set_config_line (lp, lp->serconfig); /* make settings consistent */ tmxr_set_config_line (lp, lp->serconfig); /* make settings consistent */
} }
if (!dz_mctl || (0 == (dz_csr[dz] & CSR_MSE))) /* enabled? */ if (!dz_mctl || (0 == (dz_csr[dz] & CSR_MSE))) /* enabled? */
continue; continue;
@ -873,10 +873,10 @@ for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) {
for (muxln = 0; muxln < DZ_LINES; muxln++) { for (muxln = 0; muxln < DZ_LINES; muxln++) {
TMLN *lp = &dz_ldsc[(dz * DZ_LINES) + muxln]; TMLN *lp = &dz_ldsc[(dz * DZ_LINES) + muxln];
free (lp->serconfig); free (lp->serconfig);
lp->serconfig = NULL; lp->serconfig = NULL;
} }
} }
return r; return r;
} }

View file

@ -46,17 +46,17 @@ static uint32 history[HSIZE];
/* BITS IN MBCSR */ /* BITS IN MBCSR */
#define MBINTE 0100 #define MBINTE 0100
#define MBAFRZ 0200 #define MBAFRZ 0200
#define MBXAYR 0400 /* X<A<Y READ TRAP */ #define MBXAYR 0400 /* X<A<Y READ TRAP */
#define MBXAYW 01000 /* X<A<Y WRITE TRAP */ #define MBXAYW 01000 /* X<A<Y WRITE TRAP */
#define MBNOIN 02000 /* IGNORE INIT */ #define MBNOIN 02000 /* IGNORE INIT */
#define MBINAO 04000 /* INTERRUPT ON ALMOST OVERFLOW */ #define MBINAO 04000 /* INTERRUPT ON ALMOST OVERFLOW */
/* BITS IN MBXHGH AND MBYHGH*/ /* BITS IN MBXHGH AND MBYHGH*/
#define MBREDT 04 /* READ TRAP BIT */ #define MBREDT 04 /* READ TRAP BIT */
#define MBWRTT 010 /* WRITE TRAP BIT */ #define MBWRTT 010 /* WRITE TRAP BIT */
/* BITS IN MBHHGH */ /* BITS IN MBHHGH */
#define MBWRTB 04 /* WRITE BIT IN HISTORY MEMORY HIGH BITS */ #define MBWRTB 04 /* WRITE BIT IN HISTORY MEMORY HIGH BITS */
#define IOLN_MB 020 #define IOLN_MB 020
DIB mb_dib = { DIB mb_dib = {

View file

@ -77,14 +77,14 @@ static uint16 RAM[64*FB];
#define TVINC 0077 /* Mask for the increment. */ #define TVINC 0077 /* Mask for the increment. */
/* TVSEL bits. */ /* TVSEL bits. */
#define TVRCNS 0077 /* The console number mask. */ #define TVRCNS 0077 /* The console number mask. */
#define TVNSH 0000 /* No shift write mode. */ #define TVNSH 0000 /* No shift write mode. */
#define TVIOR 0100 /* The inclusive or mode. */ #define TVIOR 0100 /* The inclusive or mode. */
#define TVXOR 0200 /* The xor mode. */ #define TVXOR 0200 /* The xor mode. */
#define TVMOV 0300 /* The move function. */ #define TVMOV 0300 /* The move function. */
/* TVSHR bits. */ /* TVSHR bits. */
#define TVSHCN 0017 /* The shift count. */ #define TVSHCN 0017 /* The shift count. */
/* TVCNSL bits. */ /* TVCNSL bits. */
#define SCROLL 007777 /* Scroll pointer. */ #define SCROLL 007777 /* Scroll pointer. */
@ -181,7 +181,7 @@ render_display (uint16 display)
if (display >= TV_WINDOWS) if (display >= TV_WINDOWS)
return; return;
sim_debug (DBG_VID, &tv_dev, "Render display %d buffer %d\n", sim_debug (DBG_VID, &tv_dev, "Render display %d buffer %d\n",
display, buffer); display, buffer);
for (i = 0; i < (TV_PIXELS / 8); i += 2) for (i = 0; i < (TV_PIXELS / 8); i += 2)
render_word (buffer, i); render_word (buffer, i);
tv_updated[display] = 1; tv_updated[display] = 1;

View file

@ -1,27 +1,27 @@
set g2out disabled set g2out disabled
set debug stdout set debug stdout
set dpy enabled set dpy enabled
set dpy debug set dpy debug
# Small test program. # Small test program.
dep -m 100 law 1000 dep -m 100 law 1000
dep -m 101 idla dep -m 101 idla
dep -m 102 idsi dep -m 102 idsi
dep -m 103 jmp 102 dep -m 103 jmp 102
dep -m 104 jmp 100 dep -m 104 jmp 100
# Small display list. # Small display list.
#Go to point mode, set scale, set intensity. #Go to point mode, set scale, set intensity.
dep 1000 020117 dep 1000 020117
#Stay in point mode, set x=1000. #Stay in point mode, set x=1000.
dep 1001 021000 dep 1001 021000
#Go to vector mode, set y=1000. #Go to vector mode, set y=1000.
dep 1002 301000 dep 1002 301000
#Escape, intensify, delta x=100. #Escape, intensify, delta x=100.
dep 1003 600100 dep 1003 600100
#Stop. #Stop.
dep 1004 003000 dep 1004 003000
dep pc 100 dep pc 100
# Ready to go or single step. # Ready to go or single step.

View file

@ -90,4 +90,4 @@
#define UNIT_MODE_TEST (1 << UNIT_V_MODE) #define UNIT_MODE_TEST (1 << UNIT_V_MODE)
#endif /* TX0_DEFS_H_ */ #endif /* TX0_DEFS_H_ */

View file

@ -97,7 +97,7 @@ iii_draw_line(int x1, int y1, int x2, int y2, int l)
if (dy == 0) { if (dy == 0) {
for (i = 1; i < dx; i++) { for (i = 1; i < dx; i++) {
display_point(x1, y1, l, 0); display_point(x1, y1, l, 0);
x1+=ax; x1+=ax;
} }
return; return;
} }

View file

@ -1,9 +1,9 @@
# Attach to a server. If the remote port isn't telnet, append ;notelnet. # Attach to a server. If the remote port isn't telnet, append ;notelnet.
attach tty 12345,connect=localhost:23 attach tty 12345,connect=localhost:23
# Configure a bootstrap ROM; some programs require this. # Configure a bootstrap ROM; some programs require this.
set rom type=stty set rom type=stty
# Load SSV version 22. # Load SSV version 22.
load -s ssv22.iml load -s ssv22.iml
# Reset and run. # Reset and run.
reset reset
go go

8
scp.c
View file

@ -6637,10 +6637,10 @@ if (vdelt) {
if (1) { if (1) {
char mode[] = S_xstr(SIM_VERSION_MODE); char mode[] = S_xstr(SIM_VERSION_MODE);
if (NULL != strchr (mode, '\"')) { /* Quoted String? */ if (NULL != strchr (mode, '\"')) { /* Quoted String? */
mode[strlen (mode) - 1] = '\0'; /* strip quotes */ mode[strlen (mode) - 1] = '\0'; /* strip quotes */
memmove (mode, mode + 1, strlen (mode)); memmove (mode, mode + 1, strlen (mode));
} }
fprintf (st, " %s", mode); fprintf (st, " %s", mode);
setenv ("SIM_VERSION_MODE", mode, 1); setenv ("SIM_VERSION_MODE", mode, 1);
} }

View file

@ -1,43 +1,43 @@
/* /*
* QEMU System Emulator * QEMU System Emulator
* *
* Copyright (c) 2003-2008 Fabrice Bellard * Copyright (c) 2003-2008 Fabrice Bellard
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef QEMU_MAIN_LOOP_H #ifndef QEMU_MAIN_LOOP_H
#define QEMU_MAIN_LOOP_H 1 #define QEMU_MAIN_LOOP_H 1
/** /**
* qemu_notify_event: Force processing of pending events. * qemu_notify_event: Force processing of pending events.
* *
* Similar to signaling a condition variable, qemu_notify_event forces * Similar to signaling a condition variable, qemu_notify_event forces
* main_loop_wait to look at pending events and exit. The caller of * main_loop_wait to look at pending events and exit. The caller of
* main_loop_wait will usually call it again very soon, so qemu_notify_event * main_loop_wait will usually call it again very soon, so qemu_notify_event
* also has the side effect of recalculating the sets of file descriptors * also has the side effect of recalculating the sets of file descriptors
* that the main loop waits for. * that the main loop waits for.
* *
* Calling qemu_notify_event is rarely necessary, because main loop * Calling qemu_notify_event is rarely necessary, because main loop
* services (bottom halves and timers) call it themselves. * services (bottom halves and timers) call it themselves.
*/ */
void qemu_notify_event(void); void qemu_notify_event(void);
#endif #endif

View file

@ -1,8 +1,8 @@
#ifndef MONITOR_H #ifndef MONITOR_H
#define MONITOR_H #define MONITOR_H
#include "qemu-common.h" #include "qemu-common.h"
void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3); void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
#endif /* !MONITOR_H */ #endif /* !MONITOR_H */

View file

@ -1,54 +1,54 @@
/* Common header file that is included by all of QEMU. /* Common header file that is included by all of QEMU.
* *
* This file is supposed to be included only by .c files. No header file should * This file is supposed to be included only by .c files. No header file should
* depend on qemu-common.h, as this would easily lead to circular header * depend on qemu-common.h, as this would easily lead to circular header
* dependencies. * dependencies.
* *
* If a header file uses a definition from qemu-common.h, that definition * If a header file uses a definition from qemu-common.h, that definition
* must be moved to a separate header file, and the header that uses it * must be moved to a separate header file, and the header that uses it
* must include that header. * must include that header.
*/ */
#ifndef QEMU_COMMON_H #ifndef QEMU_COMMON_H
#define QEMU_COMMON_H #define QEMU_COMMON_H
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qemu/typedefs.h" #include "qemu/typedefs.h"
#include "glib.h" #include "glib.h"
#include "config-host.h" #include "config-host.h"
#if defined(O_BINARY) /* O_BINARY isn't used in slirp */ #if defined(O_BINARY) /* O_BINARY isn't used in slirp */
#undef O_BINARY /* Avoid potential redefinition elsewhere */ #undef O_BINARY /* Avoid potential redefinition elsewhere */
#endif #endif
/* HOST_LONG_BITS is the size of a native pointer in bits. */ /* HOST_LONG_BITS is the size of a native pointer in bits. */
#if UINTPTR_MAX == UINT32_MAX #if UINTPTR_MAX == UINT32_MAX
# define HOST_LONG_BITS 32 # define HOST_LONG_BITS 32
#elif UINTPTR_MAX == UINT64_MAX #elif UINTPTR_MAX == UINT64_MAX
# define HOST_LONG_BITS 64 # define HOST_LONG_BITS 64
#else #else
# error Unknown pointer size # error Unknown pointer size
#endif #endif
/* util/cutils.c */ /* util/cutils.c */
/** /**
* pstrcpy: * pstrcpy:
* @buf: buffer to copy string into * @buf: buffer to copy string into
* @buf_size: size of @buf in bytes * @buf_size: size of @buf in bytes
* @str: string to copy * @str: string to copy
* *
* Copy @str into @buf, including the trailing NUL, but do not * Copy @str into @buf, including the trailing NUL, but do not
* write more than @buf_size bytes. The resulting buffer is * write more than @buf_size bytes. The resulting buffer is
* always NUL terminated (even if the source string was too long). * always NUL terminated (even if the source string was too long).
* If @buf_size is zero or negative then no bytes are copied. * If @buf_size is zero or negative then no bytes are copied.
* *
* This function is similar to strncpy(), but avoids two of that * This function is similar to strncpy(), but avoids two of that
* function's problems: * function's problems:
* * if @str fits in the buffer, pstrcpy() does not zero-fill the * * if @str fits in the buffer, pstrcpy() does not zero-fill the
* remaining space at the end of @buf * remaining space at the end of @buf
* * if @str is too long, pstrcpy() will copy the first @buf_size-1 * * if @str is too long, pstrcpy() will copy the first @buf_size-1
* bytes and then add a NUL * bytes and then add a NUL
*/ */
void pstrcpy(char *buf, int buf_size, const char *str); void pstrcpy(char *buf, int buf_size, const char *str);
#endif #endif

View file

@ -1,431 +1,431 @@
/* $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */ /* $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
/* /*
* QEMU version: Copy from netbsd, removed debug code, removed some of * QEMU version: Copy from netbsd, removed debug code, removed some of
* the implementations. Left in singly-linked lists, lists, simple * the implementations. Left in singly-linked lists, lists, simple
* queues, and tail queues. * queues, and tail queues.
*/ */
/* /*
* Copyright (c) 1991, 1993 * Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)queue.h 8.5 (Berkeley) 8/20/94 * @(#)queue.h 8.5 (Berkeley) 8/20/94
*/ */
#ifndef QEMU_SYS_QUEUE_H_ #ifndef QEMU_SYS_QUEUE_H_
#define QEMU_SYS_QUEUE_H_ #define QEMU_SYS_QUEUE_H_
/* /*
* This file defines four types of data structures: singly-linked lists, * This file defines four types of data structures: singly-linked lists,
* lists, simple queues, and tail queues. * lists, simple queues, and tail queues.
* *
* A singly-linked list is headed by a single forward pointer. The * A singly-linked list is headed by a single forward pointer. The
* elements are singly linked for minimum space and pointer manipulation * elements are singly linked for minimum space and pointer manipulation
* overhead at the expense of O(n) removal for arbitrary elements. New * overhead at the expense of O(n) removal for arbitrary elements. New
* elements can be added to the list after an existing element or at the * elements can be added to the list after an existing element or at the
* head of the list. Elements being removed from the head of the list * head of the list. Elements being removed from the head of the list
* should use the explicit macro for this purpose for optimum * should use the explicit macro for this purpose for optimum
* efficiency. A singly-linked list may only be traversed in the forward * efficiency. A singly-linked list may only be traversed in the forward
* direction. Singly-linked lists are ideal for applications with large * direction. Singly-linked lists are ideal for applications with large
* datasets and few or no removals or for implementing a LIFO queue. * datasets and few or no removals or for implementing a LIFO queue.
* *
* A list is headed by a single forward pointer (or an array of forward * A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked * pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to * so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before * traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list * or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction. * may only be traversed in the forward direction.
* *
* A simple queue is headed by a pair of pointers, one the head of the * A simple queue is headed by a pair of pointers, one the head of the
* list and the other to the tail of the list. The elements are singly * list and the other to the tail of the list. The elements are singly
* linked to save space, so elements can only be removed from the * linked to save space, so elements can only be removed from the
* head of the list. New elements can be added to the list after * head of the list. New elements can be added to the list after
* an existing element, at the head of the list, or at the end of the * an existing element, at the head of the list, or at the end of the
* list. A simple queue may only be traversed in the forward direction. * list. A simple queue may only be traversed in the forward direction.
* *
* A tail queue is headed by a pair of pointers, one to the head of the * A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly * list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to * linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or * traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of * after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction. * the list. A tail queue may be traversed in either direction.
* *
* For details on the use of these macros, see the queue(3) manual page. * For details on the use of these macros, see the queue(3) manual page.
*/ */
/* /*
* List definitions. * List definitions.
*/ */
#define QLIST_HEAD(name, type) \ #define QLIST_HEAD(name, type) \
struct name { \ struct name { \
struct type *lh_first; /* first element */ \ struct type *lh_first; /* first element */ \
} }
#define QLIST_HEAD_INITIALIZER(head) \ #define QLIST_HEAD_INITIALIZER(head) \
{ NULL } { NULL }
#define QLIST_ENTRY(type) \ #define QLIST_ENTRY(type) \
struct { \ struct { \
struct type *le_next; /* next element */ \ struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \ struct type **le_prev; /* address of previous next element */ \
} }
/* /*
* List functions. * List functions.
*/ */
#define QLIST_INIT(head) do { \ #define QLIST_INIT(head) do { \
(head)->lh_first = NULL; \ (head)->lh_first = NULL; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QLIST_SWAP(dstlist, srclist, field) do { \ #define QLIST_SWAP(dstlist, srclist, field) do { \
void *tmplist; \ void *tmplist; \
tmplist = (srclist)->lh_first; \ tmplist = (srclist)->lh_first; \
(srclist)->lh_first = (dstlist)->lh_first; \ (srclist)->lh_first = (dstlist)->lh_first; \
if ((srclist)->lh_first != NULL) { \ if ((srclist)->lh_first != NULL) { \
(srclist)->lh_first->field.le_prev = &(srclist)->lh_first; \ (srclist)->lh_first->field.le_prev = &(srclist)->lh_first; \
} \ } \
(dstlist)->lh_first = tmplist; \ (dstlist)->lh_first = tmplist; \
if ((dstlist)->lh_first != NULL) { \ if ((dstlist)->lh_first != NULL) { \
(dstlist)->lh_first->field.le_prev = &(dstlist)->lh_first; \ (dstlist)->lh_first->field.le_prev = &(dstlist)->lh_first; \
} \ } \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QLIST_FIX_HEAD_PTR(head, field) do { \ #define QLIST_FIX_HEAD_PTR(head, field) do { \
if ((head)->lh_first != NULL) { \ if ((head)->lh_first != NULL) { \
(head)->lh_first->field.le_prev = &(head)->lh_first; \ (head)->lh_first->field.le_prev = &(head)->lh_first; \
} \ } \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QLIST_INSERT_AFTER(listelm, elm, field) do { \ #define QLIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \ (listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \ &(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \ (listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \ (elm)->field.le_prev = &(listelm)->field.le_next; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QLIST_INSERT_BEFORE(listelm, elm, field) do { \ #define QLIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \ (elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \ (elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \ *(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \ (listelm)->field.le_prev = &(elm)->field.le_next; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QLIST_INSERT_HEAD(head, elm, field) do { \ #define QLIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \ (head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \ (elm)->field.le_prev = &(head)->lh_first; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QLIST_REMOVE(elm, field) do { \ #define QLIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \ if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \ (elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \ (elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \ *(elm)->field.le_prev = (elm)->field.le_next; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QLIST_FOREACH(var, head, field) \ #define QLIST_FOREACH(var, head, field) \
for ((var) = ((head)->lh_first); \ for ((var) = ((head)->lh_first); \
(var); \ (var); \
(var) = ((var)->field.le_next)) (var) = ((var)->field.le_next))
#define QLIST_FOREACH_SAFE(var, head, field, next_var) \ #define QLIST_FOREACH_SAFE(var, head, field, next_var) \
for ((var) = ((head)->lh_first); \ for ((var) = ((head)->lh_first); \
(var) && ((next_var) = ((var)->field.le_next), 1); \ (var) && ((next_var) = ((var)->field.le_next), 1); \
(var) = (next_var)) (var) = (next_var))
/* /*
* List access methods. * List access methods.
*/ */
#define QLIST_EMPTY(head) ((head)->lh_first == NULL) #define QLIST_EMPTY(head) ((head)->lh_first == NULL)
#define QLIST_FIRST(head) ((head)->lh_first) #define QLIST_FIRST(head) ((head)->lh_first)
#define QLIST_NEXT(elm, field) ((elm)->field.le_next) #define QLIST_NEXT(elm, field) ((elm)->field.le_next)
/* /*
* Singly-linked List definitions. * Singly-linked List definitions.
*/ */
#define QSLIST_HEAD(name, type) \ #define QSLIST_HEAD(name, type) \
struct name { \ struct name { \
struct type *slh_first; /* first element */ \ struct type *slh_first; /* first element */ \
} }
#define QSLIST_HEAD_INITIALIZER(head) \ #define QSLIST_HEAD_INITIALIZER(head) \
{ NULL } { NULL }
#define QSLIST_ENTRY(type) \ #define QSLIST_ENTRY(type) \
struct { \ struct { \
struct type *sle_next; /* next element */ \ struct type *sle_next; /* next element */ \
} }
/* /*
* Singly-linked List functions. * Singly-linked List functions.
*/ */
#define QSLIST_INIT(head) do { \ #define QSLIST_INIT(head) do { \
(head)->slh_first = NULL; \ (head)->slh_first = NULL; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSLIST_INSERT_AFTER(slistelm, elm, field) do { \ #define QSLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \ (elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \ (slistelm)->field.sle_next = (elm); \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSLIST_INSERT_HEAD(head, elm, field) do { \ #define QSLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \ (elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \ (head)->slh_first = (elm); \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSLIST_REMOVE_HEAD(head, field) do { \ #define QSLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \ (head)->slh_first = (head)->slh_first->field.sle_next; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSLIST_REMOVE_AFTER(slistelm, field) do { \ #define QSLIST_REMOVE_AFTER(slistelm, field) do { \
(slistelm)->field.sle_next = \ (slistelm)->field.sle_next = \
QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field); \ QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field); \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSLIST_FOREACH(var, head, field) \ #define QSLIST_FOREACH(var, head, field) \
for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
#define QSLIST_FOREACH_SAFE(var, head, field, tvar) \ #define QSLIST_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = QSLIST_FIRST((head)); \ for ((var) = QSLIST_FIRST((head)); \
(var) && ((tvar) = QSLIST_NEXT((var), field), 1); \ (var) && ((tvar) = QSLIST_NEXT((var), field), 1); \
(var) = (tvar)) (var) = (tvar))
/* /*
* Singly-linked List access methods. * Singly-linked List access methods.
*/ */
#define QSLIST_EMPTY(head) ((head)->slh_first == NULL) #define QSLIST_EMPTY(head) ((head)->slh_first == NULL)
#define QSLIST_FIRST(head) ((head)->slh_first) #define QSLIST_FIRST(head) ((head)->slh_first)
#define QSLIST_NEXT(elm, field) ((elm)->field.sle_next) #define QSLIST_NEXT(elm, field) ((elm)->field.sle_next)
/* /*
* Simple queue definitions. * Simple queue definitions.
*/ */
#define QSIMPLEQ_HEAD(name, type) \ #define QSIMPLEQ_HEAD(name, type) \
struct name { \ struct name { \
struct type *sqh_first; /* first element */ \ struct type *sqh_first; /* first element */ \
struct type **sqh_last; /* addr of last next element */ \ struct type **sqh_last; /* addr of last next element */ \
} }
#define QSIMPLEQ_HEAD_INITIALIZER(head) \ #define QSIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first } { NULL, &(head).sqh_first }
#define QSIMPLEQ_ENTRY(type) \ #define QSIMPLEQ_ENTRY(type) \
struct { \ struct { \
struct type *sqe_next; /* next element */ \ struct type *sqe_next; /* next element */ \
} }
/* /*
* Simple queue functions. * Simple queue functions.
*/ */
#define QSIMPLEQ_INIT(head) do { \ #define QSIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \ (head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \ (head)->sqh_last = &(head)->sqh_first; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSIMPLEQ_INSERT_HEAD(head, elm, field) do { \ #define QSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \ (head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \ (head)->sqh_first = (elm); \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSIMPLEQ_INSERT_TAIL(head, elm, field) do { \ #define QSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \ (elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \ *(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \ (head)->sqh_last = &(elm)->field.sqe_next; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ #define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL) \ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \ (head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \ (listelm)->field.sqe_next = (elm); \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSIMPLEQ_REMOVE_HEAD(head, field) do { \ #define QSIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\ if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\
(head)->sqh_last = &(head)->sqh_first; \ (head)->sqh_last = &(head)->sqh_first; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do { \ #define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do { \
QSIMPLEQ_INIT(removed); \ QSIMPLEQ_INIT(removed); \
if (((removed)->sqh_first = (head)->sqh_first) != NULL) { \ if (((removed)->sqh_first = (head)->sqh_first) != NULL) { \
if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) { \ if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) { \
(head)->sqh_last = &(head)->sqh_first; \ (head)->sqh_last = &(head)->sqh_first; \
} \ } \
(removed)->sqh_last = &(elm)->field.sqe_next; \ (removed)->sqh_last = &(elm)->field.sqe_next; \
(elm)->field.sqe_next = NULL; \ (elm)->field.sqe_next = NULL; \
} \ } \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSIMPLEQ_REMOVE(head, elm, type, field) do { \ #define QSIMPLEQ_REMOVE(head, elm, type, field) do { \
if ((head)->sqh_first == (elm)) { \ if ((head)->sqh_first == (elm)) { \
QSIMPLEQ_REMOVE_HEAD((head), field); \ QSIMPLEQ_REMOVE_HEAD((head), field); \
} else { \ } else { \
struct type *curelm = (head)->sqh_first; \ struct type *curelm = (head)->sqh_first; \
while (curelm->field.sqe_next != (elm)) \ while (curelm->field.sqe_next != (elm)) \
curelm = curelm->field.sqe_next; \ curelm = curelm->field.sqe_next; \
if ((curelm->field.sqe_next = \ if ((curelm->field.sqe_next = \
curelm->field.sqe_next->field.sqe_next) == NULL) \ curelm->field.sqe_next->field.sqe_next) == NULL) \
(head)->sqh_last = &(curelm)->field.sqe_next; \ (head)->sqh_last = &(curelm)->field.sqe_next; \
} \ } \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSIMPLEQ_FOREACH(var, head, field) \ #define QSIMPLEQ_FOREACH(var, head, field) \
for ((var) = ((head)->sqh_first); \ for ((var) = ((head)->sqh_first); \
(var); \ (var); \
(var) = ((var)->field.sqe_next)) (var) = ((var)->field.sqe_next))
#define QSIMPLEQ_FOREACH_SAFE(var, head, field, next) \ #define QSIMPLEQ_FOREACH_SAFE(var, head, field, next) \
for ((var) = ((head)->sqh_first); \ for ((var) = ((head)->sqh_first); \
(var) && ((next = ((var)->field.sqe_next)), 1); \ (var) && ((next = ((var)->field.sqe_next)), 1); \
(var) = (next)) (var) = (next))
#define QSIMPLEQ_CONCAT(head1, head2) do { \ #define QSIMPLEQ_CONCAT(head1, head2) do { \
if (!QSIMPLEQ_EMPTY((head2))) { \ if (!QSIMPLEQ_EMPTY((head2))) { \
*(head1)->sqh_last = (head2)->sqh_first; \ *(head1)->sqh_last = (head2)->sqh_first; \
(head1)->sqh_last = (head2)->sqh_last; \ (head1)->sqh_last = (head2)->sqh_last; \
QSIMPLEQ_INIT((head2)); \ QSIMPLEQ_INIT((head2)); \
} \ } \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QSIMPLEQ_LAST(head, type, field) \ #define QSIMPLEQ_LAST(head, type, field) \
(QSIMPLEQ_EMPTY((head)) ? \ (QSIMPLEQ_EMPTY((head)) ? \
NULL : \ NULL : \
((struct type *)(void *) \ ((struct type *)(void *) \
((char *)((head)->sqh_last) - offsetof(struct type, field)))) ((char *)((head)->sqh_last) - offsetof(struct type, field))))
/* /*
* Simple queue access methods. * Simple queue access methods.
*/ */
#define QSIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL) #define QSIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
#define QSIMPLEQ_FIRST(head) ((head)->sqh_first) #define QSIMPLEQ_FIRST(head) ((head)->sqh_first)
#define QSIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) #define QSIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
/* /*
* Tail queue definitions. * Tail queue definitions.
*/ */
#define Q_TAILQ_HEAD(name, type, qual) \ #define Q_TAILQ_HEAD(name, type, qual) \
struct name { \ struct name { \
qual type *tqh_first; /* first element */ \ qual type *tqh_first; /* first element */ \
qual type *qual *tqh_last; /* addr of last next element */ \ qual type *qual *tqh_last; /* addr of last next element */ \
} }
#define QTAILQ_HEAD(name, type) Q_TAILQ_HEAD(name, struct type,) #define QTAILQ_HEAD(name, type) Q_TAILQ_HEAD(name, struct type,)
#define QTAILQ_HEAD_INITIALIZER(head) \ #define QTAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first } { NULL, &(head).tqh_first }
#define Q_TAILQ_ENTRY(type, qual) \ #define Q_TAILQ_ENTRY(type, qual) \
struct { \ struct { \
qual type *tqe_next; /* next element */ \ qual type *tqe_next; /* next element */ \
qual type *qual *tqe_prev; /* address of previous next element */\ qual type *qual *tqe_prev; /* address of previous next element */\
} }
#define QTAILQ_ENTRY(type) Q_TAILQ_ENTRY(struct type,) #define QTAILQ_ENTRY(type) Q_TAILQ_ENTRY(struct type,)
/* /*
* Tail queue functions. * Tail queue functions.
*/ */
#define QTAILQ_INIT(head) do { \ #define QTAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \ (head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \ (head)->tqh_last = &(head)->tqh_first; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QTAILQ_INSERT_HEAD(head, elm, field) do { \ #define QTAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \ (head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \ &(elm)->field.tqe_next; \
else \ else \
(head)->tqh_last = &(elm)->field.tqe_next; \ (head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \ (head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \ (elm)->field.tqe_prev = &(head)->tqh_first; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QTAILQ_INSERT_TAIL(head, elm, field) do { \ #define QTAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \ (elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \ (elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \ *(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \ (head)->tqh_last = &(elm)->field.tqe_next; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ #define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \ (elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \ &(elm)->field.tqe_next; \
else \ else \
(head)->tqh_last = &(elm)->field.tqe_next; \ (head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \ (listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do { \ #define QTAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \ (elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \ *(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QTAILQ_REMOVE(head, elm, field) do { \ #define QTAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \ if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \ (elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \ (elm)->field.tqe_prev; \
else \ else \
(head)->tqh_last = (elm)->field.tqe_prev; \ (head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define QTAILQ_FOREACH(var, head, field) \ #define QTAILQ_FOREACH(var, head, field) \
for ((var) = ((head)->tqh_first); \ for ((var) = ((head)->tqh_first); \
(var); \ (var); \
(var) = ((var)->field.tqe_next)) (var) = ((var)->field.tqe_next))
#define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \ #define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \
for ((var) = ((head)->tqh_first); \ for ((var) = ((head)->tqh_first); \
(var) && ((next_var) = ((var)->field.tqe_next), 1); \ (var) && ((next_var) = ((var)->field.tqe_next), 1); \
(var) = (next_var)) (var) = (next_var))
#define QTAILQ_FOREACH_REVERSE(var, head, headname, field) \ #define QTAILQ_FOREACH_REVERSE(var, head, headname, field) \
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \ for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
(var); \ (var); \
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
/* /*
* Tail queue access methods. * Tail queue access methods.
*/ */
#define QTAILQ_EMPTY(head) ((head)->tqh_first == NULL) #define QTAILQ_EMPTY(head) ((head)->tqh_first == NULL)
#define QTAILQ_FIRST(head) ((head)->tqh_first) #define QTAILQ_FIRST(head) ((head)->tqh_first)
#define QTAILQ_NEXT(elm, field) ((elm)->field.tqe_next) #define QTAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define QTAILQ_LAST(head, headname) \ #define QTAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last)) (*(((struct headname *)((head)->tqh_last))->tqh_last))
#define QTAILQ_PREV(elm, headname, field) \ #define QTAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#endif /* !QEMU_SYS_QUEUE_H_ */ #endif /* !QEMU_SYS_QUEUE_H_ */

View file

@ -1,52 +1,52 @@
/* headers to use the BSD sockets */ /* headers to use the BSD sockets */
#ifndef QEMU_SOCKET_H #ifndef QEMU_SOCKET_H
#define QEMU_SOCKET_H #define QEMU_SOCKET_H
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#define socket_error() WSAGetLastError() #define socket_error() WSAGetLastError()
extern char *socket_strerror(int errcode); extern char *socket_strerror(int errcode);
#define strerror socket_strerror #define strerror socket_strerror
int inet_aton(const char *cp, struct in_addr *ia); int inet_aton(const char *cp, struct in_addr *ia);
#else #else
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include <sys/un.h> #include <sys/un.h>
#define socket_error() errno #define socket_error() errno
#endif /* !_WIN32 */ #endif /* !_WIN32 */
/* misc helpers */ /* misc helpers */
int qemu_socket(int domain, int type, int protocol); int qemu_socket(int domain, int type, int protocol);
int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
int socket_set_cork(int fd, int v); int socket_set_cork(int fd, int v);
int socket_set_nodelay(int fd); int socket_set_nodelay(int fd);
void qemu_set_block(int fd); void qemu_set_block(int fd);
void qemu_set_nonblock(int fd); void qemu_set_nonblock(int fd);
int socket_set_fast_reuse(int fd); int socket_set_fast_reuse(int fd);
#ifdef _WIN32 #ifdef _WIN32
/* MinGW needs type casts for the 'buf' and 'optval' arguments. */ /* MinGW needs type casts for the 'buf' and 'optval' arguments. */
#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \ #define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen) sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen)
/* Windows has different names for the same constants with the same values */ /* Windows has different names for the same constants with the same values */
#define SHUT_RD 0 #define SHUT_RD 0
#define SHUT_WR 1 #define SHUT_WR 1
#define SHUT_RDWR 2 #define SHUT_RDWR 2
#endif #endif
#endif /* QEMU_SOCKET_H */ #endif /* QEMU_SOCKET_H */

View file

@ -1,21 +1,21 @@
#ifndef QEMU_CHAR_H #ifndef QEMU_CHAR_H
#define QEMU_CHAR_H #define QEMU_CHAR_H
#include "qemu-common.h" #include "qemu-common.h"
/** /**
* @qemu_chr_fe_write: * @qemu_chr_fe_write:
* *
* Write data to a character backend from the front end. This function * Write data to a character backend from the front end. This function
* will send data from the front end to the back end. This function * will send data from the front end to the back end. This function
* is thread-safe. * is thread-safe.
* *
* @buf the data * @buf the data
* @len the number of bytes to send * @len the number of bytes to send
* *
* Returns: the number of bytes consumed * Returns: the number of bytes consumed
*/ */
int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len); int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
#endif #endif

View file

@ -1,112 +1,112 @@
/* /*
* win32 specific declarations * win32 specific declarations
* *
* Copyright (c) 2003-2008 Fabrice Bellard * Copyright (c) 2003-2008 Fabrice Bellard
* Copyright (c) 2010 Jes Sorensen <Jes.Sorensen@redhat.com> * Copyright (c) 2010 Jes Sorensen <Jes.Sorensen@redhat.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef QEMU_OS_WIN32_H #ifndef QEMU_OS_WIN32_H
#define QEMU_OS_WIN32_H #define QEMU_OS_WIN32_H
#include <windows.h> #include <windows.h>
#include <winsock2.h> #include <winsock2.h>
#if defined(_WIN64) #if defined(_WIN64)
/* MinGW-w64 has a 32 bit off_t, but we want 64 bit off_t. */ /* MinGW-w64 has a 32 bit off_t, but we want 64 bit off_t. */
# define off_t off64_t # define off_t off64_t
/* MinGW-w64 stdio.h defines SYS_OPEN. Allow a redefinition in arm-semi.c. */ /* MinGW-w64 stdio.h defines SYS_OPEN. Allow a redefinition in arm-semi.c. */
# undef SYS_OPEN # undef SYS_OPEN
#endif #endif
/* Workaround for older versions of MinGW. */ /* Workaround for older versions of MinGW. */
#ifndef ECONNREFUSED #ifndef ECONNREFUSED
# define ECONNREFUSED WSAECONNREFUSED # define ECONNREFUSED WSAECONNREFUSED
#endif #endif
#ifndef EINPROGRESS #ifndef EINPROGRESS
# define EINPROGRESS WSAEINPROGRESS # define EINPROGRESS WSAEINPROGRESS
#endif #endif
#ifndef EHOSTUNREACH #ifndef EHOSTUNREACH
# define EHOSTUNREACH WSAEHOSTUNREACH # define EHOSTUNREACH WSAEHOSTUNREACH
#endif #endif
#ifndef EINTR #ifndef EINTR
# define EINTR WSAEINTR # define EINTR WSAEINTR
#endif #endif
#ifndef EINPROGRESS #ifndef EINPROGRESS
# define EINPROGRESS WSAEINPROGRESS # define EINPROGRESS WSAEINPROGRESS
#endif #endif
#ifndef ENETUNREACH #ifndef ENETUNREACH
# define ENETUNREACH WSAENETUNREACH # define ENETUNREACH WSAENETUNREACH
#endif #endif
#ifndef ENOTCONN #ifndef ENOTCONN
# define ENOTCONN WSAENOTCONN # define ENOTCONN WSAENOTCONN
#endif #endif
#ifndef EWOULDBLOCK #ifndef EWOULDBLOCK
# define EWOULDBLOCK WSAEWOULDBLOCK # define EWOULDBLOCK WSAEWOULDBLOCK
#endif #endif
#if defined(_WIN64) #if defined(_WIN64)
/* On w64, setjmp is implemented by _setjmp which needs a second parameter. /* On w64, setjmp is implemented by _setjmp which needs a second parameter.
* If this parameter is NULL, longjump does no stack unwinding. * If this parameter is NULL, longjump does no stack unwinding.
* That is what we need for QEMU. Passing the value of register rsp (default) * That is what we need for QEMU. Passing the value of register rsp (default)
* lets longjmp try a stack unwinding which will crash with generated code. */ * lets longjmp try a stack unwinding which will crash with generated code. */
# undef setjmp # undef setjmp
# define setjmp(env) _setjmp(env, NULL) # define setjmp(env) _setjmp(env, NULL)
#endif #endif
/* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify /* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify
* "longjmp and don't touch the signal masks". Since we know that the * "longjmp and don't touch the signal masks". Since we know that the
* savemask parameter will always be zero we can safely define these * savemask parameter will always be zero we can safely define these
* in terms of setjmp/longjmp on Win32. * in terms of setjmp/longjmp on Win32.
*/ */
#define sigjmp_buf jmp_buf #define sigjmp_buf jmp_buf
#define sigsetjmp(env, savemask) setjmp(env) #define sigsetjmp(env, savemask) setjmp(env)
#define siglongjmp(env, val) longjmp(env, val) #define siglongjmp(env, val) longjmp(env, val)
/* Missing POSIX functions. Don't use MinGW-w64 macros. */ /* Missing POSIX functions. Don't use MinGW-w64 macros. */
#ifndef CONFIG_LOCALTIME_R #ifndef CONFIG_LOCALTIME_R
#undef gmtime_r #undef gmtime_r
struct tm *gmtime_r(const time_t *timep, struct tm *result); struct tm *gmtime_r(const time_t *timep, struct tm *result);
#undef localtime_r #undef localtime_r
struct tm *localtime_r(const time_t *timep, struct tm *result); struct tm *localtime_r(const time_t *timep, struct tm *result);
#endif /* CONFIG_LOCALTIME_R */ #endif /* CONFIG_LOCALTIME_R */
static inline void os_setup_signal_handling(void) {} static inline void os_setup_signal_handling(void) {}
static inline void os_daemonize(void) {} static inline void os_daemonize(void) {}
static inline void os_setup_post(void) {} static inline void os_setup_post(void) {}
void os_set_line_buffering(void); void os_set_line_buffering(void);
static inline void os_set_proc_name(const char *dummy) {} static inline void os_set_proc_name(const char *dummy) {}
size_t getpagesize(void); size_t getpagesize(void);
#if !defined(EPROTONOSUPPORT) #if !defined(EPROTONOSUPPORT)
# define EPROTONOSUPPORT EINVAL # define EPROTONOSUPPORT EINVAL
#endif #endif
int setenv(const char *name, const char *value, int overwrite); int setenv(const char *name, const char *value, int overwrite);
typedef struct { typedef struct {
long tv_sec; long tv_sec;
long tv_usec; long tv_usec;
} qemu_timeval; } qemu_timeval;
int qemu_gettimeofday(qemu_timeval *tp); int qemu_gettimeofday(qemu_timeval *tp);
#endif #endif

View file

@ -1,95 +1,95 @@
#ifndef QEMU_TIMER_H #ifndef QEMU_TIMER_H
#define QEMU_TIMER_H #define QEMU_TIMER_H
#include "qemu/typedefs.h" #include "qemu/typedefs.h"
#include "qemu-common.h" #include "qemu-common.h"
#define NANOSECONDS_PER_SECOND 1000000000LL #define NANOSECONDS_PER_SECOND 1000000000LL
/* timers */ /* timers */
#define SCALE_MS 1000000 #define SCALE_MS 1000000
#define SCALE_US 1000 #define SCALE_US 1000
#define SCALE_NS 1 #define SCALE_NS 1
/** /**
* QEMUClockType: * QEMUClockType:
* *
* The following clock types are available: * The following clock types are available:
* *
* @QEMU_CLOCK_REALTIME: Real time clock * @QEMU_CLOCK_REALTIME: Real time clock
* *
* The real time clock should be used only for stuff which does not * The real time clock should be used only for stuff which does not
* change the virtual machine state, as it is run even if the virtual * change the virtual machine state, as it is run even if the virtual
* machine is stopped. The real time clock has a frequency of 1000 * machine is stopped. The real time clock has a frequency of 1000
* Hz. * Hz.
* *
* @QEMU_CLOCK_VIRTUAL: virtual clock * @QEMU_CLOCK_VIRTUAL: virtual clock
* *
* The virtual clock is only run during the emulation. It is stopped * The virtual clock is only run during the emulation. It is stopped
* when the virtual machine is stopped. Virtual timers use a high * when the virtual machine is stopped. Virtual timers use a high
* precision clock, usually cpu cycles (use ticks_per_sec). * precision clock, usually cpu cycles (use ticks_per_sec).
* *
* @QEMU_CLOCK_HOST: host clock * @QEMU_CLOCK_HOST: host clock
* *
* The host clock should be use for device models that emulate accurate * The host clock should be use for device models that emulate accurate
* real time sources. It will continue to run when the virtual machine * real time sources. It will continue to run when the virtual machine
* is suspended, and it will reflect system time changes the host may * is suspended, and it will reflect system time changes the host may
* undergo (e.g. due to NTP). The host clock has the same precision as * undergo (e.g. due to NTP). The host clock has the same precision as
* the virtual clock. * the virtual clock.
* *
* @QEMU_CLOCK_VIRTUAL_RT: realtime clock used for icount warp * @QEMU_CLOCK_VIRTUAL_RT: realtime clock used for icount warp
* *
* Outside icount mode, this clock is the same as @QEMU_CLOCK_VIRTUAL. * Outside icount mode, this clock is the same as @QEMU_CLOCK_VIRTUAL.
* In icount mode, this clock counts nanoseconds while the virtual * In icount mode, this clock counts nanoseconds while the virtual
* machine is running. It is used to increase @QEMU_CLOCK_VIRTUAL * machine is running. It is used to increase @QEMU_CLOCK_VIRTUAL
* while the CPUs are sleeping and thus not executing instructions. * while the CPUs are sleeping and thus not executing instructions.
*/ */
typedef enum { typedef enum {
QEMU_CLOCK_REALTIME = 0, QEMU_CLOCK_REALTIME = 0,
QEMU_CLOCK_VIRTUAL = 1, QEMU_CLOCK_VIRTUAL = 1,
QEMU_CLOCK_HOST = 2, QEMU_CLOCK_HOST = 2,
QEMU_CLOCK_VIRTUAL_RT = 3, QEMU_CLOCK_VIRTUAL_RT = 3,
QEMU_CLOCK_MAX QEMU_CLOCK_MAX
} QEMUClockType; } QEMUClockType;
/* /*
* QEMUClockType * QEMUClockType
*/ */
/* /*
* qemu_clock_get_ns; * qemu_clock_get_ns;
* @type: the clock type * @type: the clock type
* *
* Get the nanosecond value of a clock with * Get the nanosecond value of a clock with
* type @type * type @type
* *
* Returns: the clock value in nanoseconds * Returns: the clock value in nanoseconds
*/ */
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
int64_t qemu_clock_get_ns(QEMUClockType type); int64_t qemu_clock_get_ns(QEMUClockType type);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif
/** /**
* qemu_clock_get_ms; * qemu_clock_get_ms;
* @type: the clock type * @type: the clock type
* *
* Get the millisecond value of a clock with * Get the millisecond value of a clock with
* type @type * type @type
* *
* Returns: the clock value in milliseconds * Returns: the clock value in milliseconds
*/ */
static inline int64_t qemu_clock_get_ms(QEMUClockType type) static inline int64_t qemu_clock_get_ms(QEMUClockType type)
{ {
return qemu_clock_get_ns(type) / SCALE_MS; return qemu_clock_get_ns(type) / SCALE_MS;
} }
#endif #endif

View file

@ -1,11 +1,11 @@
#ifndef QEMU_TYPEDEFS_H #ifndef QEMU_TYPEDEFS_H
#define QEMU_TYPEDEFS_H #define QEMU_TYPEDEFS_H
/* A load of opaque types so that device init declarations don't have to /* A load of opaque types so that device init declarations don't have to
pull in all the real definitions. */ pull in all the real definitions. */
struct Monitor; struct Monitor;
typedef struct Monitor Monitor; typedef struct Monitor Monitor;
typedef struct CharDriverState CharDriverState; typedef struct CharDriverState CharDriverState;
typedef struct QEMUFile QEMUFile; typedef struct QEMUFile QEMUFile;
#endif /* QEMU_TYPEDEFS_H */ #endif /* QEMU_TYPEDEFS_H */

View file

@ -2051,13 +2051,13 @@ int32 sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
chk += addr >> 8; chk += addr >> 8;
for (i=0; i<HLEN; i++) { for (i=0; i<HLEN; i++) {
byte = CPU_BD_get_mbyte(addr + i); byte = CPU_BD_get_mbyte(addr + i);
fprintf(fileref, "%02X", byte); fprintf(fileref, "%02X", byte);
chk += byte; chk &= BYTEMASK; chk += byte; chk &= BYTEMASK;
cnt++; cnt++;
} }
chk = (~chk) & BYTEMASK; chk = (~chk) & BYTEMASK;
fprintf(fileref,"%02X\n", chk); fprintf(fileref,"%02X\n", chk);
addr += HLEN; addr += HLEN;
} }
if(addr < end) { //last record if(addr < end) { //last record
fprintf(fileref, "S1%02X%04X", end - addr + 3, addr); fprintf(fileref, "S1%02X%04X", end - addr + 3, addr);
@ -2067,13 +2067,13 @@ int32 sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
chk += addr >> 8; chk += addr >> 8;
for (i=0; i<=(end - addr); i++) { for (i=0; i<=(end - addr); i++) {
byte = CPU_BD_get_mbyte(addr + i); byte = CPU_BD_get_mbyte(addr + i);
fprintf(fileref, "%02X", byte); fprintf(fileref, "%02X", byte);
chk += byte; chk &= BYTEMASK; chk += byte; chk &= BYTEMASK;
cnt++; cnt++;
} }
chk = (~chk) & BYTEMASK; chk = (~chk) & BYTEMASK;
fprintf(fileref, "%02X\n", chk); fprintf(fileref, "%02X\n", chk);
addr = end; addr = end;
} }
fprintf(fileref,"S9\n"); //EOF record fprintf(fileref,"S9\n"); //EOF record
} else { //binary } else { //binary

View file

@ -335,23 +335,23 @@ int32 sio0d(int32 io, int32 data)
case 0x11: // PTR on case 0x11: // PTR on
ptr_flag = 1; ptr_flag = 1;
ptr_unit.u3 |= RXF; ptr_unit.u3 |= RXF;
printf("Reader on\n"); printf("Reader on\n");
break; break;
case 0x12: // PTP on case 0x12: // PTP on
ptp_flag = 1; ptp_flag = 1;
ptp_unit.u3 |= TXE; ptp_unit.u3 |= TXE;
printf("Punch on\n"); printf("Punch on\n");
break; break;
case 0x13: // PTR off case 0x13: // PTR off
ptr_flag = 0; ptr_flag = 0;
if (ptr_unit.pos) if (ptr_unit.pos)
printf("Reader off-%d bytes read\n", ptr_unit.pos); printf("Reader off-%d bytes read\n", ptr_unit.pos);
ptr_unit.pos = 0; ptr_unit.pos = 0;
break; break;
case 0x14: // PTP off case 0x14: // PTP off
ptp_flag = 0; ptp_flag = 0;
if (ptp_unit.pos) if (ptp_unit.pos)
printf("Punch off-%d bytes written\n", ptp_unit.pos); printf("Punch off-%d bytes written\n", ptp_unit.pos);
ptp_unit.pos = 0; ptp_unit.pos = 0;
break; break;
default: // ignore all other characters default: // ignore all other characters

View file

@ -1,17 +1,17 @@
cd %~p0 cd %~p0
set tv disabled set tv disabled
set crt disabled set crt disabled
on error goto failed on error goto failed
break 1235 break 1235
load test.ascii load test.ascii
run 100 run 100
:failed :failed
if (PC != 669) echof "\n*** TEST FAILED\n"; exit 1 if (PC != 669) echof "\n*** TEST FAILED\n"; exit 1
echof "\n*** TEST PASSED\n" echof "\n*** TEST PASSED\n"
exit 0 exit 0

View file

@ -63,7 +63,7 @@ int dpy_quit = FALSE;
4000 4000
6000 6000
tv-off tv-off-const 1 001 (unused) tv-off tv-off-const 1 001 (unused)
tv-green-const 2 010 (unused) tv-green-const 2 010 (unused)
tv-blank green-blank-const 4 100 (flash) tv-blank green-blank-const 4 100 (flash)

View file

@ -1,99 +1,99 @@
/* tt2500_cpu.c: TT2500 bootstrap ROM contents. /* tt2500_cpu.c: TT2500 bootstrap ROM contents.
Copyright (c) 2020, Lars Brinkhoff Copyright (c) 2020, Lars Brinkhoff
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
LARS BRINKHOFF BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER LARS BRINKHOFF BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Lars Brinkhoff shall not be Except as contained in this notice, the name of Lars Brinkhoff shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Lars Brinkhoff. in this Software without prior written authorization from Lars Brinkhoff.
*/ */
#include "tt2500_defs.h" #include "tt2500_defs.h"
uint16 tt2500_rom[] = uint16 tt2500_rom[] =
{ {
/* BEGIN 0 */ 0010000, /* (NOP) */ /* BEGIN 0 */ 0010000, /* (NOP) */
/* 1 */ 0010000, /* (NOP) */ /* 1 */ 0010000, /* (NOP) */
/* 2 */ 0010000, /* (NOP) */ /* 2 */ 0010000, /* (NOP) */
/* START 3 */ 0040025, /* (PUSHJ GETC & GET CHAR) */ /* START 3 */ 0040025, /* (PUSHJ GETC & GET CHAR) */
/* 4 */ 0007001, /* (SUBI 0 WD & IS WORD "LOGO") */ /* 4 */ 0007001, /* (SUBI 0 WD & IS WORD "LOGO") */
/* 5 */ 0147577, /* (147577) */ /* 5 */ 0147577, /* (147577) */
/* 6 */ 0133774, /* (BNE START) */ /* 6 */ 0133774, /* (BNE START) */
/* 7 */ 0040022, /* (PUSHJ GETW) */ /* 7 */ 0040022, /* (PUSHJ GETW) */
/* 10 */ 0074201, /* (GET ADR WD) */ /* 10 */ 0074201, /* (GET ADR WD) */
/* 11 */ 0040022, /* (PUSHJ GETW) */ /* 11 */ 0040022, /* (PUSHJ GETW) */
/* 12 */ 0074301, /* (GET CNT WD) */ /* 12 */ 0074301, /* (GET CNT WD) */
/* LOOP 13 */ 0040022, /* (PUSHJ GETW) */ /* LOOP 13 */ 0040022, /* (PUSHJ GETW) */
/* 14 */ 0004220, /* (DEC ADR) */ /* 14 */ 0004220, /* (DEC ADR) */
/* 15 */ 0025100, /* (CWRITE WD) */ /* 15 */ 0025100, /* (CWRITE WD) */
/* 16 */ 0004320, /* (DEC CNT) */ /* 16 */ 0004320, /* (DEC CNT) */
/* 17 */ 0133773, /* (BNE LOOP) */ /* 17 */ 0133773, /* (BNE LOOP) */
/* 20 */ 0074023, /* (GET 0 XR) */ /* 20 */ 0074023, /* (GET 0 XR) */
/* 21 */ 0050100, /* (JUMP 100) */ /* 21 */ 0050100, /* (JUMP 100) */
/* GETW 22 */ 0040025, /* (PUSHJ GETC) */ /* GETW 22 */ 0040025, /* (PUSHJ GETC) */
/* 23 */ 0040025, /* (PUSHJ GETC) */ /* 23 */ 0040025, /* (PUSHJ GETC) */
/* 24 */ 0040025, /* (PUSHJ GETC) */ /* 24 */ 0040025, /* (PUSHJ GETC) */
/* GETC 25 */ 0073320, /* (DIS INTS 2) */ /* GETC 25 */ 0073320, /* (DIS INTS 2) */
/* 26 */ 0050025, /* (JUMP GETC) */ /* 26 */ 0050025, /* (JUMP GETC) */
/* 27 */ 0010000, /* (NOP) */ /* 27 */ 0010000, /* (NOP) */
/* 30 */ 0074424, /* (GET CH UART) */ /* 30 */ 0074424, /* (GET CH UART) */
/* 31 */ 0001444, /* (ANDI CH CH) */ /* 31 */ 0001444, /* (ANDI CH CH) */
/* 32 */ 0000017, /* (17) */ /* 32 */ 0000017, /* (17) */
/* 33 */ 0004114, /* (ROT WD 14) */ /* 33 */ 0004114, /* (ROT WD 14) */
/* 34 */ 0001141, /* (ANDI WD WD) */ /* 34 */ 0001141, /* (ANDI WD WD) */
/* 35 */ 0177760, /* (177760) */ /* 35 */ 0177760, /* (177760) */
/* 36 */ 0002104, /* (IOR WD CH) */ /* 36 */ 0002104, /* (IOR WD CH) */
/* 37 */ 0076016 /* (POPJ) */ /* 37 */ 0076016 /* (POPJ) */
#if 0 #if 0
0010000, /* NOP */ 0010000, /* NOP */
0010000, /* NOP */ 0010000, /* NOP */
0010000, /* NOP */ 0010000, /* NOP */
0040025, /* PUSHJ GETC Call subroutine to read TTY character. */ 0040025, /* PUSHJ GETC Call subroutine to read TTY character. */
0007001, /* SUBI 0 WD 32-bit instruction computes 147577 - WD */ 0007001, /* SUBI 0 WD 32-bit instruction computes 147577 - WD */
0147577, /* 147577 (The constant "LOGO" is stored here.) */ 0147577, /* 147577 (The constant "LOGO" is stored here.) */
0133774, /* BNE START Branch to START if result Not zero. */ 0133774, /* BNE START Branch to START if result Not zero. */
0040022, /* PUSHJ GETW Reads 4 characters to make 16-bit word. */ 0040022, /* PUSHJ GETW Reads 4 characters to make 16-bit word. */
0074201, /* GET ADR WD Move word from WD to ADR (register 2). */ 0074201, /* GET ADR WD Move word from WD to ADR (register 2). */
0040022, /* PUSHJ GETW Get next data word into WD. */ 0040022, /* PUSHJ GETW Get next data word into WD. */
0074301, /* GET CNT WD Move it to CNT. */ 0074301, /* GET CNT WD Move it to CNT. */
0040022, /* PUSHJ GETW Get another data word. */ 0040022, /* PUSHJ GETW Get another data word. */
0004220, /* DEC ADR Decrement the Address and use it to */ 0004220, /* DEC ADR Decrement the Address and use it to */
0025100, /* CWRITE WD write [WD] into control memory. */ 0025100, /* CWRITE WD write [WD] into control memory. */
0004320, /* DEC CNT Decrement the word in CNT (count). */ 0004320, /* DEC CNT Decrement the word in CNT (count). */
0133773, /* BNE LOOP Branch to LOOP unless CNT is zero. */ 0133773, /* BNE LOOP Branch to LOOP unless CNT is zero. */
0074023, /* GET 0 XR Makes PC leave Bootstrap Loader. */ 0074023, /* GET 0 XR Makes PC leave Bootstrap Loader. */
0050100, /* JUMP 100 Jump to location 100. */ 0050100, /* JUMP 100 Jump to location 100. */
0040025, /* PUSHJ GETC Get 4 bits and shift into WD. */ 0040025, /* PUSHJ GETC Get 4 bits and shift into WD. */
0040025, /* PUSHJ GETC Get 4 more. */ 0040025, /* PUSHJ GETC Get 4 more. */
0040025, /* PUSHJ GETC Get 4 more. */ 0040025, /* PUSHJ GETC Get 4 more. */
0073320, /* DIS INTS 2 Skip 2 steps if TTY interrupt active. */ 0073320, /* DIS INTS 2 Skip 2 steps if TTY interrupt active. */
0050025, /* JUMP GETC If not, go back and wait. */ 0050025, /* JUMP GETC If not, go back and wait. */
0010000, /* NOP (Skip over this.) */ 0010000, /* NOP (Skip over this.) */
0074424, /* GET CH UART Put the character into CH. */ 0074424, /* GET CH UART Put the character into CH. */
0001444, /* ANDI CH CH Mask out all but last four bits by */ 0001444, /* ANDI CH CH Mask out all but last four bits by */
0000017, /* 17 ANDing with 0 000 000 000 001 111. */ 0000017, /* 17 ANDing with 0 000 000 000 001 111. */
0004114, /* ROT WD 14 Rotate WD four places right. */ 0004114, /* ROT WD 14 Rotate WD four places right. */
0001141, /* ANDI WD WD Zero out last four bits by */ 0001141, /* ANDI WD WD Zero out last four bits by */
0177760, /* 177760 ANDing with 1 111 111 111 110 000. */ 0177760, /* 177760 ANDing with 1 111 111 111 110 000. */
0002104, /* IOR WD CH Finally, OR them together. */ 0002104, /* IOR WD CH Finally, OR them together. */
0075600, /* POPJ Return to calling program. */ 0075600, /* POPJ Return to calling program. */
#endif #endif
}; };