diff --git a/BasiliskII/src/AmigaOS/BasiliskII.info b/BasiliskII/src/AmigaOS/BasiliskII.info deleted file mode 100644 index b590d7da..00000000 Binary files a/BasiliskII/src/AmigaOS/BasiliskII.info and /dev/null differ diff --git a/BasiliskII/src/AmigaOS/Makefile b/BasiliskII/src/AmigaOS/Makefile deleted file mode 100644 index 2ccaeec0..00000000 --- a/BasiliskII/src/AmigaOS/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# AmigaOS makefile for Basilisk II (GeekGadgets tool chain) - -## System specific configuration -CC = gcc -CXX = c++ -CXXFLAGS = -g -O1 -noixemul -m68020 -msmall-code -Wno-multichar -CPPFLAGS = -I../include -I../native_cpu -I. -DEFS = -LDFLAGS = -noixemul -LIBS = /gg/lib/libnix/swapstack.o -AS = PhxAss -ASFLAGS = OPT ! INCPATH GG:os-include FPU=1 - -## Files -SRCS = ../main.cpp main_amiga.cpp ../prefs.cpp ../prefs_items.cpp \ - prefs_amiga.cpp prefs_editor_amiga.cpp sys_amiga.cpp ../rom_patches.cpp \ - ../slot_rom.cpp ../rsrc_patches.cpp ../emul_op.cpp \ - ../macos_util.cpp ../xpram.cpp xpram_amiga.cpp ../timer.cpp \ - timer_amiga.cpp clip_amiga.cpp ../adb.cpp ../serial.cpp \ - serial_amiga.cpp ../ether.cpp ether_amiga.cpp ../sony.cpp ../disk.cpp \ - ../cdrom.cpp ../scsi.cpp scsi_amiga.cpp ../video.cpp video_amiga.cpp \ - ../audio.cpp audio_amiga.cpp ../extfs.cpp extfs_amiga.cpp \ - ../user_strings.cpp user_strings_amiga.cpp asm_support.asm -APP = BasiliskII - -## Rules -.PHONY: clean distclean -.SUFFIXES: -.SUFFIXES: .c .cpp .asm .o .h - -all: $(APP) - -OBJ_DIR = obj -$(OBJ_DIR):: - @[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1 - -define SRCS_LIST_TO_OBJS - $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(foreach file, $(SRCS), \ - $(basename $(notdir $(file)))))) -endef -OBJS = $(SRCS_LIST_TO_OBJS) - -SRC_PATHS += $(sort $(foreach file, $(SRCS), $(dir $(file)))) -VPATH := -VPATH += $(addprefix :, $(subst ,:, $(filter-out $($(subst, :, ,$(VPATH))), $(SRC_PATHS)))) - -$(APP): $(OBJ_DIR) $(OBJS) - $(CXX) -o $(APP) $(LDFLAGS) $(LIBS) $(OBJS) - -clean: - rm -f $(APP) $(OBJ_DIR)/* *~ *.bak obj.0000.* - -distclean: clean - rm -rf $(OBJ_DIR) - -$(OBJ_DIR)/%.o : %.cpp - $(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/%.o : %.asm - $(AS) $(ASFLAGS) $< TO $(OBJ_DIR)/$*.obj - hunk2aout $(OBJ_DIR)/$*.obj >/dev/null - mv obj.0000.* $@ - -#------------------------------------------------------------------------- -# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/BasiliskII/src/AmigaOS/asm_support.asm b/BasiliskII/src/AmigaOS/asm_support.asm deleted file mode 100644 index d2a81b07..00000000 --- a/BasiliskII/src/AmigaOS/asm_support.asm +++ /dev/null @@ -1,1393 +0,0 @@ -* -* asm_support.asm - AmigaOS utility functions in assembly language -* -* Basilisk II (C) 1997-2001 Christian Bauer -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* - -DEBUG_DETAIL SET 1 - - INCLUDE "exec/types.i" - INCLUDE "exec/macros.i" - INCLUDE "exec/memory.i" - INCLUDE "exec/tasks.i" - INCLUDE "dos/dos.i" - INCLUDE "devices/timer.i" - -; INCLUDE "asmsupp.i" - - XDEF _AtomicAnd - XDEF _AtomicOr - XDEF _MoveVBR - XDEF _DisableSuperBypass - XDEF _Execute68k - XDEF _Execute68kTrap - XDEF _TrapHandlerAsm - XDEF _ExceptionHandlerAsm - XDEF _AsmTriggerNMI - - XREF _OldTrapHandler - XREF _OldExceptionHandler - XREF _IllInstrHandler - XREF _PrivViolHandler - XREF _EmulatedSR - XREF _IRQSigMask - XREF _InterruptFlags - XREF _MainTask - XREF _SysBase - XREF _quit_emulator - -INFO_LEVEL equ 0 - - SECTION text,CODE - - MACHINE 68020 - - IFGE INFO_LEVEL -subSysName: dc.b '+',0 - ENDIF - -* -* Atomic bit operations (don't trust the compiler) -* - -_AtomicAnd move.l 4(sp),a0 - move.l 8(sp),d0 - and.l d0,(a0) - rts - -_AtomicOr move.l 4(sp),a0 - move.l 8(sp),d0 - or.l d0,(a0) - rts - -* -* Move VBR away from 0 if neccessary -* - -_MoveVBR movem.l d0-d1/a0-a1/a5-a6,-(sp) - move.l _SysBase,a6 - - lea getvbr,a5 ;VBR at 0? - JSRLIB Supervisor - tst.l d0 - bne.s 1$ - - move.l #$400,d0 ;Yes, allocate memory for new table - move.l #MEMF_PUBLIC,d1 - JSRLIB AllocMem - tst.l d0 - beq.s 1$ - - JSRLIB Disable - - move.l d0,a5 ;Copy old table - move.l d0,a1 - sub.l a0,a0 - move.l #$400,d0 - JSRLIB CopyMem - JSRLIB CacheClearU - - move.l a5,d0 ;Set VBR - lea setvbr,a5 - JSRLIB Supervisor - - JSRLIB Enable - -1$ movem.l (sp)+,d0-d1/a0-a1/a5-a6 - rts - -getvbr movec vbr,d0 - rte - -setvbr movec d0,vbr - rte - -* -* Disable 68060 Super Bypass mode -* - -_DisableSuperBypass - movem.l d0-d1/a0-a1/a5-a6,-(sp) - move.l _SysBase,a6 - - lea dissb,a5 - JSRLIB Supervisor - - movem.l (sp)+,d0-d1/a0-a1/a5-a6 - rts - - MACHINE 68060 - -dissb movec pcr,d0 - bset #5,d0 - movec d0,pcr - rte - - MACHINE 68020 - -* -* Execute 68k subroutine (must be ended with rts) -* r->a[7] and r->sr are unused! -* - -; void Execute68k(uint32 addr, M68kRegisters *r); -_Execute68k - move.l 4(sp),d0 ;Get arguments - move.l 8(sp),a0 - - movem.l d2-d7/a2-a6,-(sp) ;Save registers - - move.l a0,-(sp) ;Push pointer to M68kRegisters on stack - pea 1$ ;Push return address on stack - move.l d0,-(sp) ;Push pointer to 68k routine on stack - movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters - - rts ;Jump into 68k routine - -1$ move.l a6,-(sp) ;Save a6 - move.l 4(sp),a6 ;Get pointer to M68kRegisters - movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters - move.l (sp)+,56(a6) ;Save a6 to M68kRegisters - addq.l #4,sp ;Remove pointer from stack - - movem.l (sp)+,d2-d7/a2-a6 ;Restore registers - rts - -* -* Execute MacOS 68k trap -* r->a[7] and r->sr are unused! -* - -; void Execute68kTrap(uint16 trap, M68kRegisters *r); -_Execute68kTrap - move.l 4(sp),d0 ;Get arguments - move.l 8(sp),a0 - - movem.l d2-d7/a2-a6,-(sp) ;Save registers - - move.l a0,-(sp) ;Push pointer to M68kRegisters on stack - move.w d0,-(sp) ;Push trap word on stack - subq.l #8,sp ;Create fake A-Line exception frame - movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters - - move.l a2,-(sp) ;Save a2 and d2 - move.l d2,-(sp) - lea 1$,a2 ;a2 points to return address - move.w 16(sp),d2 ;Load trap word into d2 - - jmp ([$28.w],10) ;Jump into MacOS A-Line handler - -1$ move.l a6,-(sp) ;Save a6 - move.l 6(sp),a6 ;Get pointer to M68kRegisters - movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters - move.l (sp)+,56(a6) ;Save a6 to M68kRegisters - addq.l #6,sp ;Remove pointer and trap word from stack - - movem.l (sp)+,d2-d7/a2-a6 ;Restore registers - rts - -* -* Exception handler of main task (for interrupts) -* - -_ExceptionHandlerAsm - move.l d0,-(sp) ;Save d0 - - and.l #SIGBREAKF_CTRL_C,d0 ;CTRL-C? - bne.s 2$ - - move.w _EmulatedSR,d0 ;Interrupts enabled in emulated SR? - and.w #$0700,d0 - bne 1$ - move.w #$0064,-(sp) ;Yes, fake interrupt stack frame - pea 1$ - move.w _EmulatedSR,d0 - move.w d0,-(sp) - or.w #$2100,d0 ;Set interrupt level in SR, enter (virtual) supervisor mode - move.w d0,_EmulatedSR - move.l $64.w,-(sp) ;Jump to MacOS interrupt handler - rts - -1$ move.l (sp)+,d0 ;Restore d0 - rts - -2$ JSRLIB Forbid ;Waiting for Dos signal? - sub.l a1,a1 - JSRLIB FindTask - move.l d0,a0 - move.l TC_SIGWAIT(a0),d0 - move.l TC_SIGRECVD(a0),d1 - JSRLIB Permit - btst #SIGB_DOS,d0 - beq 3$ - btst #SIGB_DOS,d1 - bne 4$ - -3$ lea TC_SIZE(a0),a0 ;No, remove pending Dos packets - JSRLIB GetMsg - - move.w _EmulatedSR,d0 - or.w #$0700,d0 ;Disable all interrupts - move.w d0,_EmulatedSR - moveq #0,d0 ;Disable all exception signals - moveq #-1,d1 - JSRLIB SetExcept - jsr _quit_emulator ;CTRL-C, quit emulator -4$ move.l (sp)+,d0 - rts - -* -* Trap handler of main task -* - -_TrapHandlerAsm: - IFEQ INFO_LEVEL-1002 - move.w ([6,a0]),-(sp) - move.w #0,-(sp) - move.l (4+6,a0),-(sp) - PUTMSG 0,'%s/TrapHandlerAsm: addr=%08lx opcode=%04lx' - lea (2*4,sp),sp - ENDC - - cmp.l #4,(sp) ;Illegal instruction? - beq.s doillinstr - cmp.l #10,(sp) ;A-Line exception? - beq.s doaline - cmp.l #8,(sp) ;Privilege violation? - beq.s doprivviol - - cmp.l #9,(sp) ;Trace? - beq dotrace - cmp.l #3,(sp) ;Illegal Address? - beq.s doilladdr - cmp.l #11,(sp) ;F-Line exception - beq.s dofline - - cmp.l #32,(sp) - blt 1$ - cmp.l #47,(sp) - ble doTrapXX ; Vector 32-47 : TRAP #0 - 15 Instruction Vectors - -1$: - cmp.l #48,(sp) - blt 2$ - cmp.l #55,(sp) - ble doTrapFPU -2$: - IFEQ INFO_LEVEL-1009 - PUTMSG 0,'%s/TrapHandlerAsm: stack=%08lx %08lx %08lx %08lx' - ENDC - - move.l _OldTrapHandler,-(sp) ;No, jump to old trap handler - rts - -* -* TRAP #0 - 15 Instruction Vectors -* - -doTrapXX: - IFEQ INFO_LEVEL-1009 - PUTMSG 0,'%s/doTrapXX: stack=%08lx %08lx %08lx %08lx' - ENDC - - movem.l a0/d0,-(sp) ;Save a0,d0 - move.l (2*4,sp),d0 ;vector number 32-47 - - move.l usp,a0 ;Get user stack pointer - move.l (4*4,sp),-(a0) ;Copy 4-word stack frame to user stack - move.l (3*4,sp),-(a0) - move.l a0,usp ;Update USP - or.w #$2000,(a0) ;set Supervisor bit in SR - - lsl.l #2,d0 ;convert vector number to vector offset - move.l d0,a0 - move.l (a0),d0 ;get mac trap vector - - move.l usp,a0 ;Get user stack pointer - move.l d0,-(a0) ;store vector offset as return address - move.l a0,usp ;Update USP - - movem.l (sp)+,a0/d0 ;Restore a0,d0 - addq.l #4*2,sp ;Remove exception frame from supervisor stack - - andi #$d8ff,sr ;Switch to user mode, enable interrupts - rts - - -* -* FPU Exception Instruction Vectors -* - -doTrapFPU: - move.l d0,(sp) - fmove.l fpcr,d0 - and.w #$00ff,d0 ;disable FPU exceptions - fmove.l d0,fpcr - move.l (sp)+,d0 ;Restore d0 - rte - - -* -* trace Vector -* - -dotrace - IFEQ INFO_LEVEL-1009 - PUTMSG 0,'%s/dotrace: stack=%08lx %08lx %08lx %08lx' - ENDC - - move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - - IFEQ INFO_LEVEL-1009 - move.l (12,a0),-(sp) - move.l (8,a0),-(sp) - move.l (4,a0),-(sp) - move.l (0,a0),-(sp) - move.l a0,-(sp) - move.l a7,-(sp) - PUTMSG 0,'%s/dotrace: sp=%08lx usp=%08lx (%08lx %08lx %08lx %08lx)' - lea (6*4,sp),sp - ENDC - - move.l 3*4(sp),-(a0) ;Copy 6-word stack frame to user stack - move.l 2*4(sp),-(a0) - move.l 1*4(sp),-(a0) - move.l a0,usp ;Update USP - or.w #$2000,(a0) ;set Supervisor bit in SR - move.l (sp)+,a0 ;Restore a0 - - lea 6*2(sp),sp ;Remove exception frame from supervisor stack - andi #$18ff,sr ;Switch to user mode, enable interrupts, disable trace - - move.l $24.w,-(sp) ;Jump to MacOS exception handler - rts - - -* -* A-Line handler: call MacOS A-Line handler -* - -doaline move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.l 8(sp),-(a0) ;Copy stack frame to user stack - move.l 4(sp),-(a0) - move.l a0,usp ;Update USP - - or.w #$2000,(a0) ;set Supervisor bit in SR - move.l (sp)+,a0 ;Restore a0 - - addq.l #8,sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - -; and.w #$f8ff,_EmulatedSR ;enable interrupts in EmulatedSR - - move.l $28.w,-(sp) ;Jump to MacOS exception handler - rts - -* -* F-Line handler: call F-Line exception handler -* - -dofline move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.l 8(sp),-(a0) ;Copy stack frame to user stack - move.l 4(sp),-(a0) - move.l a0,usp ;Update USP - or.w #$2000,(a0) ;set Supervisor bit in SR - move.l (sp)+,a0 ;Restore a0 - - addq.l #8,sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - - and.w #$f8ff,_EmulatedSR ;enable interrupts in EmulatedSR - - move.l $2c.w,-(sp) ;Jump to MacOS exception handler - rts - -* -* Illegal address handler -* - -doilladdr: - IFEQ INFO_LEVEL-1009 - PUTMSG 0,'%s/doilladdr: stack=%08lx %08lx %08lx %08lx' - ENDC - - move.l a0,(sp) ;Save a0 - - move.l usp,a0 ;Get user stack pointer - move.l 3*4(sp),-(a0) ;Copy 6-word stack frame to user stack - move.l 2*4(sp),-(a0) - move.l 1*4(sp),-(a0) - move.l a0,usp ;Update USP - or.w #$2000,(a0) ;set Supervisor bit in SR - move.l (sp)+,a0 ;Restore a0 - - lea 6*2(sp),sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - - move.l $0c.w,-(sp) ;Jump to MacOS exception handler - rts - - -* -* Illegal instruction handler: call IllInstrHandler() (which calls EmulOp()) -* to execute extended opcodes (see emul_op.h) -* - -doillinstr movem.l a0/d0,-(sp) - move.w ([6+2*4,sp]),d0 - and.w #$ff00,d0 - cmp.w #$7100,d0 - - IFEQ INFO_LEVEL-1009 - move.l d0,-(sp) - PUTMSG 0,'%s/doillinst: d0=%08lx stack=%08lx %08lx %08lx %08lx' - lea (1*4,sp),sp - ENDC - movem.l (sp)+,a0/d0 - beq 1$ - - move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.l 8(sp),-(a0) ;Copy stack frame to user stack - move.l 4(sp),-(a0) - move.l a0,usp ;Update USP - or.w #$2000,(a0) ;set Supervisor bit in SR - move.l (sp)+,a0 ;Restore a0 - - add.w #3*4,sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - - move.l $10.w,-(sp) ;Jump to MacOS exception handler - rts - -1$: - move.l a6,(sp) ;Save a6 - move.l usp,a6 ;Get user stack pointer - - move.l a6,-10(a6) ;Push USP (a7) - move.l 6(sp),-(a6) ;Push PC - move.w 4(sp),-(a6) ;Push SR - subq.l #4,a6 ;Skip saved USP - move.l (sp),-(a6) ;Push old a6 - movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers - move.l a6,usp ;Update USP - - add.w #12,sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - - move.l a6,-(sp) ;Jump to IllInstrHandler() in main.cpp - jsr _IllInstrHandler - addq.l #4,sp - - movem.l (sp)+,d0-d7/a0-a6 ;Restore registers - addq.l #4,sp ;Skip saved USP (!!) - rtr ;Return from exception - -* -* Privilege violation handler: MacOS runs in supervisor mode, -* so we have to emulate certain privileged instructions -* - -doprivviol move.l d0,(sp) ;Save d0 - move.w ([6,sp]),d0 ;Get instruction word - - IFEQ INFO_LEVEL-1001 - move.w ([6,a0]),-(sp) - move.w #0,-(sp) - PUTMSG 0,'%s/doprivviol: opcode=%04lx' - lea (1*4,sp),sp - ENDC - - cmp.w #$40e7,d0 ;move sr,-(sp)? - beq pushsr - cmp.w #$46df,d0 ;move (sp)+,sr? - beq popsr - - cmp.w #$007c,d0 ;ori #xxxx,sr? - beq orisr - cmp.w #$027c,d0 ;andi #xxxx,sr? - beq andisr - - cmp.w #$46fc,d0 ;move #xxxx,sr? - beq movetosrimm - - cmp.w #$46ef,d0 ;move (xxxx,sp),sr? - beq movetosrsprel - cmp.w #$46d8,d0 ;move (a0)+,sr? - beq movetosra0p - cmp.w #$46d9,d0 ;move (a1)+,sr? - beq movetosra1p - - cmp.w #$40f8,d0 ;move sr,xxxx.w? - beq movefromsrabs - cmp.w #$40d0,d0 ;move sr,(a0)? - beq movefromsra0 - cmp.w #$40d7,d0 ;move sr,(sp)? - beq movefromsrsp - - cmp.w #$f327,d0 ;fsave -(sp)? - beq fsavepush - cmp.w #$f35f,d0 ;frestore (sp)+? - beq frestorepop - cmp.w #$f32d,d0 ;fsave xxx(a5) ? - beq fsavea5 - cmp.w #$f36d,d0 ;frestore xxx(a5) ? - beq frestorea5 - - cmp.w #$4e73,d0 ;rte? - beq pvrte - - cmp.w #$40c0,d0 ;move sr,d0? - beq movefromsrd0 - cmp.w #$40c1,d0 ;move sr,d1? - beq movefromsrd1 - cmp.w #$40c2,d0 ;move sr,d2? - beq movefromsrd2 - cmp.w #$40c3,d0 ;move sr,d3? - beq movefromsrd3 - cmp.w #$40c4,d0 ;move sr,d4? - beq movefromsrd4 - cmp.w #$40c5,d0 ;move sr,d5? - beq movefromsrd5 - cmp.w #$40c6,d0 ;move sr,d6? - beq movefromsrd6 - cmp.w #$40c7,d0 ;move sr,d7? - beq movefromsrd7 - - cmp.w #$46c0,d0 ;move d0,sr? - beq movetosrd0 - cmp.w #$46c1,d0 ;move d1,sr? - beq movetosrd1 - cmp.w #$46c2,d0 ;move d2,sr? - beq movetosrd2 - cmp.w #$46c3,d0 ;move d3,sr? - beq movetosrd3 - cmp.w #$46c4,d0 ;move d4,sr? - beq movetosrd4 - cmp.w #$46c5,d0 ;move d5,sr? - beq movetosrd5 - cmp.w #$46c6,d0 ;move d6,sr? - beq movetosrd6 - cmp.w #$46c7,d0 ;move d7,sr? - beq movetosrd7 - - cmp.w #$4e7a,d0 ;movec cr,x? - beq movecfromcr - cmp.w #$4e7b,d0 ;movec x,cr? - beq movectocr - - cmp.w #$f478,d0 ;cpusha dc? - beq cpushadc - cmp.w #$f4f8,d0 ;cpusha dc/ic? - beq cpushadcic - - cmp.w #$4e69,d0 ;move usp,a1 - beq moveuspa1 - cmp.w #$4e68,d0 ;move usp,a0 - beq moveuspa0 - - cmp.w #$4e61,d0 ;move a1,usp - beq moved1usp - -pv_unhandled move.l (sp),d0 ;Unhandled instruction, jump to handler in main.cpp - move.l a6,(sp) ;Save a6 - move.l usp,a6 ;Get user stack pointer - - move.l a6,-10(a6) ;Push USP (a7) - move.l 6(sp),-(a6) ;Push PC - move.w 4(sp),-(a6) ;Push SR - subq.l #4,a6 ;Skip saved USP - move.l (sp),-(a6) ;Push old a6 - movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers - move.l a6,usp ;Update USP - - add.w #12,sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - - move.l a6,-(sp) ;Jump to PrivViolHandler() in main.cpp - jsr _PrivViolHandler - addq.l #4,sp - - movem.l (sp)+,d0-d7/a0-a6 ;Restore registers - addq.l #4,sp ;Skip saved USP - rtr ;Return from exception - -; move sr,-(sp) -pushsr move.l a0,-(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.w 8(sp),d0 ;Get CCR from exception stack frame - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - move.w d0,-(a0) ;Store SR on user stack - move.l a0,usp ;Update USP - move.l (sp)+,a0 ;Restore a0 - move.l (sp)+,d0 ;Restore d0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; move (sp)+,sr -popsr move.l a0,-(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.w (a0)+,d0 ;Get SR from user stack - move.w d0,8(sp) ;Store into CCR on exception stack frame - and.w #$00ff,8(sp) - and.w #$e700,d0 ;Extract supervisor bits - move.w d0,_EmulatedSR ;And save them - - and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled - bne 1$ - tst.l _InterruptFlags - beq 1$ - movem.l d0-d1/a0-a1/a6,-(sp) - move.l _SysBase,a6 - move.l _MainTask,a1 - move.l _IRQSigMask,d0 - JSRLIB Signal - movem.l (sp)+,d0-d1/a0-a1/a6 -1$ - move.l a0,usp ;Update USP - move.l (sp)+,a0 ;Restore a0 - move.l (sp)+,d0 ;Restore d0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; ori #xxxx,sr -orisr move.w 4(sp),d0 ;Get CCR from stack - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - or.w ([6,sp],2),d0 ;Or with immediate value - move.w d0,4(sp) ;Store into CCR on stack - and.w #$00ff,4(sp) - and.w #$e700,d0 ;Extract supervisor bits - move.w d0,_EmulatedSR ;And save them - move.l (sp)+,d0 ;Restore d0 - addq.l #4,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; andi #xxxx,sr -andisr move.w 4(sp),d0 ;Get CCR from stack - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - and.w ([6,sp],2),d0 ;And with immediate value -storesr4 move.w d0,4(sp) ;Store into CCR on stack - and.w #$00ff,4(sp) - and.w #$e700,d0 ;Extract supervisor bits - move.w d0,_EmulatedSR ;And save them - - and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled - bne.s 1$ - tst.l _InterruptFlags - beq.s 1$ - movem.l d0-d1/a0-a1/a6,-(sp) - move.l _SysBase,a6 - move.l _MainTask,a1 - move.l _IRQSigMask,d0 - JSRLIB Signal - movem.l (sp)+,d0-d1/a0-a1/a6 -1$ move.l (sp)+,d0 ;Restore d0 - addq.l #4,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; move #xxxx,sr -movetosrimm move.w ([6,sp],2),d0 ;Get immediate value - bra.s storesr4 - -; move (xxxx,sp),sr -movetosrsprel move.l a0,-(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.w ([10,sp],2),d0 ;Get offset - move.w (a0,d0.w),d0 ;Read word - move.l (sp)+,a0 ;Restore a0 - bra.s storesr4 - -; move (a0)+,sr -movetosra0p move.w (a0)+,d0 ;Read word - bra storesr2 - -; move (a1)+,sr -movetosra1p move.w (a1)+,d0 ;Read word - bra storesr2 - -; move sr,xxxx.w -movefromsrabs move.l a0,-(sp) ;Save a0 - move.w ([10,sp],2),a0 ;Get address - move.w 8(sp),d0 ;Get CCR - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - move.w d0,(a0) ;Store SR - move.l (sp)+,a0 ;Restore a0 - move.l (sp)+,d0 ;Restore d0 - addq.l #4,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; move sr,(a0) -movefromsra0 move.w 4(sp),d0 ;Get CCR - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - move.w d0,(a0) ;Store SR - move.l (sp)+,d0 ;Restore d0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; move sr,(sp) -movefromsrsp move.l a0,-(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.w 8(sp),d0 ;Get CCR - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - move.w d0,(a0) ;Store SR - move.l (sp)+,a0 ;Restore a0 - move.l (sp)+,d0 ;Restore d0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; fsave -(sp) -fsavepush move.l (sp),d0 ;Restore d0 - move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.l #$41000000,-(a0) ;Push idle frame - move.l a0,usp ;Update USP - move.l (sp)+,a0 ;Restore a0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; fsave xxx(a5) -fsavea5 move.l (sp),d0 ;Restore d0 - move.l a0,(sp) ;Save a0 - move.l a5,a0 ;Get base register - add.w ([6,sp],2),a0 ;Add offset to base register - move.l #$41000000,(a0) ;Push idle frame - move.l (sp)+,a0 ;Restore a0 - addq.l #4,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; frestore (sp)+ -frestorepop move.l (sp),d0 ;Restore d0 - move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - addq.l #4,a0 ;Nothing to do... - move.l a0,usp ;Update USP - move.l (sp)+,a0 ;Restore a0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; frestore xxx(a5) -frestorea5 move.l (sp),d0 ;Restore d0 - move.l a0,(sp) ;Save a0 - move.l (sp)+,a0 ;Restore a0 - addq.l #4,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; rte -pvrte movem.l a0/a1,-(sp) ;Save a0 and a1 - move.l usp,a0 ;Get user stack pointer - - move.w (a0)+,d0 ;Get SR from user stack - move.w d0,8+4(sp) ;Store into CCR on exception stack frame - and.w #$c0ff,8+4(sp) - and.w #$e700,d0 ;Extract supervisor bits - move.w d0,_EmulatedSR ;And save them - move.l (a0)+,10+4(sp) ;Store return address in exception stack frame - - move.w (a0)+,d0 ;get format word - lsr.w #7,d0 ;get stack frame Id - lsr.w #4,d0 - and.w #$001e,d0 - move.w (StackFormatTable,pc,d0.w),d0 ; get total stack frame length - subq.w #4,d0 ; count only extra words - lea 16+4(sp),a1 ; destination address (in supervisor stack) - bra 1$ - -2$ move.w (a0)+,(a1)+ ; copy additional stack words back to supervisor stack -1$ dbf d0,2$ - - move.l a0,usp ;Update USP - movem.l (sp)+,a0/a1 ;Restore a0 and a1 - move.l (sp)+,d0 ;Restore d0 - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; sizes of exceptions stack frames -StackFormatTable: - dc.w 4 ; Four-word stack frame, format $0 - dc.w 4 ; Throwaway four-word stack frame, format $1 - dc.w 6 ; Six-word stack frame, format $2 - dc.w 6 ; MC68040 floating-point post-instruction stack frame, format $3 - dc.w 8 ; MC68EC040 and MC68LC040 floating-point unimplemented stack frame, format $4 - dc.w 4 ; Format $5 - dc.w 4 ; Format $6 - dc.w 30 ; MC68040 access error stack frame, Format $7 - dc.w 29 ; MC68010 bus and address error stack frame, format $8 - dc.w 10 ; MC68020 and MC68030 coprocessor mid-instruction stack frame, format $9 - dc.w 16 ; MC68020 and MC68030 short bus cycle stack frame, format $a - dc.w 46 ; MC68020 and MC68030 long bus cycle stack frame, format $b - dc.w 12 ; CPU32 bus error for prefetches and operands stack frame, format $c - dc.w 4 ; Format $d - dc.w 4 ; Format $e - dc.w 4 ; Format $f - -; move sr,dx -movefromsrd0 addq.l #4,sp ;Skip saved d0 - moveq #0,d0 - move.w (sp),d0 ;Get CCR - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd1 move.l (sp)+,d0 - moveq #0,d1 - move.w (sp),d1 - or.w _EmulatedSR,d1 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd2 move.l (sp)+,d0 - moveq #0,d2 - move.w (sp),d2 - or.w _EmulatedSR,d2 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd3 move.l (sp)+,d0 - moveq #0,d3 - move.w (sp),d3 - or.w _EmulatedSR,d3 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd4 move.l (sp)+,d0 - moveq #0,d4 - move.w (sp),d4 - or.w _EmulatedSR,d4 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd5 move.l (sp)+,d0 - moveq #0,d5 - move.w (sp),d5 - or.w _EmulatedSR,d5 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd6 move.l (sp)+,d0 - moveq #0,d6 - move.w (sp),d6 - or.w _EmulatedSR,d6 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd7 move.l (sp)+,d0 - moveq #0,d7 - move.w (sp),d7 - or.w _EmulatedSR,d7 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; move dx,sr -movetosrd0 move.l (sp),d0 -storesr2 move.w d0,4(sp) - and.w #$00ff,4(sp) - and.w #$e700,d0 - move.w d0,_EmulatedSR - - and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled - bne.s 1$ - tst.l _InterruptFlags - beq.s 1$ - movem.l d0-d1/a0-a1/a6,-(sp) - move.l _SysBase,a6 - move.l _MainTask,a1 - move.l _IRQSigMask,d0 - JSRLIB Signal - movem.l (sp)+,d0-d1/a0-a1/a6 -1$ move.l (sp)+,d0 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movetosrd1 move.l d1,d0 - bra.s storesr2 - -movetosrd2 move.l d2,d0 - bra.s storesr2 - -movetosrd3 move.l d3,d0 - bra.s storesr2 - -movetosrd4 move.l d4,d0 - bra.s storesr2 - -movetosrd5 move.l d5,d0 - bra.s storesr2 - -movetosrd6 move.l d6,d0 - bra.s storesr2 - -movetosrd7 move.l d7,d0 - bra.s storesr2 - -; movec cr,x -movecfromcr move.w ([6,sp],2),d0 ;Get next instruction word - - cmp.w #$8801,d0 ;movec vbr,a0? - beq.s movecvbra0 - cmp.w #$9801,d0 ;movec vbr,a1? - beq.s movecvbra1 - cmp.w #$A801,d0 ;movec vbr,a2? - beq.s movecvbra2 - cmp.w #$1801,d0 ;movec vbr,d1? - beq movecvbrd1 - cmp.w #$0002,d0 ;movec cacr,d0? - beq.s moveccacrd0 - cmp.w #$1002,d0 ;movec cacr,d1? - beq.s moveccacrd1 - cmp.w #$0003,d0 ;movec tc,d0? - beq.s movectcd0 - cmp.w #$1003,d0 ;movec tc,d1? - beq.s movectcd1 - cmp.w #$1000,d0 ;movec sfc,d1? - beq movecsfcd1 - cmp.w #$1001,d0 ;movec dfc,d1? - beq movecdfcd1 - cmp.w #$0806,d0 ;movec urp,d0? - beq movecurpd0 - cmp.w #$0807,d0 ;movec srp,d0? - beq.s movecsrpd0 - cmp.w #$0004,d0 ;movec itt0,d0 - beq.s movecitt0d0 - cmp.w #$0005,d0 ;movec itt1,d0 - beq.s movecitt1d0 - cmp.w #$0006,d0 ;movec dtt0,d0 - beq.s movecdtt0d0 - cmp.w #$0007,d0 ;movec dtt1,d0 - beq.s movecdtt1d0 - - bra pv_unhandled - -; movec cacr,d0 -moveccacrd0 move.l (sp)+,d0 - move.l #$3111,d0 ;All caches and bursts on - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec cacr,d1 -moveccacrd1 move.l (sp)+,d0 - move.l #$3111,d1 ;All caches and bursts on - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec vbr,a0 -movecvbra0 move.l (sp)+,d0 - sub.l a0,a0 ;VBR always appears to be at 0 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec vbr,a1 -movecvbra1 move.l (sp)+,d0 - sub.l a1,a1 ;VBR always appears to be at 0 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec vbr,a2 -movecvbra2 move.l (sp)+,d0 - sub.l a2,a2 ;VBR always appears to be at 0 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec vbr,d1 -movecvbrd1 move.l (sp)+,d0 - moveq.l #0,d1 ;VBR always appears to be at 0 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec tc,d0 -movectcd0 addq.l #4,sp - moveq #0,d0 ;MMU is always off - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec tc,d1 +jl+ -movectcd1 move.l (sp)+,d0 ;Restore d0 - moveq #0,d1 ;MMU is always off - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec sfc,d1 +jl+ -movecsfcd1 move.l (sp)+,d0 ;Restore d0 - moveq #0,d1 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec dfc,d1 +jl+ -movecdfcd1 move.l (sp)+,d0 ;Restore d0 - moveq #0,d1 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movecurpd0 ; movec urp,d0 +jl+ -movecsrpd0 ; movec srp,d0 -movecitt0d0 ; movec itt0,d0 -movecitt1d0 ; movec itt1,d0 -movecdtt0d0 ; movec dtt0,d0 -movecdtt1d0 ; movec dtt1,d0 - addq.l #4,sp - moveq.l #0,d0 ;MMU is always off - addq.l #4,2(sp) ;skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec x,cr -movectocr move.w ([6,sp],2),d0 ;Get next instruction word - - cmp.w #$0801,d0 ;movec d0,vbr? - beq.s movectovbr - cmp.w #$1801,d0 ;movec d1,vbr? - beq.s movectovbr - cmp.w #$A801,d0 ;movec a2,vbr? - beq.s movectovbr - cmp.w #$0002,d0 ;movec d0,cacr? - beq.s movectocacr - cmp.w #$1002,d0 ;movec d1,cacr? - beq.s movectocacr - cmp.w #$1000,d0 ;movec d1,sfc? - beq.s movectoxfc - cmp.w #$1001,d0 ;movec d1,dfc? - beq.s movectoxfc - - bra pv_unhandled - -; movec x,vbr -movectovbr move.l (sp)+,d0 ;Ignore moves to VBR - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec dx,cacr -movectocacr movem.l d1/a0-a1/a6,-(sp) ;Move to CACR, clear caches - move.l _SysBase,a6 - JSRLIB CacheClearU - movem.l (sp)+,d1/a0-a1/a6 - move.l (sp)+,d0 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec x,sfc -; movec x,dfc -movectoxfc move.l (sp)+,d0 ;Ignore moves to SFC, DFC - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; cpusha -cpushadc -cpushadcic - IFEQ INFO_LEVEL-1003 - move.l (4),-(sp) - move.l d0,-(sp) - PUTMSG 0,'%s/cpushadc: opcode=%04lx Execbase=%08lx' - lea (2*4,sp),sp - ENDC - movem.l d1/a0-a1/a6,-(sp) ;Clear caches - move.l _SysBase,a6 - JSRLIB CacheClearU - movem.l (sp)+,d1/a0-a1/a6 - move.l (sp)+,d0 - addq.l #2,2(sp) - rte - -; move usp,a1 +jl+ -moveuspa1 move.l (sp)+,d0 - move usp,a1 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1009 - move.l a1,-(sp) - move.l a7,-(sp) - PUTMSG 0,'%s/moveuspa1: a7=%08lx a1=%08lx' - lea (2*4,sp),sp - ENDC - - rte - -; move usp,a0 +jl+ -moveuspa0 move.l (sp)+,d0 - move usp,a0 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1009 - move.l a0,-(sp) - move.l a7,-(sp) - PUTMSG 0,'%s/moveuspa0: a7=%08lx a0=%08lx' - lea (2*4,sp),sp - ENDC - - rte - -; move a1,usp +jl+ -moved1usp move.l (sp)+,d0 - move a1,usp - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; -; Trigger NMI (Pop up debugger) -; - -_AsmTriggerNMI move.l d0,-(sp) ;Save d0 - move.w #$007c,-(sp) ;Yes, fake NMI stack frame - pea 1$ - move.w _EmulatedSR,d0 - and.w #$f8ff,d0 ;Set interrupt level in SR - move.w d0,-(sp) - move.w d0,_EmulatedSR - - move.l $7c.w,-(sp) ;Jump to MacOS NMI handler - rts - -1$ move.l (sp)+,d0 ;Restore d0 - rts - - -CopyTrapStack: - movem.l d0/a0/a1,-(sp) - - move.w (5*4+6,sp),d0 ;get format word - lsr.w #7,d0 ;get stack frame Id - lsr.w #4,d0 - and.w #$001e,d0 - move.w (StackFormatTable,pc,d0.w),d0 ; get total stack frame length - - lea (5*4,sp),a0 ;get start of exception stack frame - move.l usp,a1 ;Get user stack pointer - bra 1$ - -2$ move.w (a0)+,(a1)+ ; copy additional stack words back to supervisor stack -1$ dbf d0,2$ - - move.l (3*4,sp),-(a0) ;copy return address to new top of stack - move.l a0,sp - rts - - END diff --git a/BasiliskII/src/AmigaOS/audio_amiga.cpp b/BasiliskII/src/AmigaOS/audio_amiga.cpp deleted file mode 100644 index 5c264314..00000000 --- a/BasiliskII/src/AmigaOS/audio_amiga.cpp +++ /dev/null @@ -1,515 +0,0 @@ -/* - * audio_amiga.cpp - Audio support, AmigaOS implementation using AHI - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "audio.h" -#include "audio_defs.h" - -#define DEBUG 0 -#include "debug.h" - -#define D1(x) ; - - -// Global variables -static ULONG ahi_id = AHI_DEFAULT_ID; // AHI audio ID -static struct AHIAudioCtrl *ahi_ctrl = NULL; -static struct AHISampleInfo sample[2]; // Two sample infos for double-buffering -static struct Hook sf_hook; -static int play_buf = 0; // Number of currently played buffer -static long sound_buffer_size; // Size of one audio buffer in bytes -static int audio_block_fetched = 0; // Number of audio blocks fetched by interrupt routine - -static bool main_mute = false; -static bool speaker_mute = false; -static ULONG supports_volume_changes = false; -static ULONG supports_stereo_panning = false; -static ULONG current_main_volume; -static ULONG current_speaker_volume; - - -// Prototypes -static __saveds __attribute__((regparm(3))) ULONG audio_callback(struct Hook *hook /*a0*/, struct AHISoundMessage *msg /*a1*/, struct AHIAudioCtrl *ahi_ctrl /*a2*/); -void audio_set_sample_rate_byval(uint32 value); -void audio_set_sample_size_byval(uint32 value); -void audio_set_channels_byval(uint32 value); - - -/* - * Initialization - */ - -// Set AudioStatus to reflect current audio stream format -static void set_audio_status_format(int sample_rate_index) -{ - AudioStatus.sample_rate = audio_sample_rates[sample_rate_index]; - AudioStatus.sample_size = audio_sample_sizes[0]; - AudioStatus.channels = audio_channel_counts[0]; -} - -void AudioInit(void) -{ - sample[0].ahisi_Address = sample[1].ahisi_Address = NULL; - - // Init audio status and feature flags - audio_channel_counts.push_back(2); -// set_audio_status_format(); - AudioStatus.mixer = 0; - AudioStatus.num_sources = 0; - audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; - - // Sound disabled in prefs? Then do nothing - if (PrefsFindBool("nosound")) - return; - - // AHI available? - if (AHIBase == NULL) { - WarningAlert(GetString(STR_NO_AHI_WARN)); - return; - } - - // Initialize callback hook - sf_hook.h_Entry = (HOOKFUNC)audio_callback; - - // Read "sound" preferences - const char *str = PrefsFindString("sound"); - if (str) - sscanf(str, "ahi/%08lx", &ahi_id); - - // Open audio control structure - if ((ahi_ctrl = AHI_AllocAudio( - AHIA_AudioID, ahi_id, - AHIA_MixFreq, AudioStatus.sample_rate >> 16, - AHIA_Channels, 1, - AHIA_Sounds, 2, - AHIA_SoundFunc, (ULONG)&sf_hook, - TAG_END)) == NULL) { - WarningAlert(GetString(STR_NO_AHI_CTRL_WARN)); - return; - } - - ULONG max_channels, sample_rate, frequencies, sample_rate_index; - - AHI_GetAudioAttrs(ahi_id, ahi_ctrl, - AHIDB_MaxChannels, (ULONG) &max_channels, - AHIDB_Frequencies, (ULONG) &frequencies, - TAG_END); - - D(bug("AudioInit: max_channels=%ld frequencies=%ld\n", max_channels, frequencies)); - - for (int n=0; n> 3) * AudioStatus.channels * audio_frames_per_block; - - // Prepare SampleInfos and load sounds (two sounds for double buffering) - sample[0].ahisi_Type = AudioStatus.sample_size == 16 ? AHIST_S16S : AHIST_S8S; - sample[0].ahisi_Length = audio_frames_per_block; - sample[0].ahisi_Address = AllocVec(sound_buffer_size, MEMF_PUBLIC | MEMF_CLEAR); - sample[1].ahisi_Type = AudioStatus.sample_size == 16 ? AHIST_S16S : AHIST_S8S; - sample[1].ahisi_Length = audio_frames_per_block; - sample[1].ahisi_Address = AllocVec(sound_buffer_size, MEMF_PUBLIC | MEMF_CLEAR); - if (sample[0].ahisi_Address == NULL || sample[1].ahisi_Address == NULL) - return; - - AHI_LoadSound(0, AHIST_DYNAMICSAMPLE, &sample[0], ahi_ctrl); - AHI_LoadSound(1, AHIST_DYNAMICSAMPLE, &sample[1], ahi_ctrl); - - // Set parameters - play_buf = 0; - current_main_volume = current_speaker_volume = 0x10000; - AHI_SetVol(0, current_speaker_volume, 0x8000, ahi_ctrl, AHISF_IMM); - - AHI_SetFreq(0, AudioStatus.sample_rate >> 16, ahi_ctrl, AHISF_IMM); - AHI_SetSound(0, play_buf, 0, 0, ahi_ctrl, AHISF_IMM); - - // Everything OK - audio_open = true; -} - - -/* - * Deinitialization - */ - -void AudioExit(void) -{ - // Free everything - if (ahi_ctrl != NULL) { - AHI_ControlAudio(ahi_ctrl, AHIC_Play, FALSE, TAG_END); - AHI_FreeAudio(ahi_ctrl); - } - - FreeVec(sample[0].ahisi_Address); - FreeVec(sample[1].ahisi_Address); -} - - -/* - * First source added, start audio stream - */ - -void audio_enter_stream() -{ - AHI_ControlAudio(ahi_ctrl, AHIC_Play, TRUE, TAG_END); -} - - -/* - * Last source removed, stop audio stream - */ - -void audio_exit_stream() -{ - AHI_ControlAudio(ahi_ctrl, AHIC_Play, FALSE, TAG_END); -} - - -/* - * AHI sound callback, request next buffer - */ - -static __saveds __attribute__((regparm(3))) ULONG audio_callback(struct Hook *hook /*a0*/, struct AHISoundMessage *msg /*a1*/, struct AHIAudioCtrl *ahi_ctrl /*a2*/) -{ - play_buf ^= 1; - - // New buffer available? - if (audio_block_fetched) - { - audio_block_fetched--; - - if (main_mute || speaker_mute) - { - memset(sample[play_buf].ahisi_Address, 0, sound_buffer_size); - } - else - { - // Get size of audio data - uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (apple_stream_info) { - int32 sample_count = ReadMacInt32(apple_stream_info + scd_sampleCount); - - uint32 num_channels = ReadMacInt16(apple_stream_info + scd_numChannels); - uint32 sample_size = ReadMacInt16(apple_stream_info + scd_sampleSize); - uint32 sample_rate = ReadMacInt32(apple_stream_info + scd_sampleRate); - - D(bug("stream: sample_count=%ld num_channels=%ld sample_size=%ld sample_rate=%ld\n", sample_count, num_channels, sample_size, sample_rate >> 16)); - - // Yes, this can happen. - if(sample_count != 0) { - if(sample_rate != AudioStatus.sample_rate) { - audio_set_sample_rate_byval(sample_rate); - } - if(num_channels != AudioStatus.channels) { - audio_set_channels_byval(num_channels); - } - if(sample_size != AudioStatus.sample_size) { - audio_set_sample_size_byval(sample_size); - } - } - - if (sample_count < 0) - sample_count = 0; - - int work_size = sample_count * num_channels * (sample_size>>3); - D(bug("stream: work_size=%ld sound_buffer_size=%ld\n", work_size, sound_buffer_size)); - - if (work_size > sound_buffer_size) - work_size = sound_buffer_size; - - // Put data into AHI buffer (convert 8-bit data unsigned->signed) - if (AudioStatus.sample_size == 16) - Mac2Host_memcpy(sample[play_buf].ahisi_Address, ReadMacInt32(apple_stream_info + scd_buffer), work_size); - else { - uint32 *p = (uint32 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)); - uint32 *q = (uint32 *)sample[play_buf].ahisi_Address; - int r = work_size >> 2; - while (r--) - *q++ = *p++ ^ 0x80808080; - } - if (work_size != sound_buffer_size) - memset((uint8 *)sample[play_buf].ahisi_Address + work_size, 0, sound_buffer_size - work_size); - } - } - - } - else - memset(sample[play_buf].ahisi_Address, 0, sound_buffer_size); - - // Play next buffer - AHI_SetSound(0, play_buf, 0, 0, ahi_ctrl, 0); - - // Trigger audio interrupt to get new buffer - if (AudioStatus.num_sources) { - D1(bug("stream: triggering irq\n")); - SetInterruptFlag(INTFLAG_AUDIO); - TriggerInterrupt(); - } - return 0; -} - - -/* - * MacOS audio interrupt, read next data block - */ - -void AudioInterrupt(void) -{ - D1(bug("AudioInterrupt\n")); - - // Get data from apple mixer - if (AudioStatus.mixer) { - M68kRegisters r; - r.a[0] = audio_data + adatStreamInfo; - r.a[1] = AudioStatus.mixer; - Execute68k(audio_data + adatGetSourceData, &r); - D1(bug(" GetSourceData() returns %08lx\n", r.d[0])); - } else - WriteMacInt32(audio_data + adatStreamInfo, 0); - - // Signal stream function - audio_block_fetched++; - D1(bug("AudioInterrupt done\n")); -} - - -/* - * Set sampling parameters - * "index" is an index into the audio_sample_rates[] etc. arrays - * It is guaranteed that AudioStatus.num_sources == 0 - */ - -void audio_set_sample_rate_byval(uint32 value) -{ - bool changed = (AudioStatus.sample_rate != value); - if(changed) - { - ULONG sample_rate_index; - - // get index of sample rate closest to Hz - AHI_GetAudioAttrs(ahi_id, ahi_ctrl, - AHIDB_IndexArg, value >> 16, - AHIDB_Index, (ULONG) &sample_rate_index, - TAG_END); - - D(bug(" audio_set_sample_rate_byval requested rate=%ld Hz\n", value >> 16)); - - AudioStatus.sample_rate = audio_sample_rates[sample_rate_index]; - - AHI_SetFreq(0, AudioStatus.sample_rate >> 16, ahi_ctrl, 0); - } - - D(bug(" audio_set_sample_rate_byval rate=%ld Hz\n", AudioStatus.sample_rate >> 16)); -} - -void audio_set_sample_size_byval(uint32 value) -{ - bool changed = (AudioStatus.sample_size != value); - if(changed) { -// AudioStatus.sample_size = value; -// update_sound_parameters(); -// WritePrivateProfileInt( "Audio", "SampleSize", AudioStatus.sample_size, ini_file_name ); - } - D(bug(" audio_set_sample_size_byval %d\n", AudioStatus.sample_size)); -} - -void audio_set_channels_byval(uint32 value) -{ - bool changed = (AudioStatus.channels != value); - if(changed) { -// AudioStatus.channels = value; -// update_sound_parameters(); -// WritePrivateProfileInt( "Audio", "Channels", AudioStatus.channels, ini_file_name ); - } - D(bug(" audio_set_channels_byval %d\n", AudioStatus.channels)); -} - -bool audio_set_sample_rate(int index) -{ - if(index >= 0 && index < audio_sample_rates.size() ) { - audio_set_sample_rate_byval( audio_sample_rates[index] ); - D(bug(" audio_set_sample_rate index=%ld rate=%ld\n", index, AudioStatus.sample_rate >> 16)); - } - - return true; -} - -bool audio_set_sample_size(int index) -{ - if(index >= 0 && index < audio_sample_sizes.size() ) { - audio_set_sample_size_byval( audio_sample_sizes[index] ); - D(bug(" audio_set_sample_size %d,%d\n", index,AudioStatus.sample_size)); - } - - return true; -} - -bool audio_set_channels(int index) -{ - if(index >= 0 && index < audio_channel_counts.size() ) { - audio_set_channels_byval( audio_channel_counts[index] ); - D(bug(" audio_set_channels %d,%d\n", index,AudioStatus.channels)); - } - - return true; -} - - -/* - * Get/set volume controls (volume values received/returned have the left channel - * volume in the upper 16 bits and the right channel volume in the lower 16 bits; - * both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume")) - */ - -bool audio_get_main_mute(void) -{ - D(bug("audio_get_main_mute: mute=%ld\n", main_mute)); - - return main_mute; -} - -uint32 audio_get_main_volume(void) -{ - D(bug("audio_get_main_volume\n")); - - ULONG volume = current_main_volume >> 8; // 0x10000 => 0x100 - - D(bug("audio_get_main_volume: volume=%08lx\n", volume)); - - return (volume << 16) + volume; - - return 0x01000100; -} - -bool audio_get_speaker_mute(void) -{ - D(bug("audio_get_speaker_mute: mute=%ld\n", speaker_mute)); - - return speaker_mute; -} - -uint32 audio_get_speaker_volume(void) -{ - D(bug("audio_get_speaker_volume: \n")); - - if (audio_open) - { - ULONG volume = current_speaker_volume >> 8; // 0x10000 => 0x100 - - D(bug("audio_get_speaker_volume: volume=%08lx\n", volume)); - - return (volume << 16) + volume; - } - - return 0x01000100; -} - -void audio_set_main_mute(bool mute) -{ - D(bug("audio_set_main_mute: mute=%ld\n", mute)); - - if (mute != main_mute) - { - main_mute = mute; - } -} - -void audio_set_main_volume(uint32 vol) -{ - D(bug("audio_set_main_volume: vol=%08lx\n", vol)); - - if (audio_open && supports_volume_changes) - { - ULONG volume = 0x80 * ((vol >> 16) + (vol & 0xffff)); - - D(bug("audio_set_main_volume: volume=%08lx\n", volume)); - - current_main_volume = volume; - - AHI_SetVol(0, volume, 0x8000, ahi_ctrl, AHISF_IMM); - } -} - -void audio_set_speaker_mute(bool mute) -{ - D(bug("audio_set_speaker_mute: mute=%ld\n", mute)); - - if (mute != speaker_mute) - { - speaker_mute = mute; - } -} - -void audio_set_speaker_volume(uint32 vol) -{ - D(bug("audio_set_speaker_volume: vol=%08lx\n", vol)); - - if (audio_open && supports_volume_changes) - { - ULONG volume = 0x80 * ((vol >> 16) + (vol & 0xffff)); - - D(bug("audio_set_speaker_volume: volume=%08lx\n", volume)); - - current_speaker_volume = volume; - - AHI_SetVol(0, volume, 0x8000, ahi_ctrl, AHISF_IMM); - } -} diff --git a/BasiliskII/src/AmigaOS/clip_amiga.cpp b/BasiliskII/src/AmigaOS/clip_amiga.cpp deleted file mode 100644 index 10336bbd..00000000 --- a/BasiliskII/src/AmigaOS/clip_amiga.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * clip_amiga.cpp - Clipboard handling, AmigaOS implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include - -#include "clip.h" -#include "prefs.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static struct IFFHandle *iffw = NULL; -static struct ClipboardHandle *ch = NULL; -static bool clipboard_open = false; -static bool no_clip_conversion; - - -// Conversion tables -static const uint8 mac2iso[0x80] = { - 0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1, - 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8, - 0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3, - 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc, - 0x2b, 0xb0, 0xa2, 0xa3, 0xa7, 0xb7, 0xb6, 0xdf, - 0xae, 0xa9, 0x20, 0xb4, 0xa8, 0x23, 0xc6, 0xd8, - 0x20, 0xb1, 0x3c, 0x3e, 0xa5, 0xb5, 0xf0, 0x53, - 0x50, 0x70, 0x2f, 0xaa, 0xba, 0x4f, 0xe6, 0xf8, - 0xbf, 0xa1, 0xac, 0x2f, 0x66, 0x7e, 0x44, 0xab, - 0xbb, 0x2e, 0x20, 0xc0, 0xc3, 0xd5, 0x4f, 0x6f, - 0x2d, 0x2d, 0x22, 0x22, 0x60, 0x27, 0xf7, 0x20, - 0xff, 0x59, 0x2f, 0xa4, 0x3c, 0x3e, 0x66, 0x66, - 0x23, 0xb7, 0x2c, 0x22, 0x25, 0xc2, 0xca, 0xc1, - 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4, - 0x20, 0xd2, 0xda, 0xdb, 0xd9, 0x69, 0x5e, 0x7e, - 0xaf, 0x20, 0xb7, 0xb0, 0xb8, 0x22, 0xb8, 0x20 -}; - - -/* - * Initialization - */ - -void ClipInit(void) -{ - no_clip_conversion = PrefsFindBool("noclipconversion"); - - // Create clipboard IFF handle - iffw = AllocIFF(); - if (iffw) { - ch = OpenClipboard(PRIMARY_CLIP); - if (ch) { - iffw->iff_Stream = (ULONG)ch; - InitIFFasClip(iffw); - clipboard_open = true; - } - } -} - - -/* - * Deinitialization - */ - -void ClipExit(void) -{ - if (ch) - CloseClipboard(ch); - if (iffw) - FreeIFF(iffw); -} - -/* - * Mac application zeroes clipboard - */ - -void ZeroScrap() -{ - -} - -/* - * Mac application reads clipboard - */ - -void GetScrap(void **handle, uint32 type, int32 offset) -{ - D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset)); -} - - -/* - * Mac application wrote to clipboard - */ - -void PutScrap(uint32 type, void *scrap, int32 length) -{ - D(bug("PutScrap type %08lx, data %08lx, length %ld\n", type, scrap, length)); - if (length <= 0 || !clipboard_open) - return; - - switch (type) { - case 'TEXT': { - D(bug(" clipping TEXT\n")); - - // Open IFF stream - if (OpenIFF(iffw, IFFF_WRITE)) - break; - - // Convert text from Mac charset to ISO-Latin1 - uint8 *buf = new uint8[length]; - uint8 *p = (uint8 *)scrap; - uint8 *q = buf; - for (int i=0; i LF - c = 10; - } else if (!no_clip_conversion) - c = mac2iso[c & 0x7f]; - *q++ = c; - } - - // Write text - if (!PushChunk(iffw, 'FTXT', 'FORM', IFFSIZE_UNKNOWN)) { - if (!PushChunk(iffw, 0, 'CHRS', IFFSIZE_UNKNOWN)) { - WriteChunkBytes(iffw, scrap, length); - PopChunk(iffw); - } - PopChunk(iffw); - } - - // Close IFF stream - CloseIFF(iffw); - delete[] buf; - break; - } - } -} diff --git a/BasiliskII/src/AmigaOS/ether_amiga.cpp b/BasiliskII/src/AmigaOS/ether_amiga.cpp deleted file mode 100644 index 99121a24..00000000 --- a/BasiliskII/src/AmigaOS/ether_amiga.cpp +++ /dev/null @@ -1,705 +0,0 @@ -/* - * ether_amiga.cpp - Ethernet device driver, AmigaOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "macos_util.h" -#include "ether.h" -#include "ether_defs.h" - -#define DEBUG 0 -#include "debug.h" - -#define MONITOR 0 - - -// These messages are sent to the network process -const uint32 MSG_CLEANUP = 'clea'; // Remove all protocols -const uint32 MSG_ADD_MULTI = 'addm'; // Add multicast address -const uint32 MSG_DEL_MULTI = 'delm'; // Add multicast address -const uint32 MSG_ATTACH_PH = 'atph'; // Attach protocol handler -const uint32 MSG_DETACH_PH = 'deph'; // Attach protocol handler -const uint32 MSG_WRITE = 'writ'; // Write packet - -struct NetMessage : public Message { - NetMessage(uint32 what_, const struct MsgPort *reply_port) - { - what = what_; - mn_ReplyPort = (struct MsgPort *)reply_port; - mn_Length = sizeof(*this); - } - uint32 what; - uint32 pointer; - uint16 type; - int16 result; -}; - - -// List of attached protocols -static const int NUM_READ_REQUESTS = 32; // Number of read requests that are sent to device in advance - -struct NetProtocol : public Node { - struct IOSana2Req read_io[NUM_READ_REQUESTS]; - uint8 read_buf[NUM_READ_REQUESTS][1518]; // 14 bytes header, 1500 bytes data, 4 bytes CRC - uint16 type; - uint32 handler; -}; - -static struct List prot_list; - - -// Global variables -static struct Process *net_proc = NULL; // Network device handler process -static bool proc_error; // Flag: process didn't initialize -static struct MsgPort *proc_port = NULL; // Message port of process, for communication with main task -static struct MsgPort *reply_port = NULL; // Reply port for communication with process -static struct MsgPort *read_port = NULL; // Reply port for read IORequests (set up and owned by network process) - -static bool write_done = false; // Flag: write request done - -extern struct Task *MainTask; // Pointer to main task (from main_amiga.cpp) - - -// Prototypes -static void net_func(void); - - -/* - * Send message to network process - */ - -static int16 send_to_proc(uint32 what, uint32 pointer = 0, uint16 type = 0) -{ - D(bug("sending %08lx to net_proc\n", what)); - NetMessage msg(what, reply_port); - msg.pointer = pointer; - msg.type = type; - PutMsg(proc_port, &msg); - WaitPort(reply_port); - GetMsg(reply_port); - D(bug(" sent\n")); - return msg.result; -} - - -/* - * Initialization - */ - -bool ether_init(void) -{ - // Do nothing if no Ethernet device specified - if (PrefsFindString("ether") == NULL) - return false; - - // Initialize protocol list - NewList(&prot_list); - - // Create message port - reply_port = CreateMsgPort(); - if (reply_port == NULL) - goto open_error; - D(bug("signal mask %08lx\n", 1 << reply_port->mp_SigBit)); - - // Start process - proc_error = false; - SetSignal(0, SIGF_SINGLE); - net_proc = CreateNewProcTags( - NP_Entry, (ULONG)net_func, - NP_Name, (ULONG)"Basilisk II Ethernet Task", - NP_Priority, 1, - TAG_END - ); - if (net_proc == NULL) - goto open_error; - - // Wait for signal from process - Wait(SIGF_SINGLE); - - // Initialization error? Then bail out - if (proc_error) - goto open_error; - - // Everything OK - return true; - -open_error: - net_proc = NULL; - if (reply_port) { - DeleteMsgPort(reply_port); - reply_port = NULL; - } - return false; -} - - -/* - * Deinitialization - */ - -void ether_exit(void) -{ - // Stop process - if (net_proc) { - SetSignal(0, SIGF_SINGLE); - Signal(&net_proc->pr_Task, SIGBREAKF_CTRL_C); - Wait(SIGF_SINGLE); - } - - // Delete reply port - if (reply_port) { - DeleteMsgPort(reply_port); - reply_port = NULL; - } -} - - -/* - * Reset - */ - -void ether_reset(void) -{ - // Remove all protocols - if (net_proc) - send_to_proc(MSG_CLEANUP); -} - - -/* - * Add multicast address - */ - -int16 ether_add_multicast(uint32 pb) -{ - return send_to_proc(MSG_ADD_MULTI, pb); -} - - -/* - * Delete multicast address - */ - -int16 ether_del_multicast(uint32 pb) -{ - return send_to_proc(MSG_DEL_MULTI, pb); -} - - -/* - * Attach protocol handler - */ - -int16 ether_attach_ph(uint16 type, uint32 handler) -{ - return send_to_proc(MSG_ATTACH_PH, handler, type); -} - - -/* - * Detach protocol handler - */ - -int16 ether_detach_ph(uint16 type) -{ - return send_to_proc(MSG_DETACH_PH, type); -} - - -/* - * Transmit raw ethernet packet - */ - -int16 ether_write(uint32 wds) -{ - send_to_proc(MSG_WRITE, wds); - return 1; // Command in progress -} - - -/* - * Remove protocol from protocol list - */ - -static void remove_protocol(NetProtocol *p) -{ - // Remove from list - Forbid(); - Remove(p); - Permit(); - - // Cancel read requests - for (int i=0; iread_io + i)); - WaitIO((struct IORequest *)(p->read_io + i)); - } - - // Free protocol struct - FreeMem(p, sizeof(NetProtocol)); -} - - -/* - * Remove all protocols - */ - -static void remove_all_protocols(void) -{ - NetProtocol *n = (NetProtocol *)prot_list.lh_Head, *next; - while ((next = (NetProtocol *)n->ln_Succ) != NULL) { - remove_protocol(n); - n = next; - } -} - - -/* - * Copy received network packet to Mac side - */ - -static __saveds __regargs LONG copy_to_buff(uint8 *to /*a0*/, uint8 *from /*a1*/, uint32 packet_len /*d0*/) -{ - D(bug("CopyToBuff to %08lx, from %08lx, size %08lx\n", to, from, packet_len)); - - // It would be more efficient (and take up less memory) if we - // could invoke the packet handler from here. But we don't know - // in what context we run, so calling Execute68k() would not be - // a good idea, and even worse, we might run inside a hardware - // interrupt, so we can't even trigger a Basilisk interrupt from - // here and wait for its completion. - CopyMem(from, to, packet_len); -#if MONITOR - bug("Receiving Ethernet packet:\n"); - for (int i=0; imp_SigBit; - - // Create message ports for device I/O - read_port = CreateMsgPort(); - if (read_port == NULL) - goto quit; - read_mask = 1 << read_port->mp_SigBit; - write_port = CreateMsgPort(); - if (write_port == NULL) - goto quit; - write_mask = 1 << write_port->mp_SigBit; - control_port = CreateMsgPort(); - if (control_port == NULL) - goto quit; - - // Create control IORequest - control_io = (struct IOSana2Req *)CreateIORequest(control_port, sizeof(struct IOSana2Req)); - if (control_io == NULL) - goto quit; - control_io->ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug - - // Parse device name - char dev_name[256]; - ULONG dev_unit; - - str = PrefsFindString("ether"); - if (str) { - const char *FirstSlash = strchr(str, '/'); - const char *LastSlash = strrchr(str, '/'); - - if (FirstSlash && FirstSlash && FirstSlash != LastSlash) { - - // Device name contains path, i.e. "Networks/xyzzy.device" - const char *lp = str; - char *dp = dev_name; - - while (lp != LastSlash) - *dp++ = *lp++; - *dp = '\0'; - - if (strlen(dev_name) < 1) - goto quit; - - if (sscanf(LastSlash, "/%ld", &dev_unit) != 1) - goto quit; - } else { - if (sscanf(str, "%[^/]/%ld", dev_name, &dev_unit) != 2) - goto quit; - } - } else - goto quit; - - // Open device - control_io->ios2_BufferManagement = buffer_tags; - od_error = OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)control_io, 0); - if (od_error != 0 || control_io->ios2_Req.io_Device == 0) { - printf("WARNING: OpenDevice(<%s>, unit=%d) returned error %d)\n", (UBYTE *)dev_name, dev_unit, od_error); - goto quit; - } - opened = true; - - // Is it Ethernet? - control_io->ios2_Req.io_Command = S2_DEVICEQUERY; - control_io->ios2_StatData = (void *)&query_data; - DoIO((struct IORequest *)control_io); - if (control_io->ios2_Req.io_Error) - goto quit; - if (query_data.HardwareType != S2WireType_Ethernet) { - WarningAlert(GetString(STR_NOT_ETHERNET_WARN)); - goto quit; - } - - // Yes, create IORequest for writing - write_io = (struct IOSana2Req *)CreateIORequest(write_port, sizeof(struct IOSana2Req)); - if (write_io == NULL) - goto quit; - memcpy(write_io, control_io, sizeof(struct IOSana2Req)); - write_io->ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug - write_io->ios2_Req.io_Message.mn_ReplyPort = write_port; - - // Configure Ethernet - control_io->ios2_Req.io_Command = S2_GETSTATIONADDRESS; - DoIO((struct IORequest *)control_io); - memcpy(ether_addr, control_io->ios2_DstAddr, 6); - memcpy(control_io->ios2_SrcAddr, control_io->ios2_DstAddr, 6); - control_io->ios2_Req.io_Command = S2_CONFIGINTERFACE; - DoIO((struct IORequest *)control_io); - D(bug("Ethernet address %08lx %08lx\n", *(uint32 *)ether_addr, *(uint16 *)(ether_addr + 4))); - - // Initialization went well, inform main task - proc_error = false; - Signal(MainTask, SIGF_SINGLE); - - // Main loop - for (;;) { - - // Wait for I/O and messages (CTRL_C is used for quitting the task) - ULONG sig = Wait(proc_port_mask | read_mask | write_mask | SIGBREAKF_CTRL_C); - - // Main task wants to quit us - if (sig & SIGBREAKF_CTRL_C) - break; - - // Main task sent a command to us - if (sig & proc_port_mask) { - struct NetMessage *msg; - while (msg = (NetMessage *)GetMsg(proc_port)) { - D(bug("net_proc received %08lx\n", msg->what)); - switch (msg->what) { - case MSG_CLEANUP: - remove_all_protocols(); - break; - - case MSG_ADD_MULTI: - control_io->ios2_Req.io_Command = S2_ADDMULTICASTADDRESS; - Mac2Host_memcpy(control_io->ios2_SrcAddr, msg->pointer + eMultiAddr, 6); - DoIO((struct IORequest *)control_io); - if (control_io->ios2_Req.io_Error == S2ERR_NOT_SUPPORTED) { - WarningAlert(GetString(STR_NO_MULTICAST_WARN)); - msg->result = noErr; - } else if (control_io->ios2_Req.io_Error) - msg->result = eMultiErr; - else - msg->result = noErr; - break; - - case MSG_DEL_MULTI: - control_io->ios2_Req.io_Command = S2_DELMULTICASTADDRESS; - Mac2Host_memcpy(control_io->ios2_SrcAddr, msg->pointer + eMultiAddr, 6); - DoIO((struct IORequest *)control_io); - if (control_io->ios2_Req.io_Error) - msg->result = eMultiErr; - else - msg->result = noErr; - break; - - case MSG_ATTACH_PH: { - uint16 type = msg->type; - uint32 handler = msg->pointer; - - // Protocol of that type already installed? - NetProtocol *p = (NetProtocol *)prot_list.lh_Head, *next; - while ((next = (NetProtocol *)p->ln_Succ) != NULL) { - if (p->type == type) { - msg->result = lapProtErr; - goto reply; - } - p = next; - } - - // Allocate NetProtocol, set type and handler - p = (NetProtocol *)AllocMem(sizeof(NetProtocol), MEMF_PUBLIC); - if (p == NULL) { - msg->result = lapProtErr; - goto reply; - } - p->type = type; - p->handler = handler; - - // Set up and submit read requests - for (int i=0; iread_io + i, control_io, sizeof(struct IOSana2Req)); - p->read_io[i].ios2_Req.io_Message.mn_Node.ln_Name = (char *)p; // Hide pointer to NetProtocol in node name - p->read_io[i].ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug - p->read_io[i].ios2_Req.io_Message.mn_ReplyPort = read_port; - p->read_io[i].ios2_Req.io_Command = CMD_READ; - p->read_io[i].ios2_PacketType = type; - p->read_io[i].ios2_Data = p->read_buf[i]; - p->read_io[i].ios2_Req.io_Flags = SANA2IOF_RAW; - BeginIO((struct IORequest *)(p->read_io + i)); - } - - // Add protocol to list - AddTail(&prot_list, p); - - // Everything OK - msg->result = noErr; - break; - } - - case MSG_DETACH_PH: { - uint16 type = msg->type; - msg->result = lapProtErr; - NetProtocol *p = (NetProtocol *)prot_list.lh_Head, *next; - while ((next = (NetProtocol *)p->ln_Succ) != NULL) { - if (p->type == type) { - remove_protocol(p); - msg->result = noErr; - break; - } - p = next; - } - break; - } - - case MSG_WRITE: { - // Get pointer to Write Data Structure - uint32 wds = msg->pointer; - write_io->ios2_Data = (void *)wds; - - // Calculate total packet length - long len = 0; - uint32 tmp = wds; - for (;;) { - int16 w = ReadMacInt16(tmp); - if (w == 0) - break; - len += w; - tmp += 6; - } - write_io->ios2_DataLength = len; - - // Get destination address - uint32 hdr = ReadMacInt32(wds + 2); - Mac2Host_memcpy(write_io->ios2_DstAddr, hdr, 6); - - // Get packet type - uint32 type = ReadMacInt16(hdr + 12); - if (type <= 1500) - type = 0; // 802.3 packet - write_io->ios2_PacketType = type; - - // Multicast/broadcard packet? - if (write_io->ios2_DstAddr[0] & 1) { - if (*(uint32 *)(write_io->ios2_DstAddr) == 0xffffffff && *(uint16 *)(write_io->ios2_DstAddr + 4) == 0xffff) - write_io->ios2_Req.io_Command = S2_BROADCAST; - else - write_io->ios2_Req.io_Command = S2_MULTICAST; - } else - write_io->ios2_Req.io_Command = CMD_WRITE; - - // Send packet - write_done = false; - write_io->ios2_Req.io_Flags = SANA2IOF_RAW; - BeginIO((IORequest *)write_io); - break; - } - } -reply: D(bug(" net_proc replying\n")); - ReplyMsg(msg); - } - } - - // Packet received - if (sig & read_mask) { - D(bug(" packet received, triggering Ethernet interrupt\n")); - SetInterruptFlag(INTFLAG_ETHER); - TriggerInterrupt(); - } - - // Packet write completed - if (sig & write_mask) { - GetMsg(write_port); - WriteMacInt32(ether_data + ed_Result, write_io->ios2_Req.io_Error ? excessCollsns : 0); - write_done = true; - D(bug(" packet write done, triggering Ethernet interrupt\n")); - SetInterruptFlag(INTFLAG_ETHER); - TriggerInterrupt(); - } - } -quit: - - // Close everything - remove_all_protocols(); - if (opened) { - if (CheckIO((struct IORequest *)write_io) == 0) { - AbortIO((struct IORequest *)write_io); - WaitIO((struct IORequest *)write_io); - } - CloseDevice((struct IORequest *)control_io); - } - if (write_io) - DeleteIORequest(write_io); - if (control_io) - DeleteIORequest(control_io); - if (control_port) - DeleteMsgPort(control_port); - if (write_port) - DeleteMsgPort(write_port); - if (read_port) - DeleteMsgPort(read_port); - - // Send signal to main task to confirm termination - Forbid(); - Signal(MainTask, SIGF_SINGLE); -} - - -/* - * Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers - */ - -void EtherInterrupt(void) -{ - D(bug("EtherIRQ\n")); - - // Packet write done, enqueue DT to call IODone - if (write_done) { - EnqueueMac(ether_data + ed_DeferredTask, 0xd92); - write_done = false; - } - - // Call protocol handler for received packets - IOSana2Req *io; - while (io = (struct IOSana2Req *)GetMsg(read_port)) { - - // Get pointer to NetProtocol (hidden in node name) - NetProtocol *p = (NetProtocol *)io->ios2_Req.io_Message.mn_Node.ln_Name; - - // No default handler - if (p->handler == 0) - continue; - - // Copy header to RHA - Host2Mac_memcpy(ether_data + ed_RHA, io->ios2_Data, 14); - D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12))); - - // Call protocol handler - M68kRegisters r; - r.d[0] = *(uint16 *)((uint32)io->ios2_Data + 12); // Packet type - r.d[1] = io->ios2_DataLength - 18; // Remaining packet length (without header, for ReadPacket) (-18 because the CRC is also included) - r.a[0] = (uint32)io->ios2_Data + 14; // Pointer to packet (host address, for ReadPacket) - r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA - r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines - D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", p->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4])); - Execute68k(p->handler, &r); - - // Resend IORequest - io->ios2_Req.io_Flags = SANA2IOF_RAW; - BeginIO((struct IORequest *)io); - } - D(bug(" EtherIRQ done\n")); -} diff --git a/BasiliskII/src/AmigaOS/extfs_amiga.cpp b/BasiliskII/src/AmigaOS/extfs_amiga.cpp deleted file mode 100644 index 9f157e29..00000000 --- a/BasiliskII/src/AmigaOS/extfs_amiga.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* - * extfs_amiga.cpp - MacOS file system for access native file system access, AmigaOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#define __USE_SYSBASE -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "extfs.h" -#include "extfs_defs.h" - -#define DEBUG 0 -#include "debug.h" - - -// Default Finder flags -const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited; - - -/* - * Initialization - */ - -void extfs_init(void) -{ -} - - -/* - * Deinitialization - */ - -void extfs_exit(void) -{ -} - - -/* - * Add component to path name - */ - -void add_path_component(char *path, const char *component) -{ - AddPart(path, (char *)component, MAX_PATH_LENGTH); -} - - -/* - * Finder info and resource forks are kept in helper files - * - * Finder info: - * /path/.finf/file - * Resource fork: - * /path/.rsrc/file - * - * The .finf files store a FInfo/DInfo, followed by a FXInfo/DXInfo - * (16+16 bytes) - */ - -static void make_helper_path(const char *src, char *dest, const char *add, bool only_dir = false) -{ - dest[0] = 0; - - // Get pointer to last component of path - const char *last_part = FilePart((char *)src); - - // Copy everything before - strncpy(dest, src, last_part-src); - dest[last_part-src] = 0; - - // Add additional component - AddPart(dest, (char *)add, MAX_PATH_LENGTH); - - // Add last component - if (!only_dir) - AddPart(dest, (char *)last_part, MAX_PATH_LENGTH); -} - -static int create_helper_dir(const char *path, const char *add) -{ - char helper_dir[MAX_PATH_LENGTH]; - make_helper_path(path, helper_dir, add, true); - if (helper_dir[strlen(helper_dir) - 1] == '/') // Remove trailing "/" - helper_dir[strlen(helper_dir) - 1] = 0; - return mkdir(helper_dir, 0777); -} - -static int open_helper(const char *path, const char *add, int flag) -{ - char helper_path[MAX_PATH_LENGTH]; - make_helper_path(path, helper_path, add); - - if ((flag & O_ACCMODE) == O_RDWR || (flag & O_ACCMODE) == O_WRONLY) - flag |= O_CREAT; - int fd = open(helper_path, flag, 0666); - if (fd < 0) { - if (errno == ENOENT && (flag & O_CREAT)) { - // One path component was missing, probably the helper - // directory. Try to create it and re-open the file. - int ret = create_helper_dir(path, add); - if (ret < 0) - return ret; - fd = open(helper_path, flag, 0666); - } - } - return fd; -} - -static int open_finf(const char *path, int flag) -{ - return open_helper(path, ".finf/", flag); -} - -static int open_rsrc(const char *path, int flag) -{ - return open_helper(path, ".rsrc/", flag); -} - - -/* - * Get/set finder type/creator for file specified by full path - */ - -struct ext2type { - const char *ext; - uint32 type; - uint32 creator; -}; - -static const ext2type e2t_translation[] = { - {".z", FOURCC('Z','I','V','M'), FOURCC('L','Z','I','V')}, - {".gz", FOURCC('G','z','i','p'), FOURCC('G','z','i','p')}, - {".hqx", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".bin", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".pdf", FOURCC('P','D','F',' '), FOURCC('C','A','R','O')}, - {".ps", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')}, - {".sit", FOURCC('S','I','T','!'), FOURCC('S','I','T','x')}, - {".tar", FOURCC('T','A','R','F'), FOURCC('T','A','R',' ')}, - {".uu", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".uue", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".zip", FOURCC('Z','I','P',' '), FOURCC('Z','I','P',' ')}, - {".8svx", FOURCC('8','S','V','X'), FOURCC('S','N','D','M')}, - {".aifc", FOURCC('A','I','F','C'), FOURCC('T','V','O','D')}, - {".aiff", FOURCC('A','I','F','F'), FOURCC('T','V','O','D')}, - {".au", FOURCC('U','L','A','W'), FOURCC('T','V','O','D')}, - {".mid", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')}, - {".midi", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')}, - {".mp2", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')}, - {".mp3", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')}, - {".wav", FOURCC('W','A','V','E'), FOURCC('T','V','O','D')}, - {".bmp", FOURCC('B','M','P','f'), FOURCC('o','g','l','e')}, - {".gif", FOURCC('G','I','F','f'), FOURCC('o','g','l','e')}, - {".lbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')}, - {".ilbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')}, - {".jpg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')}, - {".jpeg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')}, - {".pict", FOURCC('P','I','C','T'), FOURCC('o','g','l','e')}, - {".png", FOURCC('P','N','G','f'), FOURCC('o','g','l','e')}, - {".sgi", FOURCC('.','S','G','I'), FOURCC('o','g','l','e')}, - {".tga", FOURCC('T','P','I','C'), FOURCC('o','g','l','e')}, - {".tif", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')}, - {".tiff", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')}, - {".htm", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')}, - {".html", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')}, - {".txt", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')}, - {".rtf", FOURCC('T','E','X','T'), FOURCC('M','S','W','D')}, - {".c", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cc", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".h", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hh", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".s", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".i", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".mpg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')}, - {".mpeg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')}, - {".mov", FOURCC('M','o','o','V'), FOURCC('T','V','O','D')}, - {".fli", FOURCC('F','L','I',' '), FOURCC('T','V','O','D')}, - {".avi", FOURCC('V','f','W',' '), FOURCC('T','V','O','D')}, - {".qxd", FOURCC('X','D','O','C'), FOURCC('X','P','R','3')}, - {".hfv", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')}, - {".dsk", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')}, - {".img", FOURCC('r','o','h','d'), FOURCC('d','d','s','k')}, - {NULL, 0, 0} // End marker -}; - -void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Set default finder info - Mac_memset(finfo, 0, SIZEOF_FInfo); - if (fxinfo) - Mac_memset(fxinfo, 0, SIZEOF_FXInfo); - WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS); - WriteMacInt32(finfo + fdLocation, (uint32)-1); - - // Read Finder info file - int fd = open_finf(path, O_RDONLY); - if (fd >= 0) { - ssize_t actual = read(fd, Mac2HostAddr(finfo), SIZEOF_FInfo); - if (fxinfo) - actual += read(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo); - close(fd); - if (actual >= SIZEOF_FInfo) - return; - } - - // No Finder info file, translate file name extension to MacOS type/creator - if (!is_dir) { - int path_len = strlen(path); - for (int i=0; e2t_translation[i].ext; i++) { - int ext_len = strlen(e2t_translation[i].ext); - if (path_len < ext_len) - continue; - if (!strcasecmp(path + path_len - ext_len, e2t_translation[i].ext)) { - WriteMacInt32(finfo + fdType, e2t_translation[i].type); - WriteMacInt32(finfo + fdCreator, e2t_translation[i].creator); - break; - } - } - } -} - -void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Open Finder info file - int fd = open_finf(path, O_RDWR); - if (fd < 0) - return; - - // Write file - write(fd, Mac2HostAddr(finfo), SIZEOF_FInfo); - if (fxinfo) - write(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo); - close(fd); -} - - -/* - * Resource fork emulation functions - */ - -uint32 get_rfork_size(const char *path) -{ - // Open resource file - int fd = open_rsrc(path, O_RDONLY); - if (fd < 0) - return 0; - - // Get size - off_t size = lseek(fd, 0, SEEK_END); - - // Close file and return size - close(fd); - return size < 0 ? 0 : size; -} - -int open_rfork(const char *path, int flag) -{ - return open_rsrc(path, flag); -} - -void close_rfork(const char *path, int fd) -{ - close(fd); -} - - -/* - * Read "length" bytes from file to "buffer", - * returns number of bytes read (or -1 on error) - */ - -ssize_t extfs_read(int fd, void *buffer, size_t length) -{ - return read(fd, buffer, length); -} - - -/* - * Write "length" bytes from "buffer" to file, - * returns number of bytes written (or -1 on error) - */ - -ssize_t extfs_write(int fd, void *buffer, size_t length) -{ - return write(fd, buffer, length); -} - - -/* - * Remove file/directory (and associated helper files), - * returns false on error (and sets errno) - */ - -bool extfs_remove(const char *path) -{ - // Remove helpers first, don't complain if this fails - char helper_path[MAX_PATH_LENGTH]; - make_helper_path(path, helper_path, ".finf/", false); - remove(helper_path); - make_helper_path(path, helper_path, ".rsrc/", false); - remove(helper_path); - - // Now remove file or directory (and helper directories in the directory) - if (remove(path) < 0) { - if (errno == EISDIR || errno == ENOTEMPTY) { - helper_path[0] = 0; - strncpy(helper_path, path, MAX_PATH_LENGTH-1); - add_path_component(helper_path, ".finf"); - rmdir(helper_path); - helper_path[0] = 0; - strncpy(helper_path, path, MAX_PATH_LENGTH-1); - add_path_component(helper_path, ".rsrc"); - rmdir(helper_path); - return rmdir(path) == 0; - } else - return false; - } - return true; -} - - -/* - * Rename/move file/directory (and associated helper files), - * returns false on error (and sets errno) - */ - -bool extfs_rename(const char *old_path, const char *new_path) -{ - // Rename helpers first, don't complain if this fails - char old_helper_path[MAX_PATH_LENGTH], new_helper_path[MAX_PATH_LENGTH]; - make_helper_path(old_path, old_helper_path, ".finf/", false); - make_helper_path(new_path, new_helper_path, ".finf/", false); - create_helper_dir(new_path, ".finf/"); - rename(old_helper_path, new_helper_path); - make_helper_path(old_path, old_helper_path, ".rsrc/", false); - make_helper_path(new_path, new_helper_path, ".rsrc/", false); - create_helper_dir(new_path, ".rsrc/"); - rename(old_helper_path, new_helper_path); - - // Now rename file - return rename(old_path, new_path) == 0; -} - - -/* - * ftruncate() is missing from libnix - */ - -extern unsigned long *__stdfiledes; - -int ftruncate(int fd, off_t size) -{ - if (SetFileSize(__stdfiledes[fd], size, OFFSET_BEGINNING) < 0) - return -1; - else - return 0; -} diff --git a/BasiliskII/src/AmigaOS/main_amiga.cpp b/BasiliskII/src/AmigaOS/main_amiga.cpp deleted file mode 100644 index 90ac6db2..00000000 --- a/BasiliskII/src/AmigaOS/main_amiga.cpp +++ /dev/null @@ -1,743 +0,0 @@ -/* - * main_amiga.cpp - Startup code for AmigaOS - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "xpram.h" -#include "timer.h" -#include "sony.h" -#include "disk.h" -#include "cdrom.h" -#include "scsi.h" -#include "audio.h" -#include "video.h" -#include "serial.h" -#include "ether.h" -#include "clip.h" -#include "emul_op.h" -#include "rom_patches.h" -#include "prefs.h" -#include "prefs_editor.h" -#include "sys.h" -#include "user_strings.h" -#include "version.h" - -#define DEBUG 0 -#include "debug.h" - - -// Options for libnix -unsigned long __stack = 0x4000; // Stack requirement -int __nocommandline = 1; // Disable command line parsing - - -// Constants -static const char ROM_FILE_NAME[] = "ROM"; -static const char __ver[] = "$VER: " VERSION_STRING " " __DATE__; -static const int SCRATCH_MEM_SIZE = 65536; - - -// RAM and ROM pointers -uint32 RAMBaseMac; // RAM base (Mac address space) -uint8 *RAMBaseHost; // RAM base (host address space) -uint32 RAMSize; // Size of RAM -uint32 ROMBaseMac; // ROM base (Mac address space) -uint8 *ROMBaseHost; // ROM base (host address space) -uint32 ROMSize; // Size of ROM - - -// CPU and FPU type, addressing mode -int CPUType; -bool CPUIs68060; -int FPUType; -bool TwentyFourBitAddressing; - - -// Global variables -extern ExecBase *SysBase; -struct Library *GfxBase = NULL; -struct IntuitionBase *IntuitionBase = NULL; -struct Library *GadToolsBase = NULL; -struct Library *IFFParseBase = NULL; -struct Library *AslBase = NULL; -struct Library *P96Base = NULL; -struct Library *CyberGfxBase = NULL; -struct Library *TimerBase = NULL; -struct Library *AHIBase = NULL; -struct Library *DiskBase = NULL; - -struct Task *MainTask; // Our task -uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes -APTR OldTrapHandler = NULL; // Old trap handler -APTR OldExceptionHandler = NULL; // Old exception handler -BYTE IRQSig = -1; // "Interrupt" signal number -ULONG IRQSigMask = 0; // "Interrupt" signal mask - -static struct timerequest *timereq = NULL; // IORequest for timer - -static struct MsgPort *ahi_port = NULL; // Port for AHI -static struct AHIRequest *ahi_io = NULL; // IORequest for AHI - -static struct Process *xpram_proc = NULL; // XPRAM watchdog -static volatile bool xpram_proc_active = true; // Flag for quitting the XPRAM watchdog - -static struct Process *tick_proc = NULL; // 60Hz process -static volatile bool tick_proc_active = true; // Flag for quitting the 60Hz process - -static bool stack_swapped = false; // Stack swapping -static StackSwapStruct stack_swap; - - -// Assembly functions -struct trap_regs; -extern "C" void AtomicAnd(uint32 *p, uint32 val); -extern "C" void AtomicOr(uint32 *p, uint32 val); -extern "C" void MoveVBR(void); -extern "C" void DisableSuperBypass(void); -extern "C" void TrapHandlerAsm(void); -extern "C" void ExceptionHandlerAsm(void); -extern "C" void IllInstrHandler(trap_regs *regs); -extern "C" void PrivViolHandler(trap_regs *regs); -extern "C" void quit_emulator(void); -extern "C" void AsmTriggerNMI(void); -uint16 EmulatedSR; // Emulated SR (supervisor bit and interrupt mask) - - -// Prototypes -static void jump_to_rom(void); -static void xpram_func(void); -static void tick_func(void); - - -/* - * Main program - */ - -int main(int argc, char **argv) -{ - // Initialize variables - RAMBaseHost = NULL; - ROMBaseHost = NULL; - MainTask = FindTask(NULL); - struct DateStamp ds; - DateStamp(&ds); - srand(ds.ds_Tick); - - // Print some info - printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - printf(" %s\n", GetString(STR_ABOUT_TEXT2)); - - // Open libraries - GfxBase = OpenLibrary((UBYTE *) "graphics.library", 39); - if (GfxBase == NULL) { - printf("Cannot open graphics.library V39.\n"); - exit(1); - } - IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *) "intuition.library", 39); - if (IntuitionBase == NULL) { - printf("Cannot open intuition.library V39.\n"); - CloseLibrary(GfxBase); - exit(1); - } - DiskBase = (struct Library *)OpenResource((UBYTE *) "disk.resource"); - if (DiskBase == NULL) - QuitEmulator(); - GadToolsBase = OpenLibrary((UBYTE *) "gadtools.library", 39); - if (GadToolsBase == NULL) { - ErrorAlert(STR_NO_GADTOOLS_LIB_ERR); - QuitEmulator(); - } - IFFParseBase = OpenLibrary((UBYTE *) "iffparse.library", 39); - if (IFFParseBase == NULL) { - ErrorAlert(STR_NO_IFFPARSE_LIB_ERR); - QuitEmulator(); - } - AslBase = OpenLibrary((UBYTE *) "asl.library", 36); - if (AslBase == NULL) { - ErrorAlert(STR_NO_ASL_LIB_ERR); - QuitEmulator(); - } - - if (FindTask((UBYTE *) "« Enforcer »")) { - ErrorAlert(STR_ENFORCER_RUNNING_ERR); - QuitEmulator(); - } - - // These two can fail (the respective gfx support won't be available, then) - P96Base = OpenLibrary((UBYTE *) "Picasso96API.library", 2); - CyberGfxBase = OpenLibrary((UBYTE *) "cybergraphics.library", 2); - - // Read preferences - PrefsInit(NULL, argc, argv); - - // Open AHI - ahi_port = CreateMsgPort(); - if (ahi_port) { - ahi_io = (struct AHIRequest *)CreateIORequest(ahi_port, sizeof(struct AHIRequest)); - if (ahi_io) { - ahi_io->ahir_Version = 2; - if (OpenDevice((UBYTE *) AHINAME, AHI_NO_UNIT, (struct IORequest *)ahi_io, 0) == 0) { - AHIBase = (struct Library *)ahi_io->ahir_Std.io_Device; - } - } - } - - // Init system routines - SysInit(); - - // Show preferences editor - if (!PrefsFindBool("nogui")) - if (!PrefsEditor()) - QuitEmulator(); - - // Check start of Chip memory (because we need access to 0x0000..0x2000) - if ((uint32)FindName(&SysBase->MemList, (UBYTE *) "chip memory") < 0x2000) { - ErrorAlert(STR_NO_PREPARE_EMUL_ERR); - QuitEmulator(); - } - - // Open timer.device - timereq = (struct timerequest *)AllocVec(sizeof(timerequest), MEMF_PUBLIC | MEMF_CLEAR); - if (timereq == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - if (OpenDevice((UBYTE *) TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timereq, 0)) { - ErrorAlert(STR_NO_TIMER_DEV_ERR); - QuitEmulator(); - } - TimerBase = (struct Library *)timereq->tr_node.io_Device; - - // Allocate scratch memory - ScratchMem = (uint8 *)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC); - if (ScratchMem == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - ScratchMem += SCRATCH_MEM_SIZE/2; // ScratchMem points to middle of block - - // Create area for Mac RAM and ROM (ROM must be higher in memory, - // so we allocate one big chunk and put the ROM at the top of it) - RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary - if (RAMSize < 1024*1024) { - WarningAlert(GetString(STR_SMALL_RAM_WARN)); - RAMSize = 1024*1024; - } - RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC); - if (RAMBaseHost == NULL) { - uint32 newRAMSize = AvailMem(MEMF_LARGEST) - 0x100000; - char xText[120]; - - sprintf(xText, GetString(STR_NOT_ENOUGH_MEM_WARN), RAMSize, newRAMSize); - - if (ChoiceAlert(xText, "Use", "Quit") != 1) - QuitEmulator(); - - RAMSize = newRAMSize; - RAMBaseHost = (uint8 *)AllocVec(RAMSize - 0x100000, MEMF_PUBLIC); - if (RAMBaseHost == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - } - RAMBaseMac = (uint32)RAMBaseHost; - D(bug("Mac RAM starts at %08lx\n", RAMBaseHost)); - ROMBaseHost = RAMBaseHost + RAMSize; - ROMBaseMac = (uint32)ROMBaseHost; - D(bug("Mac ROM starts at %08lx\n", ROMBaseHost)); - - // Get rom file path from preferences - const char *rom_path = PrefsFindString("rom"); - - // Load Mac ROM - BPTR rom_fh = Open(rom_path ? (char *)rom_path : (char *)ROM_FILE_NAME, MODE_OLDFILE); - if (rom_fh == 0) { - ErrorAlert(STR_NO_ROM_FILE_ERR); - QuitEmulator(); - } - printf(GetString(STR_READING_ROM_FILE)); - Seek(rom_fh, 0, OFFSET_END); - ROMSize = Seek(rom_fh, 0, OFFSET_CURRENT); - if (ROMSize != 512*1024 && ROMSize != 1024*1024) { - ErrorAlert(STR_ROM_SIZE_ERR); - Close(rom_fh); - QuitEmulator(); - } - Seek(rom_fh, 0, OFFSET_BEGINNING); - if (Read(rom_fh, ROMBaseHost, ROMSize) != ROMSize) { - ErrorAlert(STR_ROM_FILE_READ_ERR); - Close(rom_fh); - QuitEmulator(); - } - - // Set CPU and FPU type - UWORD attn = SysBase->AttnFlags; - CPUType = attn & AFF_68040 ? 4 : (attn & AFF_68030 ? 3 : 2); - CPUIs68060 = attn & AFF_68060; - FPUType = attn & AFF_68881 ? 1 : 0; - - // Initialize everything - if (!InitAll(NULL)) - QuitEmulator(); - - // Move VBR away from 0 if neccessary - MoveVBR(); - - // On 68060, disable Super Bypass mode because of a CPU bug that is triggered by MacOS 8 - if (CPUIs68060) - DisableSuperBypass(); - - memset((UBYTE *) 8, 0, 0x2000-8); - - // Install trap handler - EmulatedSR = 0x2700; - OldTrapHandler = MainTask->tc_TrapCode; - MainTask->tc_TrapCode = (APTR)TrapHandlerAsm; - - // Allocate signal for interrupt emulation and install exception handler - IRQSig = AllocSignal(-1); - IRQSigMask = 1 << IRQSig; - OldExceptionHandler = MainTask->tc_ExceptCode; - MainTask->tc_ExceptCode = (APTR)ExceptionHandlerAsm; - SetExcept(SIGBREAKF_CTRL_C | IRQSigMask, SIGBREAKF_CTRL_C | IRQSigMask); - - // Start XPRAM watchdog process - xpram_proc = CreateNewProcTags( - NP_Entry, (ULONG)xpram_func, - NP_Name, (ULONG)"Basilisk II XPRAM Watchdog", - NP_Priority, 0, - TAG_END - ); - - // Start 60Hz process - tick_proc = CreateNewProcTags( - NP_Entry, (ULONG)tick_func, - NP_Name, (ULONG)"Basilisk II 60Hz", - NP_Priority, 5, - TAG_END - ); - - // Set task priority to -1 so we don't use all processing time - SetTaskPri(MainTask, -1); - - WriteMacInt32(0xbff, 0); // MacsBugFlags - - // Swap stack to Mac RAM area - stack_swap.stk_Lower = RAMBaseHost; - stack_swap.stk_Upper = (ULONG)RAMBaseHost + RAMSize; - stack_swap.stk_Pointer = RAMBaseHost + 0x8000; - StackSwap(&stack_swap); - stack_swapped = true; - - // Jump to ROM boot routine - Start680x0(); - - QuitEmulator(); - return 0; -} - -void Start680x0(void) -{ - typedef void (*rom_func)(void); - rom_func fp = (rom_func)(ROMBaseHost + 0x2a); - fp(); -} - - -/* - * Quit emulator (__saveds because it might be called from an exception) - */ - -// Assembly entry point -void __saveds quit_emulator(void) -{ - QuitEmulator(); -} - -void QuitEmulator(void) -{ - // Stop 60Hz process - if (tick_proc) { - SetSignal(0, SIGF_SINGLE); - tick_proc_active = false; - Wait(SIGF_SINGLE); - } - - // Stop XPRAM watchdog process - if (xpram_proc) { - SetSignal(0, SIGF_SINGLE); - xpram_proc_active = false; - Wait(SIGF_SINGLE); - } - - // Restore stack - if (stack_swapped) { - stack_swapped = false; - StackSwap(&stack_swap); - } - - // Remove exception handler - if (IRQSig >= 0) { - SetExcept(0, SIGBREAKF_CTRL_C | IRQSigMask); - MainTask->tc_ExceptCode = OldExceptionHandler; - FreeSignal(IRQSig); - } - - // Remove trap handler - MainTask->tc_TrapCode = OldTrapHandler; - - // Deinitialize everything - ExitAll(); - - // Delete RAM/ROM area - if (RAMBaseHost) - FreeVec(RAMBaseHost); - - // Delete scratch memory area - if (ScratchMem) - FreeMem((void *)(ScratchMem - SCRATCH_MEM_SIZE/2), SCRATCH_MEM_SIZE); - - // Close timer.device - if (TimerBase) - CloseDevice((struct IORequest *)timereq); - if (timereq) - FreeVec(timereq); - - // Exit system routines - SysExit(); - - // Close AHI - if (AHIBase) - CloseDevice((struct IORequest *)ahi_io); - if (ahi_io) - DeleteIORequest((struct IORequest *)ahi_io); - if (ahi_port) - DeleteMsgPort(ahi_port); - - // Exit preferences - PrefsExit(); - - // Close libraries - if (CyberGfxBase) - CloseLibrary(CyberGfxBase); - if (P96Base) - CloseLibrary(P96Base); - if (AslBase) - CloseLibrary(AslBase); - if (IFFParseBase) - CloseLibrary(IFFParseBase); - if (GadToolsBase) - CloseLibrary(GadToolsBase); - if (IntuitionBase) - CloseLibrary((struct Library *)IntuitionBase); - if (GfxBase) - CloseLibrary(GfxBase); - - exit(0); -} - - -/* - * Code was patched, flush caches if neccessary (i.e. when using a real 680x0 - * or a dynamically recompiling emulator) - */ - -void FlushCodeCache(void *start, uint32 size) -{ - CacheClearE(start, size, CACRF_ClearI | CACRF_ClearD); -} - - -/* - * Mutexes - */ - -struct B2_mutex { - int dummy; //!! -}; - -B2_mutex *B2_create_mutex(void) -{ - return new B2_mutex; -} - -void B2_lock_mutex(B2_mutex *mutex) -{ -} - -void B2_unlock_mutex(B2_mutex *mutex) -{ -} - -void B2_delete_mutex(B2_mutex *mutex) -{ - delete mutex; -} - - -/* - * Interrupt flags (must be handled atomically!) - */ - -uint32 InterruptFlags; - -void SetInterruptFlag(uint32 flag) -{ - AtomicOr(&InterruptFlags, flag); -} - -void ClearInterruptFlag(uint32 flag) -{ - AtomicAnd(&InterruptFlags, ~flag); -} - -void TriggerInterrupt(void) -{ - Signal(MainTask, IRQSigMask); -} - -void TriggerNMI(void) -{ - AsmTriggerNMI(); -} - - -/* - * 60Hz thread (really 60.15Hz) - */ - -static __saveds void tick_func(void) -{ - int tick_counter = 0; - struct MsgPort *timer_port = NULL; - struct timerequest *timer_io = NULL; - ULONG timer_mask = 0; - - // Start 60Hz timer - timer_port = CreateMsgPort(); - if (timer_port) { - timer_io = (struct timerequest *)CreateIORequest(timer_port, sizeof(struct timerequest)); - if (timer_io) { - if (!OpenDevice((UBYTE *) TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timer_io, 0)) { - timer_mask = 1 << timer_port->mp_SigBit; - timer_io->tr_node.io_Command = TR_ADDREQUEST; - timer_io->tr_time.tv_secs = 0; - timer_io->tr_time.tv_micro = 16625; - SendIO((struct IORequest *)timer_io); - } - } - } - - while (tick_proc_active) { - - // Wait for timer tick - Wait(timer_mask); - - // Restart timer - timer_io->tr_node.io_Command = TR_ADDREQUEST; - timer_io->tr_time.tv_secs = 0; - timer_io->tr_time.tv_micro = 16625; - SendIO((struct IORequest *)timer_io); - - // Pseudo Mac 1Hz interrupt, update local time - if (++tick_counter > 60) { - tick_counter = 0; - WriteMacInt32(0x20c, TimerDateTime()); - SetInterruptFlag(INTFLAG_1HZ); - TriggerInterrupt(); - } - - // Trigger 60Hz interrupt - SetInterruptFlag(INTFLAG_60HZ); - TriggerInterrupt(); - } - - // Stop timer - if (timer_io) { - if (!CheckIO((struct IORequest *)timer_io)) - AbortIO((struct IORequest *)timer_io); - WaitIO((struct IORequest *)timer_io); - CloseDevice((struct IORequest *)timer_io); - DeleteIORequest(timer_io); - } - if (timer_port) - DeleteMsgPort(timer_port); - - // Main task asked for termination, send signal - Forbid(); - Signal(MainTask, SIGF_SINGLE); -} - - -/* - * XPRAM watchdog thread (saves XPRAM every minute) - */ - -static __saveds void xpram_func(void) -{ - uint8 last_xpram[XPRAM_SIZE]; - memcpy(last_xpram, XPRAM, XPRAM_SIZE); - - while (xpram_proc_active) { - for (int i=0; i<60 && xpram_proc_active; i++) - Delay(50); // Only wait 1 second so we quit promptly when xpram_proc_active becomes false - if (memcmp(last_xpram, XPRAM, XPRAM_SIZE)) { - memcpy(last_xpram, XPRAM, XPRAM_SIZE); - SaveXPRAM(); - } - } - - // Main task asked for termination, send signal - Forbid(); - Signal(MainTask, SIGF_SINGLE); -} - - -/* - * Display error alert - */ - -void ErrorAlert(const char *text) -{ - if (PrefsFindBool("nogui")) { - printf(GetString(STR_SHELL_ERROR_PREFIX), text); - return; - } - EasyStruct req; - req.es_StructSize = sizeof(EasyStruct); - req.es_Flags = 0; - req.es_Title = (UBYTE *)GetString(STR_ERROR_ALERT_TITLE); - req.es_TextFormat = (UBYTE *)GetString(STR_GUI_ERROR_PREFIX); - req.es_GadgetFormat = (UBYTE *)GetString(STR_QUIT_BUTTON); - EasyRequest(NULL, &req, NULL, (ULONG)text); -} - - -/* - * Display warning alert - */ - -void WarningAlert(const char *text) -{ - if (PrefsFindBool("nogui")) { - printf(GetString(STR_SHELL_WARNING_PREFIX), text); - return; - } - EasyStruct req; - req.es_StructSize = sizeof(EasyStruct); - req.es_Flags = 0; - req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE); - req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX); - req.es_GadgetFormat = (UBYTE *)GetString(STR_OK_BUTTON); - EasyRequest(NULL, &req, NULL, (ULONG)text); -} - - -/* - * Display choice alert - */ - -bool ChoiceAlert(const char *text, const char *pos, const char *neg) -{ - char str[256]; - sprintf(str, "%s|%s", pos, neg); - EasyStruct req; - req.es_StructSize = sizeof(EasyStruct); - req.es_Flags = 0; - req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE); - req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX); - req.es_GadgetFormat = (UBYTE *)str; - return EasyRequest(NULL, &req, NULL, (ULONG)text); -} - - -/* - * Illegal Instruction and Privilege Violation trap handlers - */ - -struct trap_regs { // This must match the layout of M68kRegisters - uint32 d[8]; - uint32 a[8]; - uint16 sr; - uint32 pc; -}; - -void __saveds IllInstrHandler(trap_regs *r) -{ -// D(bug("IllInstrHandler/%ld\n", __LINE__)); - - uint16 opcode = *(uint16 *)(r->pc); - if ((opcode & 0xff00) != 0x7100) { - printf("Illegal Instruction %04x at %08lx\n", *(uint16 *)(r->pc), r->pc); - printf("d0 %08lx d1 %08lx d2 %08lx d3 %08lx\n" - "d4 %08lx d5 %08lx d6 %08lx d7 %08lx\n" - "a0 %08lx a1 %08lx a2 %08lx a3 %08lx\n" - "a4 %08lx a5 %08lx a6 %08lx a7 %08lx\n" - "sr %04x\n", - r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7], - r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7], - r->sr); - QuitEmulator(); - } else { - // Disable interrupts - uint16 sr = EmulatedSR; - EmulatedSR |= 0x0700; - - // Call opcode routine - EmulOp(opcode, (M68kRegisters *)r); - r->pc += 2; - - // Restore interrupts - EmulatedSR = sr; - if ((EmulatedSR & 0x0700) == 0 && InterruptFlags) - Signal(MainTask, IRQSigMask); - } -} - -void __saveds PrivViolHandler(trap_regs *r) -{ - printf("Privileged instruction %04x %04x at %08lx\n", *(uint16 *)(r->pc), *(uint16 *)(r->pc + 2), r->pc); - printf("d0 %08lx d1 %08lx d2 %08lx d3 %08lx\n" - "d4 %08lx d5 %08lx d6 %08lx d7 %08lx\n" - "a0 %08lx a1 %08lx a2 %08lx a3 %08lx\n" - "a4 %08lx a5 %08lx a6 %08lx a7 %08lx\n" - "sr %04x\n", - r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7], - r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7], - r->sr); - QuitEmulator(); -} diff --git a/BasiliskII/src/AmigaOS/prefs_amiga.cpp b/BasiliskII/src/AmigaOS/prefs_amiga.cpp deleted file mode 100644 index 3d71c1de..00000000 --- a/BasiliskII/src/AmigaOS/prefs_amiga.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * prefs_amiga.cpp - Preferences handling, AmigaOS specifix stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include "sysdeps.h" -#include "prefs.h" - - -// Platform-specific preferences items -prefs_desc platform_prefs_items[] = { - {"sound", TYPE_STRING, false, "sound output mode description"}, - {"scsimemtype", TYPE_INT32, false, "SCSI buffer memory type"}, - {NULL, TYPE_END, false, NULL} // End of list -}; - - -// Prefs file name -const char PREFS_FILE_NAME[] = "ENV:BasiliskII_prefs"; -const char PREFS_FILE_NAME_ARC[] = "ENVARC:BasiliskII_prefs"; - - -/* - * Load preferences from settings file - */ - -void LoadPrefs(void) -{ - // Read preferences from settings file - FILE *f = fopen(PREFS_FILE_NAME, "r"); - if (f != NULL) { - - // Prefs file found, load settings - LoadPrefsFromStream(f); - fclose(f); - - } else { - - // No prefs file, save defaults - SavePrefs(); - } -} - - -/* - * Save preferences to settings file - */ - -void SavePrefs(void) -{ - FILE *f; - if ((f = fopen(PREFS_FILE_NAME, "w")) != NULL) { - SavePrefsToStream(f); - fclose(f); - } - if ((f = fopen(PREFS_FILE_NAME_ARC, "w")) != NULL) { - SavePrefsToStream(f); - fclose(f); - } -} - - -/* - * Add defaults of platform-specific prefs items - * You may also override the defaults set in PrefsInit() - */ - -void AddPlatformPrefsDefaults(void) -{ - PrefsReplaceString("extfs", "WORK:"); - PrefsAddInt32("scsimemtype", 0); -} diff --git a/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp b/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp deleted file mode 100644 index f1956906..00000000 --- a/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp +++ /dev/null @@ -1,1735 +0,0 @@ -/* - * prefs_editor_amiga.cpp - Preferences editor, AmigaOS implementation (using gtlayout.library) - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "main.h" -#include "xpram.h" -#include "cdrom.h" -#include "user_strings.h" -#include "version.h" -#include "prefs.h" -#include "prefs_editor.h" - - -// Gadget/menu IDs -const int MSG_OK = 0x0100; // "Start" button -const int MSG_CANCEL = 0x0101; // "Quit" button -const int MSG_ABOUT = 0x0102; // "About..." menu item -const int MSG_ZAP_PRAM = 0x0103; // "Zap PRAM" menu item - -const int GAD_PAGEGROUP = 0x0200; - -const int GAD_DISK_LIST = 0x0300; // "Volumes" pane -const int GAD_ADD_VOLUME = 0x0301; -const int GAD_EDIT_VOLUME = 0x0302; -const int GAD_REMOVE_VOLUME = 0x0303; -const int GAD_CDROM_DEVICE = 0x0304; -const int GAD_CDROM_UNIT = 0x0305; -const int GAD_BOOTDRIVER = 0x0306; -const int GAD_NOCDROM = 0x0307; -const int GAD_EXTFS = 0x0308; - -const int GAD_VOLUME_READONLY = 0x0310; // "Add/Edit Volume" window -const int GAD_VOLUME_TYPE = 0x0311; -const int GAD_VOLUME_FILE = 0x0312; -const int GAD_VOLUME_DEVICE = 0x0313; -const int GAD_VOLUME_UNIT = 0x0314; -const int GAD_VOLUME_OPENFLAGS = 0x0315; -const int GAD_VOLUME_STARTBLOCK = 0x0316; -const int GAD_VOLUME_SIZE = 0x0317; -const int GAD_VOLUME_BLOCKSIZE = 0x0318; -const int GAD_VOLUME_PAGEGROUP = 0x0319; - -const int GAD_SCSI0_DEVICE = 0x0400; // "SCSI" pane -const int GAD_SCSI1_DEVICE = 0x0401; -const int GAD_SCSI2_DEVICE = 0x0402; -const int GAD_SCSI3_DEVICE = 0x0403; -const int GAD_SCSI4_DEVICE = 0x0404; -const int GAD_SCSI5_DEVICE = 0x0405; -const int GAD_SCSI6_DEVICE = 0x0406; -const int GAD_SCSI0_UNIT = 0x0410; -const int GAD_SCSI1_UNIT = 0x0411; -const int GAD_SCSI2_UNIT = 0x0412; -const int GAD_SCSI3_UNIT = 0x0413; -const int GAD_SCSI4_UNIT = 0x0414; -const int GAD_SCSI5_UNIT = 0x0415; -const int GAD_SCSI6_UNIT = 0x0416; -const int GAD_SCSI_MEMTYPE = 0x0420; - -const int GAD_VIDEO_TYPE = 0x0500; // "Graphics/Sound" pane -const int GAD_DISPLAY_X = 0x0501; -const int GAD_DISPLAY_Y = 0x0502; -const int GAD_FRAMESKIP = 0x0503; -const int GAD_SCREEN_MODE = 0x0504; -const int GAD_AHI_MODE = 0x0505; -const int GAD_NOSOUND = 0x0506; - -const int GAD_SERIALA_DEVICE = 0x0600; // "Serial/Network" pane -const int GAD_SERIALA_UNIT = 0x0601; -const int GAD_SERIALA_ISPAR = 0x0602; -const int GAD_SERIALB_DEVICE = 0x0603; -const int GAD_SERIALB_UNIT = 0x0604; -const int GAD_SERIALB_ISPAR = 0x0605; -const int GAD_ETHER_DEVICE = 0x0606; -const int GAD_ETHER_UNIT = 0x00607; - -const int GAD_RAMSIZE = 0x0700; // "Memory/Misc" pane -const int GAD_MODELID = 0x0701; -const int GAD_ROM_FILE = 0x0702; - - -// Global variables -struct Library *GTLayoutBase = NULL; -static struct FileRequester *dev_request = NULL, *file_request = NULL; - -// gtlayout.library macros -#define VGROUP LT_New(h, LA_Type, VERTICAL_KIND, TAG_END) -#define HGROUP LT_New(h, LA_Type, HORIZONTAL_KIND, TAG_END) -#define ENDGROUP LT_EndGroup(h) - -// Prototypes -static void create_volumes_pane(struct LayoutHandle *h); -static void create_scsi_pane(struct LayoutHandle *h); -static void create_graphics_pane(struct LayoutHandle *h); -static void create_serial_pane(struct LayoutHandle *h); -static void create_memory_pane(struct LayoutHandle *h); -static void add_edit_volume(struct LayoutHandle *h, bool adding); -static void remove_volume(struct LayoutHandle *h); -static void ghost_volumes_gadgets(struct LayoutHandle *h); -static void ghost_graphics_gadgets(struct LayoutHandle *h); -static void screen_mode_req(struct Window *win, struct LayoutHandle *h); -static void ahi_mode_req(struct Window *win, struct LayoutHandle *h); -static void read_settings(struct LayoutHandle *h); - - -/* - * Locale hook - returns string for given ID - */ - -static __saveds __attribute__((regparm(3))) const char *locale_hook_func(struct Hook *hook /*a0*/, void *id /*a1*/, struct LayoutHandle *h /*a2*/) -{ - return GetString((uint32)id); -} - -struct Hook locale_hook = {{NULL, NULL}, (HOOKFUNC)locale_hook_func, NULL, NULL}; - - -/* - * Show preferences editor - * Returns true when user clicked on "Start", false otherwise - */ - -bool PrefsEditor(void) -{ - bool retval = true, done = false; - struct LayoutHandle *h = NULL; - struct Window *win = NULL; - struct Menu *menu = NULL; - - // Pane tabs - static const LONG labels[] = { - STR_VOLUMES_PANE_TITLE, - STR_SCSI_PANE_TITLE, - STR_GRAPHICS_SOUND_PANE_TITLE, - STR_SERIAL_NETWORK_PANE_TITLE, - STR_MEMORY_MISC_PANE_TITLE, - -1 - }; - - // Open gtlayout.library - GTLayoutBase = (struct Library *)OpenLibrary("gtlayout.library", 39); - if (GTLayoutBase == NULL) { - WarningAlert(GetString(STR_NO_GTLAYOUT_LIB_WARN)); - return true; - } - - // Create layout handle - h = LT_CreateHandleTags(NULL, - LAHN_AutoActivate, FALSE, - LAHN_LocaleHook, (ULONG)&locale_hook, - TAG_END - ); - if (h == NULL) - goto quit; - - // Create menus - menu = LT_NewMenuTags( - LAMN_LayoutHandle, (ULONG)h, - LAMN_TitleID, STR_PREFS_MENU, - LAMN_ItemID, STR_PREFS_ITEM_ABOUT, - LAMN_UserData, MSG_ABOUT, - LAMN_ItemText, (ULONG)NM_BARLABEL, - LAMN_ItemID, STR_PREFS_ITEM_START, - LAMN_UserData, MSG_OK, - LAMN_ItemID, STR_PREFS_ITEM_ZAP_PRAM, - LAMN_UserData, MSG_ZAP_PRAM, - LAMN_ItemText, (ULONG)NM_BARLABEL, - LAMN_ItemID, STR_PREFS_ITEM_QUIT, - LAMN_UserData, MSG_CANCEL, - LAMN_KeyText, (ULONG)"Q", - TAG_END - ); - - // Create window contents - VGROUP; - VGROUP; - LT_New(h, LA_Type, TAB_KIND, - LATB_LabelTable, (ULONG)labels, - LATB_AutoPageID, GAD_PAGEGROUP, - LATB_FullWidth, TRUE, - TAG_END - ); - ENDGROUP; - - // Panes - LT_New(h, LA_Type, VERTICAL_KIND, - LA_ID, GAD_PAGEGROUP, - LAGR_ActivePage, 0, - TAG_END - ); - create_volumes_pane(h); - create_scsi_pane(h); - create_graphics_pane(h); - create_serial_pane(h); - create_memory_pane(h); - ENDGROUP; - - // Separator between tabs and buttons - VGROUP; - LT_New(h, LA_Type, XBAR_KIND, - LAXB_FullSize, TRUE, - TAG_END - ); - ENDGROUP; - - // "Start" and "Quit" buttons - LT_New(h, LA_Type, HORIZONTAL_KIND, - LAGR_SameSize, TRUE, - LAGR_Spread, TRUE, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_START_BUTTON, - LA_ID, MSG_OK, - LABT_ReturnKey, TRUE, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_QUIT_BUTTON, - LA_ID, MSG_CANCEL, - LABT_EscKey, TRUE, - TAG_END - ); - ENDGROUP; - ENDGROUP; - - // Open window - win = LT_Build(h, - LAWN_TitleID, STR_PREFS_TITLE, - LAWN_Menu, (ULONG)menu, - LAWN_IDCMP, IDCMP_CLOSEWINDOW, - LAWN_BelowMouse, TRUE, - LAWN_SmartZoom, TRUE, - WA_SimpleRefresh, TRUE, - WA_Activate, TRUE, - WA_CloseGadget, TRUE, - WA_DepthGadget, TRUE, - WA_DragBar, TRUE, - TAG_END - ); - if (win == NULL) - goto quit; - - // Create file requesters - dev_request = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest, - ASLFR_DoPatterns, TRUE, - ASLFR_RejectIcons, TRUE, - ASLFR_InitialDrawer, (ULONG)"DEVS:", - ASLFR_InitialPattern, (ULONG)"#?.device", - TAG_END - ); - file_request = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest, - ASLFR_DoPatterns, TRUE, - ASLFR_RejectIcons, TRUE, - ASLFR_InitialPattern, (ULONG)"#?", - TAG_END - ); - - // Event loop - do { - struct IntuiMessage *msg; - - // Wait for message - WaitPort(win->UserPort); - - // Get pending messages - while (msg = LT_GetIMsg(h)) { - - // Get data from message and reply - ULONG cl = msg->Class; - UWORD code = msg->Code; - struct Gadget *gad = (struct Gadget *)msg->IAddress; - LT_ReplyIMsg(msg); - - // Handle message according to class - switch (cl) { - case IDCMP_CLOSEWINDOW: - retval = false; - done = true; - break; - - case IDCMP_GADGETUP: - switch (gad->GadgetID) { - case MSG_OK: - read_settings(h); - SavePrefs(); - retval = true; - done = true; - break; - - case MSG_CANCEL: - retval = false; - done = true; - break; - - case GAD_DISK_LIST: - ghost_volumes_gadgets(h); - break; - - case GAD_ADD_VOLUME: - LT_LockWindow(win); - add_edit_volume(h, true); - LT_UnlockWindow(win); - break; - - case GAD_EDIT_VOLUME: - LT_LockWindow(win); - add_edit_volume(h, false); - LT_UnlockWindow(win); - break; - - case GAD_REMOVE_VOLUME: - remove_volume(h); - break; - - case GAD_BOOTDRIVER: - switch (code) { - case 0: - PrefsReplaceInt32("bootdriver", 0); - break; - case 1: - PrefsReplaceInt32("bootdriver", CDROMRefNum); - break; - } - break; - - case GAD_SCSI_MEMTYPE: - PrefsReplaceInt32("scsimemtype", code); - break; - - case GAD_VIDEO_TYPE: - ghost_graphics_gadgets(h); - break; - - case GAD_FRAMESKIP: - switch (code) { - case 0: - PrefsReplaceInt32("frameskip", 12); - break; - case 1: - PrefsReplaceInt32("frameskip", 8); - break; - case 2: - PrefsReplaceInt32("frameskip", 6); - break; - case 3: - PrefsReplaceInt32("frameskip", 4); - break; - case 4: - PrefsReplaceInt32("frameskip", 2); - break; - case 5: - PrefsReplaceInt32("frameskip", 1); - break; - } - break; - - case GAD_MODELID: - switch (code) { - case 0: - PrefsReplaceInt32("modelid", 5); - break; - case 1: - PrefsReplaceInt32("modelid", 14); - break; - } - break; - } - break; - - case IDCMP_IDCMPUPDATE: - switch (gad->GadgetID) { - case GAD_DISK_LIST: // Double-click on volumes list = edit volume - LT_LockWindow(win); - add_edit_volume(h, false); - LT_UnlockWindow(win); - break; - - case GAD_SCREEN_MODE: - screen_mode_req(win, h); - break; - - case GAD_AHI_MODE: - ahi_mode_req(win, h); - break; - - case GAD_CDROM_DEVICE: - case GAD_SCSI0_DEVICE: - case GAD_SCSI1_DEVICE: - case GAD_SCSI2_DEVICE: - case GAD_SCSI3_DEVICE: - case GAD_SCSI4_DEVICE: - case GAD_SCSI5_DEVICE: - case GAD_SCSI6_DEVICE: - case GAD_SERIALA_DEVICE: - case GAD_SERIALB_DEVICE: - if (dev_request) { - LT_LockWindow(win); - BOOL result = AslRequestTags(dev_request, - ASLFR_Window, (ULONG)win, - ASLFR_InitialDrawer, (ULONG) "Devs:", - TAG_END); - LT_UnlockWindow(win); - if (result) { - char *str; - GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); - strncpy(str, dev_request->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that. - str[255] = 0; - LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); - } - } - break; - - case GAD_ETHER_DEVICE: - if (dev_request) { - LT_LockWindow(win); - BOOL result = AslRequestTags(dev_request, - ASLFR_Window, (ULONG)win, - ASLFR_InitialDrawer, (ULONG) "Devs:Networks", - TAG_END); - LT_UnlockWindow(win); - if (result) { - char *str; - GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); - strncpy(str, dev_request->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that. - str[255] = 0; - LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); - } - } - break; - - case GAD_ROM_FILE: - if (file_request) { - LT_LockWindow(win); - BOOL result = AslRequestTags(file_request, ASLFR_Window, (ULONG)win, TAG_END); - LT_UnlockWindow(win); - if (result) { - char *str; - GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); - strncpy(str, file_request->rf_Dir, 255); - str[255] = 0; - AddPart(str, file_request->rf_File, 255); - LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); - } - } - break; - } - break; - - case IDCMP_MENUPICK: - while (code != MENUNULL) { - struct MenuItem *item = ItemAddress(menu, code); - if (item == NULL) - break; - switch ((ULONG)GTMENUITEM_USERDATA(item)) { - case MSG_OK: - read_settings(h); - SavePrefs(); - retval = true; - done = true; - break; - - case MSG_CANCEL: - retval = false; - done = true; - break; - - case MSG_ABOUT: { - char str[256]; - sprintf(str, GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - strncat(str, "\n", 255); - strncat(str, GetString(STR_ABOUT_TEXT2), 255); - - EasyStruct req; - req.es_StructSize = sizeof(EasyStruct); - req.es_Flags = 0; - req.es_Title = (UBYTE *)GetString(STR_ABOUT_TITLE); - req.es_TextFormat = (UBYTE *)str; - req.es_GadgetFormat = (UBYTE *)GetString(STR_OK_BUTTON); - LT_LockWindow(win); - EasyRequest(win, &req, NULL); - LT_UnlockWindow(win); - break; - } - - case MSG_ZAP_PRAM: - ZapPRAM(); - break; - } - code = item->NextSelect; - } - break; - } - } - } while (!done); - -quit: - // Free requesters - FreeAslRequest(dev_request); - FreeAslRequest(file_request); - - // Delete Menus - LT_DisposeMenu(menu); - - // Delete handle - LT_DeleteHandle(h); - - // Close gtlayout.library - CloseLibrary(GTLayoutBase); - return retval; -} - - -/* - * "Volumes" pane - */ - -static struct List disk_list; -static char cdrom_name[256], extfs_name[256]; -static ULONG cdrom_unit, cdrom_flags, cdrom_start, cdrom_size, cdrom_bsize; -static BYTE bootdriver_num, nocdrom; - -// Read volumes preferences -static void parse_volumes_prefs(void) -{ - NewList(&disk_list); - const char *str; - for (int i=0; (str = PrefsFindString("disk", i)) != NULL; i++) { - struct Node *item = (struct Node *)AllocMem(sizeof(struct Node), MEMF_CLEAR); - item->ln_Name = (char *)str; - AddTail(&disk_list, item); - } - - cdrom_name[0] = 0; - cdrom_unit = 0; cdrom_flags = 0; cdrom_start = 0; cdrom_size = 0; cdrom_bsize = 2048; - - str = PrefsFindString("cdrom"); - if (str) - sscanf(str, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", cdrom_name, &cdrom_unit, &cdrom_flags, &cdrom_start, &cdrom_size, &cdrom_bsize); - - bootdriver_num = 0; - - int bootdriver = PrefsFindInt32("bootdriver"); - switch (bootdriver) { - case 0: - bootdriver_num = 0; - break; - case CDROMRefNum: - bootdriver_num = 1; - break; - } - - nocdrom = PrefsFindBool("nocdrom"); - - extfs_name[0] = 0; - str = PrefsFindString("extfs"); - if (str) - strncpy(extfs_name, str, sizeof(extfs_name) - 1); -} - -// Ghost/unghost "Edit" and "Remove" buttons -static void ghost_volumes_gadgets(struct LayoutHandle *h) -{ - UWORD sel = LT_GetAttributes(h, GAD_DISK_LIST, TAG_END); - if (sel == 0xffff) { - LT_SetAttributes(h, GAD_EDIT_VOLUME, GA_Disabled, TRUE, TAG_END); - LT_SetAttributes(h, GAD_REMOVE_VOLUME, GA_Disabled, TRUE, TAG_END); - } else { - LT_SetAttributes(h, GAD_EDIT_VOLUME, GA_Disabled, FALSE, TAG_END); - LT_SetAttributes(h, GAD_REMOVE_VOLUME, GA_Disabled, FALSE, TAG_END); - } -} - -// Get device data from partition name -static void analyze_partition(const char *part, char *dev_name, ULONG &dev_unit, ULONG &dev_flags, ULONG &dev_start, ULONG &dev_size, ULONG &dev_bsize) -{ - // Remove everything after and including the ':' - char str[256]; - strncpy(str, part, sizeof(str) - 1); - str[sizeof(str) - 1] = 0; - char *colon = strchr(str, ':'); - if (colon) - *colon = 0; - - // Look for partition - struct DosList *dl = LockDosList(LDF_DEVICES | LDF_READ); - dl = FindDosEntry(dl, str, LDF_DEVICES); - if (dl) { - // Get File System Startup Message - struct FileSysStartupMsg *fssm = (struct FileSysStartupMsg *)(dl->dol_misc.dol_handler.dol_Startup << 2); - if (fssm) { - // Get DOS environment vector - struct DosEnvec *de = (struct DosEnvec *)(fssm->fssm_Environ << 2); - if (de && de->de_TableSize >= DE_UPPERCYL) { - // Read settings from FSSM and Envec - strncpy(dev_name, (char *)(fssm->fssm_Device << 2) + 1, 255); - dev_name[255] = 0; - dev_unit = fssm->fssm_Unit; - dev_flags = fssm->fssm_Flags; - dev_start = de->de_BlocksPerTrack * de->de_Surfaces * de->de_LowCyl; - dev_size = de->de_BlocksPerTrack * de->de_Surfaces * (de->de_HighCyl - de->de_LowCyl + 1); - dev_bsize = de->de_SizeBlock << 2; - } - } - } - UnLockDosList(LDF_DEVICES | LDF_READ); -} - -// Display and handle "Add/Edit Volume" window -static void add_edit_volume(struct LayoutHandle *h2, bool adding) -{ - bool ok_clicked = false; - - UWORD sel = LT_GetAttributes(h2, GAD_DISK_LIST, TAG_END); - if ((sel == 0xffff) && !adding) - return; - - char dev_name[256] = ""; - char file_name[256] = ""; - ULONG dev_unit = 0, dev_flags = 0, dev_start = 0, dev_size = 0, dev_bsize = 512; - BYTE read_only = false, is_device = false; - - if (!adding) { - const char *str = PrefsFindString("disk", sel); - if (str == NULL) - return; - if (str[0] == '*') { - read_only = true; - str++; - } - if (strstr(str, "/dev/") == str) { - is_device = true; - sscanf(str, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", dev_name, &dev_unit, &dev_flags, &dev_start, &dev_size, &dev_bsize); - } else { - strncpy(file_name, str, sizeof(file_name) - 1); - file_name[sizeof(file_name) - 1] = 0; - } - } - - // Create layout handle - struct LayoutHandle *h = NULL; - struct Window *win = NULL; - h = LT_CreateHandleTags(NULL, - LAHN_AutoActivate, FALSE, - LAHN_LocaleHook, (ULONG)&locale_hook, - TAG_END - ); - if (h == NULL) - return; - - // Create window contents - VGROUP; - // Volume gadgets - VGROUP; - LT_New(h, LA_Type, CHECKBOX_KIND, - LA_LabelID, STR_VOL_READONLY_CTRL, - LA_ID, GAD_VOLUME_READONLY, - LA_BYTE, (ULONG)&read_only, - TAG_END - ); - LT_New(h, LA_Type, CYCLE_KIND, - LA_LabelID, STR_VOL_TYPE_CTRL, - LA_ID, GAD_VOLUME_TYPE, - LACY_AutoPageID, GAD_VOLUME_PAGEGROUP, - LACY_FirstLabel, STR_VOL_FILE_LAB, - LACY_LastLabel, STR_VOL_DEVICE_LAB, - LA_BYTE, (ULONG)&is_device, - TAG_END - ); - ENDGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_ID, GAD_VOLUME_PAGEGROUP, - LAGR_ActivePage, is_device, - TAG_END - ); - VGROUP; - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_VOL_FILE_CTRL, - LA_ID, GAD_VOLUME_FILE, - LA_Chars, 20, - LA_STRPTR, (ULONG)file_name, - GTST_MaxChars, sizeof(file_name) - 1, - LAST_Picker, TRUE, - TAG_END - ); - ENDGROUP; - VGROUP; - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_VOLUME_DEVICE, - LA_Chars, 20, - LA_STRPTR, (ULONG)dev_name, - GTST_MaxChars, sizeof(dev_name) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_VOLUME_UNIT, - LA_LONG, (ULONG)&dev_unit, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_VOL_OPENFLAGS_CTRL, - LA_ID, GAD_VOLUME_OPENFLAGS, - LA_LONG, (ULONG)&dev_flags, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_VOL_STARTBLOCK_CTRL, - LA_ID, GAD_VOLUME_STARTBLOCK, - LA_LONG, (ULONG)&dev_start, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_VOL_SIZE_CTRL, - LA_ID, GAD_VOLUME_SIZE, - LA_LONG, (ULONG)&dev_size, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_VOL_BLOCKSIZE_CTRL, - LA_ID, GAD_VOLUME_BLOCKSIZE, - LA_LONG, (ULONG)&dev_bsize, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - ENDGROUP; - ENDGROUP; - - // Separator between gadgets and buttons - VGROUP; - LT_New(h, LA_Type, XBAR_KIND, - LAXB_FullSize, TRUE, - TAG_END - ); - ENDGROUP; - - // "OK" and "Cancel" buttons - LT_New(h, LA_Type, HORIZONTAL_KIND, - LAGR_SameSize, TRUE, - LAGR_Spread, TRUE, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_OK_BUTTON, - LA_ID, MSG_OK, - LABT_ReturnKey, TRUE, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_CANCEL_BUTTON, - LA_ID, MSG_CANCEL, - LABT_EscKey, TRUE, - TAG_END - ); - ENDGROUP; - ENDGROUP; - - // Open window - win = LT_Build(h, - LAWN_TitleID, adding ? STR_ADD_VOLUME_TITLE : STR_EDIT_VOLUME_TITLE, - LAWN_IDCMP, IDCMP_CLOSEWINDOW, - LAWN_BelowMouse, TRUE, - LAWN_SmartZoom, TRUE, - WA_SimpleRefresh, TRUE, - WA_Activate, TRUE, - WA_CloseGadget, TRUE, - WA_DepthGadget, TRUE, - WA_DragBar, TRUE, - TAG_END - ); - if (win == NULL) { - LT_DeleteHandle(h); - return; - } - - // Event loop - bool done = false; - do { - struct IntuiMessage *msg; - - // Wait for message - WaitPort(win->UserPort); - - // Get pending messages - while (msg = LT_GetIMsg(h)) { - - // Get data from message and reply - ULONG cl = msg->Class; - UWORD code = msg->Code; - struct Gadget *gad = (struct Gadget *)msg->IAddress; - LT_ReplyIMsg(msg); - - // Handle message according to class - switch (cl) { - case IDCMP_CLOSEWINDOW: - done = true; - break; - - case IDCMP_GADGETUP: - switch (gad->GadgetID) { - case MSG_OK: - ok_clicked = true; - done = true; - break; - case MSG_CANCEL: - done = true; - break; - } - break; - - case IDCMP_IDCMPUPDATE: { - struct FileRequester *req = NULL; - switch (gad->GadgetID) { - case GAD_VOLUME_FILE: - req = file_request; - goto do_req; - case GAD_VOLUME_DEVICE: - req = dev_request; -do_req: if (req) { - LT_LockWindow(win); - BOOL result = AslRequestTags(req, ASLFR_Window, (ULONG)win, TAG_END); - LT_UnlockWindow(win); - if (result) { - char *str; - GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); - if (gad->GadgetID == GAD_VOLUME_FILE) { - strncpy(str, req->rf_Dir, 255); - str[255] = 0; - AddPart(str, req->rf_File, 255); - } else { - if (strlen(req->rf_File)) { - strncpy(str, req->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that. - str[255] = 0; - } else if (strlen(req->rf_Dir) && req->rf_Dir[strlen(req->rf_Dir) - 1] == ':') { - analyze_partition(req->rf_Dir, str, dev_unit, dev_flags, dev_start, dev_size, dev_bsize); - LT_SetAttributes(h, GAD_VOLUME_UNIT, GTIN_Number, dev_unit, TAG_END); - LT_SetAttributes(h, GAD_VOLUME_OPENFLAGS, GTIN_Number, dev_flags, TAG_END); - LT_SetAttributes(h, GAD_VOLUME_STARTBLOCK, GTIN_Number, dev_start, TAG_END); - LT_SetAttributes(h, GAD_VOLUME_SIZE, GTIN_Number, dev_size, TAG_END); - LT_SetAttributes(h, GAD_VOLUME_BLOCKSIZE, GTIN_Number, dev_bsize, TAG_END); - } - } - LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); - } - } - break; - } - break; - } - } - } - } while (!done); - - // Update preferences and list view - if (ok_clicked) { - char str[256]; - LT_UpdateStrings(h); - - if (is_device) - sprintf(str, "%s/dev/%s/%ld/%ld/%ld/%ld/%ld", read_only ? "*" : "", dev_name, dev_unit, dev_flags, dev_start, dev_size, dev_bsize); - else - sprintf(str, "%s%s", read_only ? "*" : "", file_name); - LT_SetAttributes(h2, GAD_DISK_LIST, GTLV_Labels, ~0, TAG_END); - - if (adding) { - - // Add new item - int i; - PrefsAddString("disk", str); - struct Node *item = (struct Node *)AllocMem(sizeof(struct Node), MEMF_CLEAR); - for (i=0; PrefsFindString("disk", i); i++) ; - item->ln_Name = (char *)PrefsFindString("disk", i - 1); - AddTail(&disk_list, item); - - } else { - - // Replace existing item - PrefsReplaceString("disk", str, sel); - struct Node *item = disk_list.lh_Head; - for (int i=0; item->ln_Succ; i++) { - if (i == sel) { - item->ln_Name = (char *)PrefsFindString("disk", sel); - break; - } - item = item->ln_Succ; - } - } - LT_SetAttributes(h2, GAD_DISK_LIST, GTLV_Labels, (ULONG)&disk_list, TAG_END); - ghost_volumes_gadgets(h2); - } - - // Delete handle - LT_DeleteHandle(h); -} - -// Remove volume from list -static void remove_volume(struct LayoutHandle *h) -{ - UWORD sel = LT_GetAttributes(h, GAD_DISK_LIST, TAG_END); - if (sel != 0xffff) { - - // Remove item from preferences and list view - LT_SetAttributes(h, GAD_DISK_LIST, GTLV_Labels, ~0, TAG_END); - PrefsRemoveItem("disk", sel); - struct Node *item = disk_list.lh_Head; - for (int i=0; item->ln_Succ; i++) { - struct Node *next = item->ln_Succ; - if (i == sel) { - Remove(item); - FreeMem(item, sizeof(struct Node)); - break; - } - item = next; - } - LT_SetAttributes(h, GAD_DISK_LIST, GTLV_Labels, (ULONG)&disk_list, GTLV_Selected, 0xffff, TAG_END); - ghost_volumes_gadgets(h); - } -} - -// Read settings from gadgets and set preferences -static void read_volumes_settings(void) -{ - struct Node *item = disk_list.lh_Head; - while (item->ln_Succ) { - struct Node *next = item->ln_Succ; - Remove(item); - FreeMem(item, sizeof(struct Node)); - item = next; - } - - if (strlen(cdrom_name)) { - char str[256]; - sprintf(str, "/dev/%s/%ld/%ld/%ld/%ld/%ld", cdrom_name, cdrom_unit, cdrom_flags, cdrom_start, cdrom_size, cdrom_bsize); - PrefsReplaceString("cdrom", str); - } else - PrefsRemoveItem("cdrom"); - - PrefsReplaceBool("nocdrom", nocdrom); - - if (strlen(extfs_name)) - PrefsReplaceString("extfs", extfs_name); -} - -// Create "Volumes" pane -static void create_volumes_pane(struct LayoutHandle *h) -{ - parse_volumes_prefs(); - - VGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_VOLUMES_CTRL, - TAG_END - ); - VGROUP; - LT_New(h, LA_Type, LISTVIEW_KIND, - LA_ID, GAD_DISK_LIST, - LA_Chars, 20, - GTLV_Labels, (ULONG)&disk_list, - LALV_Lines, 6, - LALV_Link, (ULONG)NIL_LINK, - LALV_ResizeX, TRUE, - LALV_ResizeY, TRUE, - LALV_Selected, 0, - TAG_END - ); - ENDGROUP; - LT_New(h, LA_Type, HORIZONTAL_KIND, - LAGR_SameSize, TRUE, - LAGR_Spread, TRUE, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_ADD_VOLUME_BUTTON, - LA_ID, GAD_ADD_VOLUME, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_EDIT_VOLUME_BUTTON, - LA_ID, GAD_EDIT_VOLUME, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_REMOVE_VOLUME_BUTTON, - LA_ID, GAD_REMOVE_VOLUME, - TAG_END - ); - ENDGROUP; - ENDGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_CDROM_DRIVE_CTRL, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_CDROM_DEVICE, - LA_Chars, 20, - LA_STRPTR, (ULONG)cdrom_name, - GTST_MaxChars, sizeof(cdrom_name) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_CDROM_UNIT, - LA_LONG, (ULONG)&cdrom_unit, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, CYCLE_KIND, - LA_LabelID, STR_BOOTDRIVER_CTRL, - LA_ID, GAD_BOOTDRIVER, - LACY_FirstLabel, STR_BOOT_ANY_LAB, - LACY_LastLabel, STR_BOOT_CDROM_LAB, - LA_BYTE, (ULONG)&bootdriver_num, - TAG_END - ); - LT_New(h, LA_Type, CHECKBOX_KIND, - LA_LabelID, STR_NOCDROM_CTRL, - LA_ID, GAD_NOCDROM, - LA_BYTE, (ULONG)&nocdrom, - TAG_END - ); - ENDGROUP; - VGROUP; - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_EXTFS_CTRL, - LA_ID, GAD_EXTFS, - LA_Chars, 20, - LA_STRPTR, (ULONG)extfs_name, - GTST_MaxChars, sizeof(extfs_name) - 1, - TAG_END - ); - ENDGROUP; - ENDGROUP; -} - - -/* - * "SCSI" pane - */ - -static char scsi_dev[6][256]; -static LONG scsi_unit[6]; -static LONG scsi_memtype; - -// Read SCSI preferences -static void parse_scsi_prefs(void) -{ - for (int i=0; i<7; i++) { - scsi_dev[i][0] = 0; - scsi_unit[i] = 0; - - char prefs_name[16]; - sprintf(prefs_name, "scsi%d", i); - const char *str = PrefsFindString(prefs_name); - if (str) - sscanf(str, "%[^/]/%ld", scsi_dev[i], &scsi_unit[i]); - } - - scsi_memtype = PrefsFindInt32("scsimemtype"); -} - -// Read settings from gadgets and set preferences -static void read_scsi_settings(void) -{ - for (int i=0; i<7; i++) { - char prefs_name[16]; - sprintf(prefs_name, "scsi%d", i); - - if (strlen(scsi_dev[i])) { - char str[256]; - sprintf(str, "%s/%ld", scsi_dev[i], scsi_unit[i]); - PrefsReplaceString(prefs_name, str); - } else - PrefsRemoveItem(prefs_name); - } -} - -// Create "SCSI" pane -static void create_scsi_pane(struct LayoutHandle *h) -{ - parse_scsi_prefs(); - - VGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_SCSI_DEVICES_CTRL, - TAG_END - ); - for (int i=0; i<7; i++) { - HGROUP; - LT_New(h, LA_Type, TEXT_KIND, - LA_LabelID, STR_SCSI_ID_0 + i, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_SCSI0_DEVICE + i, - LA_Chars, 20, - LA_STRPTR, (ULONG)scsi_dev[i], - GTST_MaxChars, sizeof(scsi_dev[i]) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_SCSI0_UNIT + i, - LA_Chars, 4, - LA_LONG, (ULONG)&scsi_unit[i], - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - ENDGROUP; - } - ENDGROUP; - VGROUP; - LT_New(h, LA_Type, CYCLE_KIND, - LA_LabelID, STR_SCSI_MEMTYPE_CTRL, - LA_ID, GAD_SCSI_MEMTYPE, - LACY_FirstLabel, STR_MEMTYPE_CHIP_LAB, - LACY_LastLabel, STR_MEMTYPE_ANY_LAB, - LA_LONG, (ULONG)&scsi_memtype, - TAG_END - ); - ENDGROUP; - ENDGROUP; -} - - -/* - * "Graphics/Sound" pane - */ - -// Display types -enum { - DISPLAY_WINDOW, - DISPLAY_PIP, - DISPLAY_SCREEN -}; - -static LONG display_type; -static LONG dis_width, dis_height; -static ULONG mode_id; -static BYTE frameskip_num; -static struct NameInfo mode_name; -static ULONG ahi_id; -static char ahi_mode_name[256]; -static BYTE nosound; - -// Read graphics preferences -static void parse_graphics_prefs(void) -{ - display_type = DISPLAY_WINDOW; - dis_width = 512; - dis_height = 384; - mode_id = 0; - ahi_id = AHI_DEFAULT_ID; - ahi_mode_name[0] = 0; - - frameskip_num = 0; - int frameskip = PrefsFindInt32("frameskip"); - switch (frameskip) { - case 12: - frameskip_num = 0; - break; - case 8: - frameskip_num = 1; - break; - case 6: - frameskip_num = 2; - break; - case 4: - frameskip_num = 3; - break; - case 2: - frameskip_num = 4; - break; - case 1: - frameskip_num = 5; - break; - } - - const char *str = PrefsFindString("screen"); - if (str) { - if (sscanf(str, "win/%ld/%ld", &dis_width, &dis_height) == 2) - display_type = DISPLAY_WINDOW; - else if (sscanf(str, "pip/%ld/%ld", &dis_width, &dis_height) == 2) - display_type = DISPLAY_PIP; - else if (sscanf(str, "scr/%08lx", &mode_id) == 1) - display_type = DISPLAY_SCREEN; - } - - GetDisplayInfoData(NULL, (UBYTE *)&mode_name, sizeof(mode_name), DTAG_NAME, mode_id); - - str = PrefsFindString("sound"); - if (str) { - if (sscanf(str, "ahi/%08lx", &ahi_id) == 1 && AHIBase) { - AHI_GetAudioAttrs(ahi_id, NULL, - AHIDB_Name, (ULONG)ahi_mode_name, - AHIDB_BufferLen, sizeof(ahi_mode_name) - 1, - TAG_END - ); - } - } - nosound = PrefsFindBool("nosound"); -} - -// Ghost/unghost graphics gadgets, depending on display type -static void ghost_graphics_gadgets(struct LayoutHandle *h) -{ - bool dis_xy, dis_skip, dis_mode; - switch (display_type) { - case DISPLAY_WINDOW: - dis_xy = false; - dis_skip = false; - dis_mode = true; - break; - case DISPLAY_PIP: - dis_xy = false; - dis_skip = true; - dis_mode = true; - break; - case DISPLAY_SCREEN: - dis_xy = true; - dis_skip = true; - dis_mode = false; - break; - } - LT_SetAttributes(h, GAD_DISPLAY_X, GA_Disabled, dis_xy, TAG_END); - LT_SetAttributes(h, GAD_DISPLAY_Y, GA_Disabled, dis_xy, TAG_END); - LT_SetAttributes(h, GAD_FRAMESKIP, GA_Disabled, dis_skip, TAG_END); - LT_SetAttributes(h, GAD_SCREEN_MODE, GA_Disabled, dis_mode, TAG_END); - LT_SetAttributes(h, GAD_AHI_MODE, GA_Disabled, AHIBase == NULL, TAG_END); -} - -// Show screen mode requester -static void screen_mode_req(struct Window *win, struct LayoutHandle *h) -{ - if (P96Base == NULL && CyberGfxBase == NULL) - return; - - LT_LockWindow(win); - - ULONG id; - - // Try P96 first, because it also provides a (fake) cybergraphics.library - if (P96Base) { - id = p96RequestModeIDTags( - P96MA_MinDepth, 8, - P96MA_FormatsAllowed, RGBFF_CLUT | RGBFF_R5G5B5 | RGBFF_A8R8G8B8, - TAG_END - ); - } else { - UWORD ModelArray[] = { PIXFMT_LUT8, PIXFMT_RGB15, PIXFMT_ARGB32, 0, ~0 }; - id = (ULONG) CModeRequestTags(NULL, - CYBRMREQ_MinDepth, 8, - CYBRMREQ_CModelArray, (ULONG) ModelArray, - TAG_END - ); - } - LT_UnlockWindow(win); - - if (id != INVALID_ID) { - mode_id = id; - GetDisplayInfoData(NULL, (UBYTE *)&mode_name, sizeof(mode_name), DTAG_NAME, mode_id); - LT_SetAttributes(h, GAD_SCREEN_MODE, GTTX_Text, (ULONG)mode_name.Name, TAG_END); - } -} - -// Show AHI mode requester -static void ahi_mode_req(struct Window *win, struct LayoutHandle *h) -{ - if (AHIBase == NULL) - return; - - struct AHIAudioModeRequester *req = AHI_AllocAudioRequest( - AHIR_Window, (ULONG)win, - TAG_END - ); - if (req == NULL) - return; - - LT_LockWindow(win); - BOOL ok = AHI_AudioRequest(req, - AHIR_InitialAudioID, ahi_id, - TAG_END - ); - LT_UnlockWindow(win); - - if (ok) { - ahi_id = req->ahiam_AudioID; - AHI_GetAudioAttrs(ahi_id, NULL, - AHIDB_Name, (ULONG)ahi_mode_name, - AHIDB_BufferLen, sizeof(ahi_mode_name) - 1, - TAG_END - ); - LT_SetAttributes(h, GAD_AHI_MODE, GTTX_Text, (ULONG)ahi_mode_name, TAG_END); - } - AHI_FreeAudioRequest(req); -} - -// Read settings from gadgets and set preferences -static void read_graphics_settings(void) -{ - char str[256]; - switch (display_type) { - case DISPLAY_WINDOW: - sprintf(str, "win/%ld/%ld", dis_width, dis_height); - break; - case DISPLAY_PIP: - sprintf(str, "pip/%ld/%ld", dis_width, dis_height); - break; - case DISPLAY_SCREEN: - sprintf(str, "scr/%08lx", mode_id); - break; - default: - PrefsRemoveItem("screen"); - return; - } - PrefsReplaceString("screen", str); - - sprintf(str, "ahi/%08lx", ahi_id); - PrefsReplaceString("sound", str); - - PrefsReplaceBool("nosound", nosound); -} - -// Create "Graphics/Sound" pane -static void create_graphics_pane(struct LayoutHandle *h) -{ - parse_graphics_prefs(); - - VGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_GRAPHICS_CTRL, - TAG_END - ); - static const LONG labels[] = {STR_WINDOW_LAB, STR_PIP_LAB, STR_FULLSCREEN_LAB, -1}; - LT_New(h, LA_Type, CYCLE_KIND, - LA_LabelID, STR_VIDEO_TYPE_CTRL, - LA_ID, GAD_VIDEO_TYPE, - LACY_LabelTable, (ULONG)labels, - LA_LONG, (ULONG)&display_type, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_DISPLAY_X_CTRL, - LA_ID, GAD_DISPLAY_X, - LA_LONG, (ULONG)&dis_width, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_DISPLAY_Y_CTRL, - LA_ID, GAD_DISPLAY_Y, - LA_LONG, (ULONG)&dis_height, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, POPUP_KIND, - LA_LabelID, STR_FRAMESKIP_CTRL, - LA_ID, GAD_FRAMESKIP, - LAPU_FirstLabel, STR_REF_5HZ_LAB, - LAPU_LastLabel, STR_REF_60HZ_LAB, - LA_BYTE, (ULONG)&frameskip_num, - TAG_END - ); - LT_New(h, LA_Type, TEXT_KIND, - LA_LabelID, STR_SCREEN_MODE_CTRL, - LA_ID, GAD_SCREEN_MODE, - LA_Chars, DISPLAYNAMELEN, - LATX_Picker, TRUE, - GTTX_Text, (ULONG)mode_name.Name, - GTTX_Border, TRUE, - TAG_END - ); - ENDGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_SOUND_CTRL, - TAG_END - ); - LT_New(h, LA_Type, TEXT_KIND, - LA_LabelID, STR_AHI_MODE_CTRL, - LA_ID, GAD_AHI_MODE, - LA_Chars, DISPLAYNAMELEN, - LATX_Picker, TRUE, - GTTX_Text, (ULONG)ahi_mode_name, - GTTX_Border, TRUE, - TAG_END - ); - LT_New(h, LA_Type, CHECKBOX_KIND, - LA_LabelID, STR_NOSOUND_CTRL, - LA_ID, GAD_NOSOUND, - LA_BYTE, (ULONG)&nosound, - TAG_END - ); - ENDGROUP; - ENDGROUP; - - ghost_graphics_gadgets(h); -} - - -/* - * "Serial/Network" pane - */ - -static char seriala_dev[256], serialb_dev[256]; -static LONG seriala_unit, serialb_unit; -static BYTE seriala_ispar, serialb_ispar; - -static char ether_dev[256]; -static ULONG ether_unit; - -// Read serial/network preferences -static void parse_ser_prefs(const char *prefs, char *dev, LONG &unit, BYTE &ispar) -{ - dev[0] = 0; - unit = 0; - ispar = false; - - const char *str = PrefsFindString(prefs); - if (str) { - if (str[0] == '*') { - ispar = true; - str++; - } - sscanf(str, "%[^/]/%ld", dev, &unit); - } -} - -static void parse_serial_prefs(void) -{ - parse_ser_prefs("seriala", seriala_dev, seriala_unit, seriala_ispar); - parse_ser_prefs("serialb", serialb_dev, serialb_unit, serialb_ispar); - - ether_dev[0] = 0; - ether_unit = 0; - - const char *str = PrefsFindString("ether"); - if (str) { - const char *FirstSlash = strchr(str, '/'); - const char *LastSlash = strrchr(str, '/'); - - if (FirstSlash && FirstSlash && FirstSlash != LastSlash) { - // Device name contains path, i.e. "Networks/xyzzy.device" - const char *lp = str; - char *dp = ether_dev; - - while (lp != LastSlash) - *dp++ = *lp++; - *dp = '\0'; - - sscanf(LastSlash, "/%ld", ðer_unit); - -// printf("dev=<%s> unit=%d\n", ether_dev, ether_unit); - } else { - sscanf(str, "%[^/]/%ld", ether_dev, ðer_unit); - } - } -} - -// Set serial preference item -static void make_serial_prefs(const char *prefs, const char *dev, LONG unit, BYTE ispar) -{ - if (strlen(dev)) { - char str[256]; - sprintf(str, "%s%s/%ld", ispar ? "*" : "", dev, unit); - PrefsReplaceString(prefs, str); - } else - PrefsRemoveItem(prefs); -} - -// Read settings from gadgets and set preferences -static void read_serial_settings(void) -{ - make_serial_prefs("seriala", seriala_dev, seriala_unit, seriala_ispar); - make_serial_prefs("serialb", serialb_dev, serialb_unit, serialb_ispar); - - if (strlen(ether_dev)) { - char str[256]; - - sprintf(str, "%s/%ld", ether_dev, ether_unit); - PrefsReplaceString("ether", str); - } else - PrefsRemoveItem("ether"); -} - -// Create "Serial/Network" pane -static void create_serial_pane(struct LayoutHandle *h) -{ - parse_serial_prefs(); - - VGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_SERIALA_CTRL, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_SERIALA_DEVICE, - LA_Chars, 20, - LA_STRPTR, (ULONG)seriala_dev, - GTST_MaxChars, sizeof(seriala_dev) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_SERIALA_UNIT, - LA_LONG, (ULONG)&seriala_unit, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, CHECKBOX_KIND, - LA_LabelID, STR_ISPAR_CTRL, - LA_ID, GAD_SERIALA_ISPAR, - LA_BYTE, (ULONG)&seriala_ispar, - TAG_END - ); - ENDGROUP; - - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_SERIALB_CTRL, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_SERIALB_DEVICE, - LA_Chars, 20, - LA_STRPTR, (ULONG)serialb_dev, - GTST_MaxChars, sizeof(serialb_dev) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_SERIALB_UNIT, - LA_LONG, (ULONG)&serialb_unit, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, CHECKBOX_KIND, - LA_LabelID, STR_ISPAR_CTRL, - LA_ID, GAD_SERIALB_ISPAR, - LA_BYTE, (ULONG)&serialb_ispar, - TAG_END - ); - ENDGROUP; - - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_ETHERNET_IF_CTRL, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_ETHER_DEVICE, - LA_Chars, 20, - LA_STRPTR, (ULONG)ether_dev, - GTST_MaxChars, sizeof(ether_dev) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_ETHER_UNIT, - LA_LONG, (ULONG)ðer_unit, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - ENDGROUP; - ENDGROUP; -} - - -/* - * "Memory/Misc" pane - */ - -static ULONG ramsize_mb; -static BYTE model_num; -static char rom_file[256]; - -// Read memory/misc preferences -static void parse_memory_prefs(void) -{ - ramsize_mb = PrefsFindInt32("ramsize") >> 20; - - model_num = 0; - int id = PrefsFindInt32("modelid"); - switch (id) { - case 5: - model_num = 0; - break; - case 14: - model_num = 1; - break; - } - - rom_file[0] = 0; - const char *str = PrefsFindString("rom"); - if (str) { - strncpy(rom_file, str, sizeof(rom_file) - 1); - rom_file[sizeof(rom_file) - 1] = 0; - } -} - -// Read settings from gadgets and set preferences -static void read_memory_settings(void) -{ - PrefsReplaceInt32("ramsize", ramsize_mb << 20); - - if (strlen(rom_file)) - PrefsReplaceString("rom", rom_file); - else - PrefsRemoveItem("rom"); -} - -// Create "Memory/Misc" pane -static void create_memory_pane(struct LayoutHandle *h) -{ - parse_memory_prefs(); - - VGROUP; - LT_New(h, LA_Type, LEVEL_KIND, - LA_LabelID, STR_RAMSIZE_SLIDER, - LA_ID, GAD_RAMSIZE, - LA_Chars, 20, - LA_LONG, (ULONG)&ramsize_mb, - GTSL_LevelFormat, (ULONG)GetString(STR_RAMSIZE_FMT), - GTSL_Min, 1, - GTSL_Max, AvailMem(MEMF_LARGEST) >> 20, - TAG_END - ); - LT_New(h, LA_Type, CYCLE_KIND, - LA_LabelID, STR_MODELID_CTRL, - LA_ID, GAD_MODELID, - LACY_FirstLabel, STR_MODELID_5_LAB, - LACY_LastLabel, STR_MODELID_14_LAB, - LA_BYTE, (ULONG)&model_num, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_ROM_FILE_CTRL, - LA_ID, GAD_ROM_FILE, - LA_Chars, 20, - LA_STRPTR, (ULONG)rom_file, - GTST_MaxChars, sizeof(rom_file) - 1, - LAST_Picker, TRUE, - TAG_END - ); - ENDGROUP; -} - - -/* - * Read settings from gadgets and set preferences - */ - -static void read_settings(struct LayoutHandle *h) -{ - LT_UpdateStrings(h); - read_volumes_settings(); - read_scsi_settings(); - read_graphics_settings(); - read_serial_settings(); - read_memory_settings(); -} diff --git a/BasiliskII/src/AmigaOS/scsi_amiga.cpp b/BasiliskII/src/AmigaOS/scsi_amiga.cpp deleted file mode 100644 index c660eb26..00000000 --- a/BasiliskII/src/AmigaOS/scsi_amiga.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - * scsi_amiga.cpp - SCSI Manager, Amiga specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include - -#include "sysdeps.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "scsi.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static struct SCSICmd scsi; - -static IOStdReq *ios[8*8]; // IORequests for 8 units and 8 LUNs each -static IOStdReq *io; // Active IORequest (selected target) - -static struct MsgPort *the_port = NULL; // Message port for device communication - -static ULONG buffer_size; // Size of data buffer -static UBYTE *buffer = NULL; // Pointer to data buffer -static ULONG buffer_memf; // Buffer memory flags - -static UBYTE cmd_buffer[12]; // Buffer for SCSI command - -const int SENSE_LENGTH = 256; -static UBYTE *sense_buffer = NULL; // Buffer for autosense data - -static bool direct_transfers_supported = false; // Direct data transfers (bypassing the buffer) are supported - - -/* - * Initialization - */ - -void SCSIInit(void) -{ - int id, lun; - - int memtype = PrefsFindInt32("scsimemtype"); - switch (memtype) { - case 1: - buffer_memf = MEMF_24BITDMA | MEMF_PUBLIC; - break; - case 2: - buffer_memf = MEMF_ANY | MEMF_PUBLIC; - direct_transfers_supported = true; - break; - default: - buffer_memf = MEMF_CHIP | MEMF_PUBLIC; - break; - } - - // Create port and buffers - the_port = CreateMsgPort(); - buffer = (UBYTE *)AllocMem(buffer_size = 0x10000, buffer_memf); - sense_buffer = (UBYTE *)AllocMem(SENSE_LENGTH, MEMF_CHIP | MEMF_PUBLIC); - if (the_port == NULL || buffer == NULL || sense_buffer == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - - // Create and open IORequests for all 8 units (and all 8 LUNs) - for (id=0; id<8; id++) { - for (lun=0; lun<8; lun++) - ios[id*8+lun] = NULL; - char prefs_name[16]; - sprintf(prefs_name, "scsi%d", id); - const char *str = PrefsFindString(prefs_name); - if (str) { - char dev_name[256]; - ULONG dev_unit = 0; - if (sscanf(str, "%[^/]/%ld", dev_name, &dev_unit) == 2) { - for (lun=0; lun<8; lun++) { - struct IOStdReq *io = (struct IOStdReq *)CreateIORequest(the_port, sizeof(struct IOStdReq)); - if (io == NULL) - continue; - if (OpenDevice((UBYTE *) dev_name, dev_unit + lun * 10, (struct IORequest *)io, 0)) { - DeleteIORequest(io); - continue; - } - io->io_Data = &scsi; - io->io_Length = sizeof(scsi); - io->io_Command = HD_SCSICMD; - ios[id*8+lun] = io; - } - } - } - } - - // Reset SCSI bus - SCSIReset(); - - // Init SCSICmd - memset(&scsi, 0, sizeof(scsi)); - scsi.scsi_Command = cmd_buffer; - scsi.scsi_SenseData = sense_buffer; - scsi.scsi_SenseLength = SENSE_LENGTH; -} - - -/* - * Deinitialization - */ - -void SCSIExit(void) -{ - // Close all devices - for (int i=0; i<8; i++) - for (int j=0; j<8; j++) { - struct IOStdReq *io = ios[i*8+j]; - if (io) { - CloseDevice((struct IORequest *)io); - DeleteIORequest(io); - } - } - - // Delete port and buffers - if (the_port) - DeleteMsgPort(the_port); - if (buffer) - FreeMem(buffer, buffer_size); - if (sense_buffer) - FreeMem(sense_buffer, SENSE_LENGTH); -} - - -/* - * Check if requested data size fits into buffer, allocate new buffer if needed - */ - -static bool try_buffer(int size) -{ - if (size <= buffer_size) - return true; - - UBYTE *new_buffer = (UBYTE *)AllocMem(size, buffer_memf); - if (new_buffer == NULL) - return false; - FreeMem(buffer, buffer_size); - buffer = new_buffer; - buffer_size = size; - return true; -} - - -/* - * Set SCSI command to be sent by scsi_send_cmd() - */ - -void scsi_set_cmd(int cmd_length, uint8 *cmd) -{ - scsi.scsi_CmdLength = cmd_length; - memcpy(cmd_buffer, cmd, cmd_length); -} - - -/* - * Check for presence of SCSI target - */ - -bool scsi_is_target_present(int id) -{ - return ios[id * 8] != NULL; -} - - -/* - * Set SCSI target (returns false on error) - */ - -bool scsi_set_target(int id, int lun) -{ - struct IOStdReq *new_io = ios[id * 8 + lun]; - if (new_io == NULL) - return false; - if (new_io != io) - scsi.scsi_SenseActual = 0; // Clear sense data when selecting new target - io = new_io; - return true; -} - - -/* - * Send SCSI command to active target (scsi_set_command() must have been called), - * read/write data according to S/G table (returns false on error); timeout is in 1/60 sec - */ - -bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr, uint32 *sg_len, uint16 *stat, uint32 timeout) -{ - // Bypass the buffer if there's only one S/G table entry - bool do_direct_transfer = (sg_size == 1 && ((uint32)sg_ptr[0] & 1) == 0 && direct_transfers_supported); - - if (!do_direct_transfer) { - - // Check if buffer is large enough, allocate new buffer if needed - if (!try_buffer(data_length)) { - char str[256]; - sprintf(str, GetString(STR_SCSI_BUFFER_ERR), data_length); - ErrorAlert(str); - return false; - } - - // Process S/G table when writing - if (!reading) { - D(bug(" writing to buffer\n")); - uint8 *buffer_ptr = buffer; - for (int i=0; i -#include -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "serial.h" -#include "serial_defs.h" - -#define DEBUG 0 -#include "debug.h" - -#define MONITOR 0 - - -// These messages are sent to the serial process -const uint32 MSG_QUERY = 'qery'; // Query port status, return status in control_io -const uint32 MSG_SET_PARAMS = 'setp'; // Set serial parameters (parameters in control_io) -const uint32 MSG_SET_PAR_PARAMS = 'pstp'; // Set parallel parameters (parameters in control_io) -const uint32 MSG_KILL_IO = 'kill'; // Kill pending I/O requests -const uint32 MSG_BREAK = 'brek'; // Send break -const uint32 MSG_RESET = 'rset'; // Reset channel -const uint32 MSG_PRIME_IN = 'prin'; // Data input -const uint32 MSG_PRIME_OUT = 'pout'; // Data output - -struct SerMessage : public Message { - SerMessage(uint32 what_, const struct MsgPort *reply_port = NULL) - { - what = what_; - mn_ReplyPort = (struct MsgPort *)reply_port; - mn_Length = sizeof(*this); - } - uint32 what; - uint32 pb; -}; - - -// Driver private variables -class ASERDPort : public SERDPort { -public: - ASERDPort(const char *dev) - { - device_name = dev; - if (dev && dev[0] == '*') { - is_parallel = true; - device_name++; - } else - is_parallel = false; - control_io = NULL; - serial_proc = NULL; - reply_port = NULL; - } - - virtual ~ASERDPort() - { - } - - virtual int16 open(uint16 config); - virtual int16 prime_in(uint32 pb, uint32 dce); - virtual int16 prime_out(uint32 pb, uint32 dce); - virtual int16 control(uint32 pb, uint32 dce, uint16 code); - virtual int16 status(uint32 pb, uint32 dce, uint16 code); - virtual int16 close(void); - -private: - bool configure(uint16 config); - void set_handshake(uint32 s, bool with_dtr); - void send_to_proc(uint32 what, uint32 pb = 0); - bool query(void); - bool set_params(void); - bool set_par_params(void); - void conv_error(struct IOExtSer *io, uint32 dt); - static void serial_func(void); - - const char *device_name; // Device name - bool is_parallel; // Flag: Port is parallel - IOExtSer *control_io; // IORequest for setting serial port characteristics etc. - - struct Process *serial_proc; // Serial device handler process - bool proc_error; // Flag: process didn't initialize - struct MsgPort *proc_port; // Message port of process, for communication with main task - struct MsgPort *reply_port; // Reply port for communication with process - - uint8 err_mask; // shkErrs -}; - - -// Global variables -static void *proc_arg; // Argument to process -extern struct Task *MainTask; // Pointer to main task (from main_amiga.cpp) - - -/* - * Initialization - */ - -void SerialInit(void) -{ - // Read serial preferences and create structs for both ports - the_serd_port[0] = new ASERDPort(PrefsFindString("seriala")); - the_serd_port[1] = new ASERDPort(PrefsFindString("serialb")); -} - - -/* - * Deinitialization - */ - -void SerialExit(void) -{ - delete (ASERDPort *)the_serd_port[0]; - delete (ASERDPort *)the_serd_port[1]; -} - - -/* - * Open serial port - */ - -int16 ASERDPort::open(uint16 config) -{ - // Don't open NULL name devices - if (device_name == NULL) - return openErr; - - // Init variables - err_mask = 0; - - // Create message port - reply_port = CreateMsgPort(); - if (reply_port == NULL) - goto open_error; - - // Start process - proc_error = false; - proc_arg = this; - SetSignal(0, SIGF_SINGLE); - serial_proc = CreateNewProcTags( - NP_Entry, (ULONG)serial_func, - NP_Name, (ULONG)"Basilisk II Serial Task", - NP_Priority, 1, - TAG_END - ); - if (serial_proc == NULL) - goto open_error; - - // Wait for signal from process - Wait(SIGF_SINGLE); - - // Initialization error? Then bail out - if (proc_error) - goto open_error; - - // Configure port - configure(config); - return noErr; - -open_error: - serial_proc = NULL; - if (reply_port) { - DeleteMsgPort(reply_port); - reply_port = NULL; - } - return openErr; -} - - -/* - * Read data from port - */ - -int16 ASERDPort::prime_in(uint32 pb, uint32 dce) -{ - // Send input command to serial process - D(bug("primein\n")); - read_done = false; - read_pending = true; - WriteMacInt32(input_dt + serdtDCE, dce); - send_to_proc(MSG_PRIME_IN, pb); - return 1; // Command in progress -} - - -/* - * Write data to port - */ - -int16 ASERDPort::prime_out(uint32 pb, uint32 dce) -{ - // Send output command to serial process - D(bug("primeout\n")); - write_done = false; - write_pending = true; - WriteMacInt32(output_dt + serdtDCE, dce); - send_to_proc(MSG_PRIME_OUT, pb); - return 1; // Command in progress -} - - -/* - * Control calls - */ - -int16 ASERDPort::control(uint32 pb, uint32 dce, uint16 code) -{ - D(bug("control(%ld)\n", (uint32)code)); - switch (code) { - case 1: // KillIO - send_to_proc(MSG_KILL_IO); - return noErr; - - case kSERDConfiguration: - if (configure(ReadMacInt16(pb + csParam))) - return noErr; - else - return paramErr; - - case kSERDInputBuffer: { - if (is_parallel) - return noErr; - int buf = ReadMacInt16(pb + csParam + 4) & 0xffffffc0; - if (buf < 1024) // 1k minimum - buf = 1024; - D(bug(" buffer size is now %08lx\n", buf)); - control_io->io_RBufLen = buf; - return set_params() ? noErr : paramErr; - } - - case kSERDSerHShake: - set_handshake(pb + csParam, false); - return noErr; - - case kSERDSetBreak: - if (!is_parallel) - send_to_proc(MSG_BREAK); - return noErr; - - case kSERDClearBreak: - return noErr; - - case kSERDBaudRate: - if (is_parallel) - return noErr; - control_io->io_Baud = ReadMacInt16(pb + csParam); - D(bug(" baud rate %ld\n", control_io->io_Baud)); - return set_params() ? noErr : paramErr; - - case kSERDHandshake: - case kSERDHandshakeRS232: - set_handshake(pb + csParam, true); - return noErr; - - case kSERDClockMIDI: - if (is_parallel) - return noErr; - control_io->io_Baud = 31250; - control_io->io_SerFlags = SERF_XDISABLED | SERF_SHARED; - control_io->io_StopBits = 1; - control_io->io_ReadLen = control_io->io_WriteLen = 8; - return set_params() ? noErr : paramErr; - - case kSERDMiscOptions: - case kSERDAssertDTR: - case kSERDNegateDTR: - case kSERDSetPEChar: - case kSERDSetPEAltChar: - case kSERDAssertRTS: - case kSERDNegateRTS: - return noErr; // Not supported under AmigaOS - - case kSERD115KBaud: - if (is_parallel) - return noErr; - control_io->io_Baud = 115200; - return set_params() ? noErr : paramErr; - - case kSERD230KBaud: - case kSERDSetHighSpeed: - if (is_parallel) - return noErr; - control_io->io_Baud = 230400; - return set_params() ? noErr : paramErr; - - case kSERDResetChannel: - send_to_proc(MSG_RESET); - return noErr; - - default: - printf("WARNING: SerialControl(): unimplemented control code %d\n", code); - return controlErr; - } -} - - -/* - * Status calls - */ - -int16 ASERDPort::status(uint32 pb, uint32 dce, uint16 code) -{ - D(bug("status(%ld)\n", (uint32)code)); - switch (code) { - case kSERDInputCount: - WriteMacInt32(pb + csParam, 0); - if (!is_parallel) { - if (!query()) - return noErr; - D(bug("status(2) successful, returning %08lx\n", control_io->IOSer.io_Actual)); - WriteMacInt32(pb + csParam, control_io->IOSer.io_Actual); - } - return noErr; - - case kSERDStatus: { - uint32 p = pb + csParam; - WriteMacInt8(p + staCumErrs, cum_errors); - cum_errors = 0; - WriteMacInt8(p + staRdPend, read_pending); - WriteMacInt8(p + staWrPend, write_pending); - if (is_parallel) { - WriteMacInt8(p + staXOffSent, 0); - WriteMacInt8(p + staXOffHold, 0); - WriteMacInt8(p + staCtsHold, 0); - WriteMacInt8(p + staDsrHold, 0); - WriteMacInt8(p + staModemStatus, dsrEvent | dcdEvent | ctsEvent); - } else { - query(); - WriteMacInt8(p + staXOffSent, - (control_io->io_Status & IO_STATF_XOFFREAD ? xOffWasSent : 0) - | (control_io->io_Status & (1 << 6) ? dtrNegated : 0)); // RTS - WriteMacInt8(p + staXOffHold, control_io->io_Status & IO_STATF_XOFFWRITE); - WriteMacInt8(p + staCtsHold, control_io->io_Status & (1 << 4)); // CTS - WriteMacInt8(p + staDsrHold, control_io->io_Status & (1 << 3)); // DSR - WriteMacInt8(p + staModemStatus, - (control_io->io_Status & (1 << 3) ? 0 : dsrEvent) - | (control_io->io_Status & (1 << 2) ? riEvent : 0) - | (control_io->io_Status & (1 << 5) ? 0 : dcdEvent) - | (control_io->io_Status & (1 << 4) ? 0 : ctsEvent) - | (control_io->io_Status & IO_STATF_READBREAK ? breakEvent : 0)); - } - return noErr; - } - - default: - printf("WARNING: SerialStatus(): unimplemented status code %d\n", code); - return statusErr; - } -} - - -/* - * Close serial port - */ - -int16 ASERDPort::close() -{ - // Stop process - if (serial_proc) { - SetSignal(0, SIGF_SINGLE); - Signal(&serial_proc->pr_Task, SIGBREAKF_CTRL_C); - Wait(SIGF_SINGLE); - } - - // Delete reply port - if (reply_port) { - DeleteMsgPort(reply_port); - reply_port = NULL; - } - return noErr; -} - - -/* - * Configure serial port with MacOS config word - */ - -bool ASERDPort::configure(uint16 config) -{ - D(bug(" configure %04lx\n", (uint32)config)); - if (is_parallel) - return true; - - // Set number of stop bits - switch (config & 0xc000) { - case stop10: - control_io->io_StopBits = 1; - break; - case stop20: - control_io->io_StopBits = 2; - break; - default: - return false; - } - - // Set parity mode - switch (config & 0x3000) { - case noParity: - control_io->io_SerFlags &= ~SERF_PARTY_ON; - break; - case oddParity: - control_io->io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD; - break; - case evenParity: - control_io->io_SerFlags |= SERF_PARTY_ON; - control_io->io_SerFlags &= ~SERF_PARTY_ODD; - break; - default: - return false; - } - - // Set number of data bits - switch (config & 0x0c00) { - case data5: - control_io->io_ReadLen = control_io->io_WriteLen = 5; - break; - case data6: - control_io->io_ReadLen = control_io->io_WriteLen = 6; - break; - case data7: - control_io->io_ReadLen = control_io->io_WriteLen = 7; - break; - case data8: - control_io->io_ReadLen = control_io->io_WriteLen = 8; - break; - } - - // Set baud rate - control_io->io_Baud = 115200 / ((config & 0x03ff) + 2); - return set_params(); -} - - -/* - * Set serial handshaking - */ - -void ASERDPort::set_handshake(uint32 s, bool with_dtr) -{ - D(bug(" set_handshake %02x %02x %02x %02x %02x %02x %02x %02x\n", - ReadMacInt8(s + 0), ReadMacInt8(s + 1), ReadMacInt8(s + 2), ReadMacInt8(s + 3), - ReadMacInt8(s + 4), ReadMacInt8(s + 5), ReadMacInt8(s + 6), ReadMacInt8(s + 7))); - - err_mask = ReadMacInt8(s + shkErrs); - - if (is_parallel) { - - // Parallel handshake - if (with_dtr) { - if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR)) - ((IOExtPar *)control_io)->io_ParFlags |= PARF_ACKMODE; - else - ((IOExtPar *)control_io)->io_ParFlags &= ~PARF_ACKMODE; - } else { - if (ReadMacInt8(s + shkFCTS)) - ((IOExtPar *)control_io)->io_ParFlags |= PARF_ACKMODE; - else - ((IOExtPar *)control_io)->io_ParFlags &= ~PARF_ACKMODE; - } - set_par_params(); - - } else { - - // Serial handshake - if (ReadMacInt8(s + shkFXOn) || ReadMacInt8(s + shkFInX)) - control_io->io_SerFlags &= ~SERF_XDISABLED; - else - control_io->io_SerFlags |= SERF_XDISABLED; - - if (with_dtr) { - if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR)) - control_io->io_SerFlags |= SERF_7WIRE; - else - control_io->io_SerFlags &= ~SERF_7WIRE; - } else { - if (ReadMacInt8(s + shkFCTS)) - control_io->io_SerFlags |= SERF_7WIRE; - else - control_io->io_SerFlags &= ~SERF_7WIRE; - } - control_io->io_CtlChar = ReadMacInt16(s + shkXOn) << 16; - set_params(); - } -} - - -/* - * Send message to serial process - */ - -void ASERDPort::send_to_proc(uint32 what, uint32 pb) -{ - D(bug("sending %08lx to serial_proc\n", what)); - SerMessage msg(what, reply_port); - msg.pb = pb; - PutMsg(proc_port, &msg); - WaitPort(reply_port); - GetMsg(reply_port); - D(bug(" sent\n")); -} - - -/* - * Query serial port status - */ - -bool ASERDPort::query(void) -{ - send_to_proc(MSG_QUERY); - return control_io->IOSer.io_Error == 0; -} - - -/* - * Set serial parameters - */ - -bool ASERDPort::set_params(void) -{ - // Set/clear RadBoogie - UBYTE flags = control_io->io_SerFlags; - if (!(flags & SERF_PARTY_ON) && (flags & SERF_XDISABLED) && control_io->io_ReadLen == 8) - control_io->io_SerFlags |= SERF_RAD_BOOGIE; - else - control_io->io_SerFlags &= ~SERF_RAD_BOOGIE; - - // Send message to serial process - send_to_proc(MSG_SET_PARAMS); - return control_io->IOSer.io_Error == 0; -} - - -/* - * Set parallel parameters - */ - -bool ASERDPort::set_par_params(void) -{ - send_to_proc(MSG_SET_PAR_PARAMS); - return control_io->IOSer.io_Error == 0; -} - - -/* - * Convert AmigaOS error code to MacOS error code, set serdtResult and cum_errors - */ - -void ASERDPort::conv_error(struct IOExtSer *io, uint32 dt) -{ - int16 oserr; - uint8 cum; - - BYTE err = io->IOSer.io_Error; - if (err == 0 || err == IOERR_NOCMD) { - oserr = 0; - cum = 0; - } else { - if (is_parallel) { - oserr = (err_mask & framingErr) ? rcvrErr : 0; - cum = framingErr; - } else { - switch (io->IOSer.io_Error) { - case SerErr_DetectedBreak: - oserr = breakRecd; - cum = breakErr; - break; - case SerErr_ParityErr: - oserr = (err_mask & parityErr) ? rcvrErr : 0; - cum = parityErr; - break; - case SerErr_BufOverflow: - oserr = (err_mask & swOverrunErr) ? rcvrErr : 0; - cum = swOverrunErr; - break; - case SerErr_LineErr: - oserr = (err_mask & hwOverrunErr) ? rcvrErr : 0; - cum = hwOverrunErr; - break; - default: - oserr = (err_mask & framingErr) ? rcvrErr : 0; - cum = framingErr; - break; - } - } - } - - WriteMacInt32(dt + serdtResult, oserr); - cum_errors |= cum; -} - - -/* - * Process for communication with the serial.device - */ - -__saveds void ASERDPort::serial_func(void) -{ - struct ASERDPort *obj = (ASERDPort *)proc_arg; - struct MsgPort *proc_port = NULL, *io_port = NULL, *control_port = NULL; - struct IOExtSer *read_io = NULL, *write_io = NULL, *control_io = NULL; - uint8 orig_params[sizeof(struct IOExtSer)]; - bool opened = false; - ULONG io_mask = 0, proc_port_mask = 0; - - // Default: error occured - obj->proc_error = true; - - // Create message port for communication with main task - proc_port = CreateMsgPort(); - if (proc_port == NULL) - goto quit; - proc_port_mask = 1 << proc_port->mp_SigBit; - - // Create message ports for serial.device I/O - io_port = CreateMsgPort(); - if (io_port == NULL) - goto quit; - io_mask = 1 << io_port->mp_SigBit; - control_port = CreateMsgPort(); - if (control_port == NULL) - goto quit; - - // Create IORequests - read_io = (struct IOExtSer *)CreateIORequest(io_port, sizeof(struct IOExtSer)); - write_io = (struct IOExtSer *)CreateIORequest(io_port, sizeof(struct IOExtSer)); - control_io = (struct IOExtSer *)CreateIORequest(control_port, sizeof(struct IOExtSer)); - if (read_io == NULL || write_io == NULL || control_io == NULL) - goto quit; - read_io->IOSer.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug - write_io->IOSer.io_Message.mn_Node.ln_Type = 0; - control_io->IOSer.io_Message.mn_Node.ln_Type = 0; - - // Parse device name - char dev_name[256]; - ULONG dev_unit; - if (sscanf(obj->device_name, "%[^/]/%ld", dev_name, &dev_unit) < 2) - goto quit; - - // Open device - if (obj->is_parallel) - ((IOExtPar *)read_io)->io_ParFlags = PARF_SHARED; - else - read_io->io_SerFlags = SERF_SHARED | SERF_7WIRE; - if (OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)read_io, 0) || read_io->IOSer.io_Device == NULL) - goto quit; - opened = true; - - // Copy IORequests - memcpy(write_io, read_io, sizeof(struct IOExtSer)); - memcpy(control_io, read_io, sizeof(struct IOExtSer)); - - // Attach control_io to control_port and set default values - control_io->IOSer.io_Message.mn_ReplyPort = control_port; - if (!obj->is_parallel) { - control_io->io_CtlChar = SER_DEFAULT_CTLCHAR; - control_io->io_RBufLen = 64; - control_io->io_ExtFlags = 0; - control_io->io_Baud = 9600; - control_io->io_BrkTime = 250000; - control_io->io_ReadLen = control_io->io_WriteLen = 8; - control_io->io_StopBits = 1; - control_io->io_SerFlags = SERF_SHARED; - control_io->IOSer.io_Command = SDCMD_SETPARAMS; - DoIO((struct IORequest *)control_io); - memcpy(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar)); - } - - // Initialization went well, inform main task - obj->proc_port = proc_port; - obj->control_io = control_io; - obj->proc_error = false; - Signal(MainTask, SIGF_SINGLE); - - // Main loop - for (;;) { - - // Wait for I/O and messages (CTRL_C is used for quitting the task) - ULONG sig = Wait(proc_port_mask | io_mask | SIGBREAKF_CTRL_C); - - // Main task wants to quit us - if (sig & SIGBREAKF_CTRL_C) - break; - - // Main task sent a command to us - if (sig & proc_port_mask) { - struct SerMessage *msg; - while (msg = (SerMessage *)GetMsg(proc_port)) { - D(bug("serial_proc received %08lx\n", msg->what)); - switch (msg->what) { - case MSG_QUERY: - control_io->IOSer.io_Command = SDCMD_QUERY; - DoIO((struct IORequest *)control_io); - D(bug(" query returned %08lx, actual %08lx\n", control_io->IOSer.io_Error, control_io->IOSer.io_Actual)); - break; - - case MSG_SET_PARAMS: - // Only send SDCMD_SETPARAMS when configuration has changed - if (memcmp(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar))) { - memcpy(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar)); - memcpy(&(read_io->io_CtlChar), &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar)); - memcpy(&(write_io->io_CtlChar), &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar)); - control_io->IOSer.io_Command = SDCMD_SETPARAMS; - D(bug(" params %08lx %08lx %08lx %08lx %08lx %08lx\n", control_io->io_CtlChar, control_io->io_RBufLen, control_io->io_ExtFlags, control_io->io_Baud, control_io->io_BrkTime, *(uint32 *)((uint8 *)control_io + 76))); - DoIO((struct IORequest *)control_io); - D(bug(" set_parms returned %08lx\n", control_io->IOSer.io_Error)); - } - break; - - case MSG_SET_PAR_PARAMS: - control_io->IOSer.io_Command = PDCMD_SETPARAMS; - DoIO((struct IORequest *)control_io); - D(bug(" set_par_parms returned %08lx\n", control_io->IOSer.io_Error)); - break; - - case MSG_BREAK: - control_io->IOSer.io_Command = SDCMD_BREAK; - DoIO((struct IORequest *)control_io); - D(bug(" break returned %08lx\n", control_io->IOSer.io_Error)); - break; - - case MSG_RESET: - control_io->IOSer.io_Command = CMD_RESET; - DoIO((struct IORequest *)control_io); - D(bug(" reset returned %08lx\n", control_io->IOSer.io_Error)); - break; - - case MSG_KILL_IO: - AbortIO((struct IORequest *)read_io); - AbortIO((struct IORequest *)write_io); - WaitIO((struct IORequest *)read_io); - WaitIO((struct IORequest *)write_io); - obj->read_pending = obj->write_pending = false; - obj->read_done = obj->write_done = false; - break; - - case MSG_PRIME_IN: - read_io->IOSer.io_Message.mn_Node.ln_Name = (char *)msg->pb; - read_io->IOSer.io_Data = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer)); - read_io->IOSer.io_Length = ReadMacInt32(msg->pb + ioReqCount); - read_io->IOSer.io_Actual = 0; - read_io->IOSer.io_Command = CMD_READ; - D(bug("serial_proc receiving %ld bytes from %08lx\n", read_io->IOSer.io_Length, read_io->IOSer.io_Data)); - SendIO((struct IORequest *)read_io); - break; - - case MSG_PRIME_OUT: { - write_io->IOSer.io_Message.mn_Node.ln_Name = (char *)msg->pb; - write_io->IOSer.io_Data = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer)); - write_io->IOSer.io_Length = ReadMacInt32(msg->pb + ioReqCount); - write_io->IOSer.io_Actual = 0; - write_io->IOSer.io_Command = CMD_WRITE; - D(bug("serial_proc transmitting %ld bytes from %08lx\n", write_io->IOSer.io_Length, write_io->IOSer.io_Data)); -#if MONITOR - bug("Sending serial data:\n"); - uint8 *adr = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer)); - for (int i=0; iIOSer.io_Actual, read_io->IOSer.io_Error)); - uint32 pb = (uint32)read_io->IOSer.io_Message.mn_Node.ln_Name; -#if MONITOR - bug("Receiving serial data:\n"); - uint8 *adr = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer)); - for (int i=0; iIOSer.io_Actual; i++) { - bug("%02lx ", adr[i]); - } - bug("\n"); -#endif - WriteMacInt32(pb + ioActCount, read_io->IOSer.io_Actual); - obj->conv_error(read_io, obj->input_dt); - obj->read_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } else if (io == write_io) { - D(bug("write_io complete, %ld bytes sent, error %ld\n", write_io->IOSer.io_Actual, write_io->IOSer.io_Error)); - uint32 pb = (uint32)write_io->IOSer.io_Message.mn_Node.ln_Name; - WriteMacInt32(pb + ioActCount, write_io->IOSer.io_Actual); - obj->conv_error(write_io, obj->output_dt); - obj->write_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } - } - } - } -quit: - - // Close everything - if (opened) { - if (CheckIO((struct IORequest *)write_io) == 0) { - AbortIO((struct IORequest *)write_io); - WaitIO((struct IORequest *)write_io); - } - if (CheckIO((struct IORequest *)read_io) == 0) { - AbortIO((struct IORequest *)read_io); - WaitIO((struct IORequest *)read_io); - } - CloseDevice((struct IORequest *)read_io); - } - if (control_io) - DeleteIORequest(control_io); - if (write_io) - DeleteIORequest(write_io); - if (read_io) - DeleteIORequest(read_io); - if (control_port) - DeleteMsgPort(control_port); - if (io_port) - DeleteMsgPort(io_port); - - // Send signal to main task to confirm termination - Forbid(); - Signal(MainTask, SIGF_SINGLE); -} diff --git a/BasiliskII/src/AmigaOS/sys_amiga.cpp b/BasiliskII/src/AmigaOS/sys_amiga.cpp deleted file mode 100644 index 617df7b0..00000000 --- a/BasiliskII/src/AmigaOS/sys_amiga.cpp +++ /dev/null @@ -1,1122 +0,0 @@ -/* - * sys_amiga.cpp - System dependent routines, Amiga implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "sys.h" - -#define DEBUG 0 -#include "debug.h" - - -// File handles are pointers to these structures -struct file_handle { - bool is_file; // Flag: plain file or /dev/something? - bool read_only; // Copy of Sys_open() flag - loff_t start_byte; // Size of file header (if any) - loff_t size; // Size of file/device (minus header) - - BPTR f; // AmigaDOS file handle (if is_file == true) - - struct IOStdReq *io; // Pointer to IORequest (if is_file == false) - ULONG block_size; // Block size of device (must be a power of two) - bool is_nsd; // New style device? - bool does_64bit; // Supports 64 bit trackdisk commands? - bool is_ejected; // Volume has been (logically) ejected - bool is_2060scsi; // Enable workaround for 2060scsi.device CD-ROM TD_READ bug -}; - - -// FileInfoBlock (must be global because it has to be on a longword boundary) -static struct FileInfoBlock FIB; - -// Message port for device communication -static struct MsgPort *the_port = NULL; - -// Temporary buffer in chip memory -const int TMP_BUF_SIZE = 0x10000; -static UBYTE *tmp_buf = NULL; - - -/* - * Initialization - */ - -void SysInit(void) -{ - // Create port and temporary buffer - the_port = CreateMsgPort(); - tmp_buf = (UBYTE *)AllocMem(TMP_BUF_SIZE, MEMF_CHIP | MEMF_PUBLIC); - if (the_port == NULL || tmp_buf == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } -} - - -/* - * Deinitialization - */ - -void SysExit(void) -{ - // Delete port and temporary buffer - if (the_port) { - DeleteMsgPort(the_port); - the_port = NULL; - } - if (tmp_buf) { - FreeMem(tmp_buf, TMP_BUF_SIZE); - tmp_buf = NULL; - } -} - - -/* - * This gets called when no "floppy" prefs items are found - * It scans for available floppy drives and adds appropriate prefs items - */ - -void SysAddFloppyPrefs(void) -{ - for (int i=0; i<4; i++) { - ULONG id = GetUnitID(i); - if (id == DRT_150RPM) { // We need an HD drive - char str[256]; - sprintf(str, "/dev/mfm.device/%d/0/0/2880/512", i); - PrefsAddString("floppy", str); - } - } -} - - -/* - * This gets called when no "disk" prefs items are found - * It scans for available HFS volumes and adds appropriate prefs items - */ - -void SysAddDiskPrefs(void) -{ - // AmigaOS doesn't support MacOS partitioning, so this probably doesn't make much sense... -} - - -/* - * This gets called when no "cdrom" prefs items are found - * It scans for available CD-ROM drives and adds appropriate prefs items - */ - -void SysAddCDROMPrefs(void) -{ - // Don't scan for drives if nocdrom option given - if (PrefsFindBool("nocdrom")) - return; - - //!! -} - - -/* - * Add default serial prefs (must be added, even if no ports present) - */ - -void SysAddSerialPrefs(void) -{ - PrefsAddString("seriala", "serial.device/0"); - PrefsAddString("serialb", "*parallel.device/0"); -} - - -/* - * Open file/device, create new file handle (returns NULL on error) - * - * Format for device names: /dev////// - */ - -void *Sys_open(const char *name, bool read_only) -{ - bool is_file = (strstr(name, "/dev/") != name); - - D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write")); - - // File or device? - if (is_file) { - - // File, open it and get stats - BPTR f = Open((char *)name, MODE_OLDFILE); - if (!f) - return NULL; - if (!ExamineFH(f, &FIB)) { - Close(f); - return NULL; - } - - // Check if file is write protected - if (FIB.fib_Protection & FIBF_WRITE) - read_only = true; - - // Create file_handle - file_handle *fh = new file_handle; - fh->f = f; - fh->is_file = true; - fh->read_only = read_only; - - // Detect disk image file layout - loff_t size = FIB.fib_Size; - Seek(fh->f, 0, OFFSET_BEGINNING); - Read(fh->f, tmp_buf, 256); - FileDiskLayout(size, tmp_buf, fh->start_byte, fh->size); - return fh; - - } else { - - // Device, parse string - char dev_name[256]; - ULONG dev_unit = 0, dev_flags = 0, dev_start = 0, dev_size = 16, dev_bsize = 512; - if (sscanf(name, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", dev_name, &dev_unit, &dev_flags, &dev_start, &dev_size, &dev_bsize) < 2) - return NULL; - - // Create IORequest - struct IOStdReq *io = (struct IOStdReq *)CreateIORequest(the_port, sizeof(struct IOExtTD)); - if (io == NULL) - return NULL; - - // Open device - if (OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)io, dev_flags)) { - D(bug(" couldn't open device\n")); - DeleteIORequest(io); - return NULL; - } - - // Check for new style device - bool is_nsd = false, does_64bit = false; - struct NSDeviceQueryResult nsdqr; - nsdqr.DevQueryFormat = 0; - nsdqr.SizeAvailable = 0; - io->io_Command = NSCMD_DEVICEQUERY; - io->io_Length = sizeof(nsdqr); - io->io_Data = (APTR)&nsdqr; - LONG error = DoIO((struct IORequest *)io); - D(bug("DEVICEQUERY returned %ld (length %ld, actual %ld)\n", error, io->io_Length, io->io_Actual)); - if ((!error) && (io->io_Actual >= 16) && (io->io_Actual <= sizeof(nsdqr)) && (nsdqr.SizeAvailable == io->io_Actual)) { - - // Looks like an NSD - is_nsd = true; - D(bug(" new style device, type %ld\n", nsdqr.DeviceType)); - - // We only work with trackdisk-like devices - if (nsdqr.DeviceType != NSDEVTYPE_TRACKDISK) { - CloseDevice((struct IORequest *)io); - DeleteIORequest(io); - return NULL; - } - - // Check whether device is 64 bit capable - UWORD *cmdcheck; - for (cmdcheck = nsdqr.SupportedCommands; *cmdcheck; cmdcheck++) { - if (*cmdcheck == NSCMD_TD_READ64) { - D(bug(" supports 64 bit commands\n")); - does_64bit = true; - } - } - } - - // Create file_handle - file_handle *fh = new file_handle; - fh->io = io; - fh->is_file = false; - fh->read_only = read_only; - fh->start_byte = (loff_t)dev_start * dev_bsize; - fh->size = (loff_t)dev_size * dev_bsize; - fh->block_size = dev_bsize; - fh->is_nsd = is_nsd; - fh->does_64bit = does_64bit; - fh->is_ejected = false; - fh->is_2060scsi = (strcmp(dev_name, "2060scsi.device") == 0); - return fh; - } -} - - -/* - * Close file/device, delete file handle - */ - -void Sys_close(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - D(bug("Sys_close(%08lx)\n", arg)); - - // File or device? - if (fh->is_file) { - - // File, simply close it - Close(fh->f); - - } else { - - // Device, close it and delete IORequest - fh->io->io_Command = CMD_UPDATE; - DoIO((struct IORequest *)fh->io); - - fh->io->io_Command = TD_MOTOR; - fh->io->io_Length = 0; - DoIO((struct IORequest *)fh->io); - - CloseDevice((struct IORequest *)fh->io); - DeleteIORequest(fh->io); - } - delete fh; -} - - -/* - * Send one I/O request, using 64-bit addressing if the device supports it - */ - -static loff_t send_io_request(file_handle *fh, bool writing, ULONG length, loff_t offset, APTR data) -{ - if (fh->does_64bit) { - fh->io->io_Command = writing ? NSCMD_TD_WRITE64 : NSCMD_TD_READ64; - fh->io->io_Actual = offset >> 32; - } else { - fh->io->io_Command = writing ? CMD_WRITE : CMD_READ; - fh->io->io_Actual = 0; - } - fh->io->io_Length = length; - fh->io->io_Offset = offset; - fh->io->io_Data = data; - - if (fh->is_2060scsi && fh->block_size == 2048) { - - // 2060scsi.device has serious problems reading CD-ROMs via TD_READ - static struct SCSICmd scsi; - const int SENSE_LENGTH = 256; - static UBYTE sense_buffer[SENSE_LENGTH]; // Buffer for autosense data - static UBYTE cmd_buffer[10] = { 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - D(bug("send_io_request length=%lu offset=%lu\n", length, (ULONG) offset)); - - memset(sense_buffer, 0, sizeof(sense_buffer)); - - scsi.scsi_Command = cmd_buffer; - scsi.scsi_CmdLength = sizeof(cmd_buffer); - scsi.scsi_SenseData = sense_buffer; - scsi.scsi_SenseLength = SENSE_LENGTH; - scsi.scsi_Flags = SCSIF_AUTOSENSE | (writing ? SCSIF_WRITE : SCSIF_READ); - scsi.scsi_Data = (UWORD *) data; - scsi.scsi_Length = length; - - ULONG block_offset = (ULONG) offset / fh->block_size; - ULONG block_length = length / fh->block_size; - - cmd_buffer[2] = block_offset >> 24; - cmd_buffer[3] = block_offset >> 16; - cmd_buffer[4] = block_offset >> 8; - cmd_buffer[5] = block_offset & 0xff; - - cmd_buffer[7] = block_length >> 8; - cmd_buffer[8] = block_length & 0xff; - - fh->io->io_Command = HD_SCSICMD; - fh->io->io_Actual = 0; - fh->io->io_Offset = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - - BYTE result = DoIO((struct IORequest *)fh->io); - - if (result) { - D(bug("send_io_request SCSI FAIL result=%lu\n", result)); - - if (result == HFERR_BadStatus) { - D(bug("send_io_request SCSI Status=%lu\n", scsi.scsi_Status)); - if (scsi.scsi_Status == 2) { - D(bug("send_io_request Sense Key=%02lx\n", sense_buffer[2] & 0x0f)); - D(bug("send_io_request ASC=%02lx ASCQ=%02lx\n", sense_buffer[12], sense_buffer[13])); - } - } - return 0; - } - - D(bug("send_io_request SCSI Actual=%lu\n", scsi.scsi_Actual)); - - if (scsi.scsi_Actual != length) - return 0; - - return scsi.scsi_Actual; - - } else { - -// if (DoIO((struct IORequest *)fh->io) || fh->io->io_Actual != length) - if (DoIO((struct IORequest *)fh->io)) - { - D(bug("send_io_request/%ld: Actual=%lu length=%lu Err=%ld\n", __LINE__, fh->io->io_Actual, length, fh->io->io_Error)); - return 0; - } - return fh->io->io_Actual; - } -} - - -/* - * Read "length" bytes from file/device, starting at "offset", to "buffer", - * returns number of bytes read (or 0) - */ - -size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - { - D(bug("Sys_read/%ld return 0\n", __LINE__)); - return 0; - } - - D(bug("Sys_read/%ld length=%ld\n", __LINE__, length)); - - // File or device? - if (fh->is_file) { - - // File, seek to position - if (Seek(fh->f, offset + fh->start_byte, OFFSET_BEGINNING) == -1) - { - D(bug("Sys_read/%ld return 0\n", __LINE__)); - return 0; - } - - // Read data - LONG actual = Read(fh->f, buffer, length); - if (actual == -1) - { - D(bug("Sys_read/%ld return 0\n", __LINE__)); - return 0; - } - else - { - D(bug("Sys_read/%ld return %ld\n", __LINE__, actual)); - return actual; - } - - } else { - - // Device, pre-read (partial read of first block) necessary? - loff_t pos = offset + fh->start_byte; - size_t actual = 0; - uint32 pre_offset = pos % fh->block_size; - if (pre_offset) { - - // Yes, read one block - if (send_io_request(fh, false, fh->block_size, pos - pre_offset, tmp_buf) == 0) - { - D(bug("Sys_read/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Copy data to destination buffer - size_t pre_length = fh->block_size - pre_offset; - if (pre_length > length) - pre_length = length; - memcpy(buffer, tmp_buf + pre_offset, pre_length); - - // Adjust data pointers - buffer = (uint8 *)buffer + pre_length; - pos += pre_length; - length -= pre_length; - actual += pre_length; - } - - // Main read (complete reads of middle blocks) possible? - if (length >= fh->block_size) { - - // Yes, read blocks - size_t main_length = length & ~(fh->block_size - 1); - if (send_io_request(fh, false, main_length, pos, buffer) == 0) - { - D(bug("Sys_read/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Adjust data pointers - buffer = (uint8 *)buffer + main_length; - pos += main_length; - length -= main_length; - actual += main_length; - } - - // Post-read (partial read of last block) necessary? - if (length) { - - // Yes, read one block - if (send_io_request(fh, false, fh->block_size, pos, tmp_buf) == 0) - { - D(bug("Sys_read/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Copy data to destination buffer - memcpy(buffer, tmp_buf, length); - actual += length; - } - - D(bug("Sys_read/%ld return %ld\n", __LINE__, actual)); - return actual; - } -} - - -/* - * Write "length" bytes from "buffer" to file/device, starting at "offset", - * returns number of bytes written (or 0) - */ - -size_t Sys_write(void *arg, void *buffer, loff_t offset, size_t length) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - D(bug("Sys_write/%ld length=%ld\n", __LINE__, length)); - - // File or device? - if (fh->is_file) { - - // File, seek to position if necessary - if (Seek(fh->f, offset + fh->start_byte, OFFSET_BEGINNING) == -1) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Write data - LONG actual = Write(fh->f, buffer, length); - if (actual == -1) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - else - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, actual)); - return actual; - } - - } else { - - // Device, pre-write (partial write of first block) necessary - loff_t pos = offset + fh->start_byte; - size_t actual = 0; - uint32 pre_offset = pos % fh->block_size; - if (pre_offset) { - - // Yes, read one block - if (send_io_request(fh, false, fh->block_size, pos - pre_offset, tmp_buf) == 0) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Copy data from source buffer - size_t pre_length = fh->block_size - pre_offset; - if (pre_length > length) - pre_length = length; - memcpy(tmp_buf + pre_offset, buffer, pre_length); - - // Write block back - if (send_io_request(fh, true, fh->block_size, pos - pre_offset, tmp_buf) == 0) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Adjust data pointers - buffer = (uint8 *)buffer + pre_length; - pos += pre_length; - length -= pre_length; - actual += pre_length; - } - - // Main write (complete writes of middle blocks) possible? - if (length >= fh->block_size) { - - // Yes, write blocks - size_t main_length = length & ~(fh->block_size - 1); - if (send_io_request(fh, true, main_length, pos, buffer) == 0) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Adjust data pointers - buffer = (uint8 *)buffer + main_length; - pos += main_length; - length -= main_length; - actual += main_length; - } - - // Post-write (partial write of last block) necessary? - if (length) { - - // Yes, read one block - if (send_io_request(fh, false, fh->block_size, pos, tmp_buf) == 0) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Copy data from source buffer - memcpy(buffer, tmp_buf, length); - - // Write block back - if (send_io_request(fh, true, fh->block_size, pos, tmp_buf) == 0) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - actual += length; - } - - D(bug("Sys_write/%ld return %ld\n", __LINE__, actual)); - return actual; - } -} - - -/* - * Return size of file/device (minus header) - */ - -loff_t SysGetFileSize(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - return fh->size; -} - - -/* - * Eject volume (if applicable) - */ - -void SysEject(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - - // Flush buffer, turn off the drive motor and eject volume - fh->io->io_Command = CMD_UPDATE; - DoIO((struct IORequest *)fh->io); - - fh->io->io_Command = TD_MOTOR; - fh->io->io_Length = 0; - DoIO((struct IORequest *)fh->io); - - fh->io->io_Command = TD_EJECT; - fh->io->io_Length = 1; - DoIO((struct IORequest *)fh->io); - - fh->is_ejected = true; - } -} - - -/* - * Format volume (if applicable) - */ - -bool SysFormat(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - //!! - return true; -} - - -/* - * Check if file/device is read-only (this includes the read-only flag on Sys_open()) - */ - -bool SysIsReadOnly(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (fh->is_file) { - - // File, return flag given to Sys_open - return fh->read_only; - - } else { - - // Device, check write protection - fh->io->io_Command = TD_PROTSTATUS; - DoIO((struct IORequest *)fh->io); - if (fh->io->io_Actual) - return true; - else - return fh->read_only; - } -} - - -/* - * Check if the given file handle refers to a fixed or a removable disk - */ - -bool SysIsFixedDisk(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - return true; -} - - -/* - * Check if a disk is inserted in the drive (always true for files) - */ - -bool SysIsDiskInserted(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return true; - else { - - // Check medium status - fh->io->io_Command = TD_CHANGESTATE; - fh->io->io_Actual = 0; - DoIO((struct IORequest *)fh->io); - bool inserted = (fh->io->io_Actual == 0); - - if (!inserted) { - // Disk was ejected and has now been taken out - fh->is_ejected = false; - } - - if (fh->is_ejected) { - // Disk was ejected but has not yet been taken out, report it as - // no longer in the drive - return false; - } else - return inserted; - } -} - - -/* - * Prevent medium removal (if applicable) - */ - -void SysPreventRemoval(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - - // Send PREVENT ALLOW MEDIUM REMOVAL SCSI command - struct SCSICmd scsi; - static const UBYTE the_cmd[6] = {0x1e, 0, 0, 0, 1, 0}; - scsi.scsi_Length = 0; - scsi.scsi_Command = (UBYTE *)the_cmd; - scsi.scsi_CmdLength = 6; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - DoIO((struct IORequest *)fh->io); - } -} - - -/* - * Allow medium removal (if applicable) - */ - -void SysAllowRemoval(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - - // Send PREVENT ALLOW MEDIUM REMOVAL SCSI command - struct SCSICmd scsi; - static const UBYTE the_cmd[6] = {0x1e, 0, 0, 0, 0, 0}; - scsi.scsi_Length = 0; - scsi.scsi_Command = (UBYTE *)the_cmd; - scsi.scsi_CmdLength = 6; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - DoIO((struct IORequest *)fh->io); - } -} - - -/* - * Read CD-ROM TOC (binary MSF format, 804 bytes max.) - */ - -bool SysCDReadTOC(void *arg, uint8 *toc) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - // Send READ TOC MSF SCSI command - struct SCSICmd scsi; - static const UBYTE read_toc_cmd[10] = {0x43, 0x02, 0, 0, 0, 0, 0, 0x03, 0x24, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 804; - scsi.scsi_Command = (UBYTE *)read_toc_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - memcpy(toc, tmp_buf, 804); - return true; - } -} - - -/* - * Read CD-ROM position data (Sub-Q Channel, 16 bytes, see SCSI standard) - */ - -bool SysCDGetPosition(void *arg, uint8 *pos) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - // Send READ SUB-CHANNEL SCSI command - struct SCSICmd scsi; - static const UBYTE read_subq_cmd[10] = {0x42, 0x02, 0x40, 0x01, 0, 0, 0, 0, 0x10, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 16; - scsi.scsi_Command = (UBYTE *)read_subq_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - memcpy(pos, tmp_buf, 16); - return true; - } -} - - -/* - * Play CD audio - */ - -bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end_m, uint8 end_s, uint8 end_f) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - // Send PLAY AUDIO MSF SCSI command - struct SCSICmd scsi; - UBYTE play_cmd[10] = {0x47, 0, 0, start_m, start_s, start_f, end_m, end_s, end_f, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 0; - scsi.scsi_Command = play_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - return true; - } -} - - -/* - * Pause CD audio - */ - -bool SysCDPause(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - // Send PAUSE RESUME SCSI command - struct SCSICmd scsi; - static const UBYTE pause_cmd[10] = {0x4b, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 0; - scsi.scsi_Command = (UBYTE *)pause_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - return true; - } -} - - -/* - * Resume paused CD audio - */ - -bool SysCDResume(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - // Send PAUSE RESUME SCSI command - struct SCSICmd scsi; - static const UBYTE resume_cmd[10] = {0x4b, 0, 0, 0, 0, 0, 0, 0, 1, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 0; - scsi.scsi_Command = (UBYTE *)resume_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - return true; - } -} - - -/* - * Stop CD audio - */ - -bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - uint8 end_m = lead_out_m; - uint8 end_s = lead_out_s; - uint8 end_f = lead_out_f + 1; - if (end_f >= 75) { - end_f = 0; - end_s++; - if (end_s >= 60) { - end_s = 0; - end_m++; - } - } - - // Send PLAY AUDIO MSF SCSI command (play first frame of lead-out area) - struct SCSICmd scsi; - UBYTE play_cmd[10] = {0x47, 0, 0, lead_out_m, lead_out_s, lead_out_f, end_m, end_s, end_f, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 0; - scsi.scsi_Command = play_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - return true; - } -} - - -/* - * Perform CD audio fast-forward/fast-reverse operation starting from specified address - */ - -bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - //!! - return false; -} - - -/* - * Set CD audio volume (0..255 each channel) - */ - -void SysCDSetVolume(void *arg, uint8 left, uint8 right) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - - // Send MODE SENSE (CD-ROM Audio Control Parameters Page) SCSI command - struct SCSICmd scsi; - static const UBYTE mode_sense_cmd[6] = {0x1a, 0x08, 0x0e, 0, 20, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 20; - scsi.scsi_Command = (UBYTE *)mode_sense_cmd; - scsi.scsi_CmdLength = 6; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return; - - tmp_buf[6] = 0x04; // Immed - tmp_buf[9] = 0; // LBA/sec format - tmp_buf[10] = 0; // LBA/sec - tmp_buf[11] = 0; - tmp_buf[13] = left; // Port 0 volume - tmp_buf[15] = right; // Port 1 volume - - // Send MODE SELECT (CD-ROM Audio Control Parameters Page) SCSI command - static const UBYTE mode_select_cmd[6] = {0x15, 0x10, 0, 0, 20, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 20; - scsi.scsi_Command = (UBYTE *)mode_select_cmd; - scsi.scsi_CmdLength = 6; - scsi.scsi_Flags = SCSIF_WRITE; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - DoIO((struct IORequest *)fh->io); - } -} - - -/* - * Get CD audio volume (0..255 each channel) - */ - -void SysCDGetVolume(void *arg, uint8 &left, uint8 &right) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - - // Send MODE SENSE (CD-ROM Audio Control Parameters Page) SCSI command - struct SCSICmd scsi; - static const UBYTE mode_sense_cmd[6] = {0x1a, 0x08, 0x0e, 0, 20, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 20; - scsi.scsi_Command = (UBYTE *)mode_sense_cmd; - scsi.scsi_CmdLength = 6; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return; - left = tmp_buf[13]; // Port 0 volume - right = tmp_buf[15]; // Port 1 volume - } -} diff --git a/BasiliskII/src/AmigaOS/sysdeps.h b/BasiliskII/src/AmigaOS/sysdeps.h deleted file mode 100644 index 89505830..00000000 --- a/BasiliskII/src/AmigaOS/sysdeps.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * sysdeps.h - System dependent definitions for AmigaOS - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SYSDEPS_H -#define SYSDEPS_H - -#include -#include -#include -#include -#include -#include -#include - -#include "user_strings_amiga.h" - -// Mac and host address space are the same -#define REAL_ADDRESSING 1 - -// Using 68k natively -#define EMULATED_68K 0 - -// Mac ROM is not write protected -#define ROM_IS_WRITE_PROTECTED 0 -#define USE_SCRATCHMEM_SUBTERFUGE 1 - -// ExtFS is supported -#define SUPPORTS_EXTFS 1 - -// mon is not supported -#undef ENABLE_MON - -// Data types -typedef unsigned char uint8; -typedef signed char int8; -typedef unsigned short uint16; -typedef signed short int16; -typedef unsigned long uint32; -typedef signed long int32; -typedef unsigned long long uint64; -typedef signed long long int64; - -typedef unsigned long long loff_t; - -// Time data type for Time Manager emulation -typedef struct timeval tm_time_t; - -// Endianess conversion (not needed) -#define ntohs(x) (x) -#define ntohl(x) (x) -#define htons(x) (x) -#define htonl(x) (x) - -// Some systems don't define this (ExecBase->AttnFlags) -#ifndef AFF_68060 -#define AFF_68060 (1L<<7) -#endif - -#endif diff --git a/BasiliskII/src/AmigaOS/timer_amiga.cpp b/BasiliskII/src/AmigaOS/timer_amiga.cpp deleted file mode 100644 index ce5fd515..00000000 --- a/BasiliskII/src/AmigaOS/timer_amiga.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * timer_amiga.cpp - Time Manager emulation, AmigaOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include - -#include "sysdeps.h" -#include "timer.h" - -#define DEBUG 0 -#include "debug.h" - - -/* - * Return microseconds since boot (64 bit) - */ - -void Microseconds(uint32 &hi, uint32 &lo) -{ - D(bug("Microseconds\n")); - struct timeval tv; - GetSysTime(&tv); - uint64 tl = (uint64)tv.tv_secs * 1000000 + tv.tv_micro; - hi = tl >> 32; - lo = tl; -} - - -/* - * Return local date/time in Mac format (seconds since 1.1.1904) - */ - -uint32 TimerDateTime(void) -{ - ULONG secs, mics; - CurrentTime(&secs, &mics); - return secs + 0x8b31ef80; -} - - -/* - * Get current time - */ - -void timer_current_time(tm_time_t &t) -{ - GetSysTime(&t); -} - - -/* - * Add times - */ - -void timer_add_time(tm_time_t &res, tm_time_t a, tm_time_t b) -{ - res = a; - AddTime(&res, &b); -} - - -/* - * Subtract times - */ - -void timer_sub_time(tm_time_t &res, tm_time_t a, tm_time_t b) -{ - res = a; - SubTime(&res, &b); -} - - -/* - * Compare times (<0: a < b, =0: a = b, >0: a > b) - */ - -int timer_cmp_time(tm_time_t a, tm_time_t b) -{ - return CmpTime(&b, &a); -} - - -/* - * Convert Mac time value (>0: microseconds, <0: microseconds) to tm_time_t - */ - -void timer_mac2host_time(tm_time_t &res, int32 mactime) -{ - if (mactime > 0) { - res.tv_secs = mactime / 1000; // Time in milliseconds - res.tv_micro = (mactime % 1000) * 1000; - } else { - res.tv_secs = -mactime / 1000000; // Time in negative microseconds - res.tv_micro = -mactime % 1000000; - } -} - - -/* - * Convert positive tm_time_t to Mac time value (>0: microseconds, <0: microseconds) - * A negative input value for hosttime results in a zero return value - * As long as the microseconds value fits in 32 bit, it must not be converted to milliseconds! - */ - -int32 timer_host2mac_time(tm_time_t hosttime) -{ - if (hosttime.tv_secs < 0) - return 0; - else { - uint64 t = (uint64)hosttime.tv_secs * 1000000 + hosttime.tv_micro; - if (t > 0x7fffffff) - return t / 1000; // Time in milliseconds - else - return -t; // Time in negative microseconds - } -} - - -/* - * Suspend emulator thread, virtual CPU in idle mode - */ - -void idle_wait(void) -{ - // XXX if you implement this make sure to call idle_resume() from TriggerInterrupt() -} - - -/* - * Resume execution of emulator thread, events just arrived - */ - -void idle_resume(void) -{ -} diff --git a/BasiliskII/src/AmigaOS/user_strings_amiga.cpp b/BasiliskII/src/AmigaOS/user_strings_amiga.cpp deleted file mode 100644 index 5b41a587..00000000 --- a/BasiliskII/src/AmigaOS/user_strings_amiga.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * user_strings_amiga.cpp - AmigaOS-specific localizable strings - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "user_strings.h" - - -// Platform-specific string definitions -user_string_def platform_strings[] = { - // Common strings that have a platform-specific variant - {STR_VOLUME_IS_MOUNTED_WARN, "The volume '%s' is mounted under AmigaOS. Basilisk II will try to unmount it."}, - {STR_EXTFS_CTRL, "Amiga Root"}, - {STR_EXTFS_NAME, "Amiga Directory Tree"}, - {STR_EXTFS_VOLUME_NAME, "Amiga"}, - - // Purely platform-specific strings - {STR_NO_PREPARE_EMUL_ERR, "PrepareEmul is not installed. Run PrepareEmul and then try again to start Basilisk II."}, - {STR_NO_GADTOOLS_LIB_ERR, "Cannot open gadtools.library V39."}, - {STR_NO_IFFPARSE_LIB_ERR, "Cannot open iffparse.library V39."}, - {STR_NO_ASL_LIB_ERR, "Cannot open asl.library V36."}, - {STR_NO_TIMER_DEV_ERR, "Cannot open timer.device."}, - {STR_NO_P96_MODE_ERR, "The selected screen mode is not a Picasso96 or CyberGraphX mode."}, - {STR_NO_VIDEO_MODE_ERR, "Cannot obtain selected video mode."}, - {STR_WRONG_SCREEN_DEPTH_ERR, "Basilisk II only supports 8, 16 or 24 bit screens."}, - {STR_WRONG_SCREEN_FORMAT_ERR, "Basilisk II only supports big-endian chunky ARGB screen modes."}, - {STR_ENFORCER_RUNNING_ERR, "Enforcer/CyberGuard is running. Remove and then try again to start Basilisk II."}, - - {STR_NOT_ETHERNET_WARN, "The selected network device is not an Ethernet device. Networking will be disabled."}, - {STR_NO_MULTICAST_WARN, "Your Ethernet card does not support multicast and is not usable with AppleTalk. Please report this to the manufacturer of the card."}, - {STR_NO_GTLAYOUT_LIB_WARN, "Cannot open gtlayout.library V39. The preferences editor GUI will not be available."}, - {STR_NO_AHI_WARN, "Cannot open ahi.device V2. Audio output will be disabled."}, - {STR_NO_AHI_CTRL_WARN, "Cannot open AHI control structure. Audio output will be disabled."}, - {STR_NOT_ENOUGH_MEM_WARN, "Could not get %lu MBytes of memory.\nShould I use the largest Block (%lu MBytes) instead ?"}, - - {STR_AHI_MODE_CTRL, "AHI Mode"}, - {STR_SCSI_MEMTYPE_CTRL, "Buffer Memory Type"}, - {STR_MEMTYPE_CHIP_LAB, "Chip"}, - {STR_MEMTYPE_24BITDMA_LAB, "24-Bit DMA"}, - {STR_MEMTYPE_ANY_LAB, "Any"}, - {STR_SCSI_DEVICES_CTRL, "Virtual SCSI Devices"}, - - {-1, NULL} // End marker -}; - - -/* - * Fetch pointer to string, given the string number - */ - -const char *GetString(int num) -{ - // First search for platform-specific string - int i = 0; - while (platform_strings[i].num >= 0) { - if (platform_strings[i].num == num) - return platform_strings[i].str; - i++; - } - - // Not found, search for common string - i = 0; - while (common_strings[i].num >= 0) { - if (common_strings[i].num == num) - return common_strings[i].str; - i++; - } - return NULL; -} diff --git a/BasiliskII/src/AmigaOS/user_strings_amiga.h b/BasiliskII/src/AmigaOS/user_strings_amiga.h deleted file mode 100644 index 8903e5e8..00000000 --- a/BasiliskII/src/AmigaOS/user_strings_amiga.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * user_strings_amiga.h - AmigaOS-specific localizable strings - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef USER_STRINGS_AMIGA_H -#define USER_STRINGS_AMIGA_H - -enum { - STR_NO_PREPARE_EMUL_ERR = 10000, - STR_NO_GADTOOLS_LIB_ERR, - STR_NO_IFFPARSE_LIB_ERR, - STR_NO_ASL_LIB_ERR, - STR_NO_TIMER_DEV_ERR, - STR_NO_P96_MODE_ERR, - STR_NO_VIDEO_MODE_ERR, - STR_WRONG_SCREEN_DEPTH_ERR, - STR_WRONG_SCREEN_FORMAT_ERR, - STR_ENFORCER_RUNNING_ERR, - - STR_NOT_ETHERNET_WARN, - STR_NO_MULTICAST_WARN, - STR_NO_GTLAYOUT_LIB_WARN, - STR_NO_AHI_WARN, - STR_NO_AHI_CTRL_WARN, - STR_NOT_ENOUGH_MEM_WARN, - - STR_AHI_MODE_CTRL, - STR_SCSI_MEMTYPE_CTRL, - STR_MEMTYPE_CHIP_LAB, - STR_MEMTYPE_24BITDMA_LAB, - STR_MEMTYPE_ANY_LAB, - STR_SCSI_DEVICES_CTRL -}; - -#endif diff --git a/BasiliskII/src/AmigaOS/video_amiga.cpp b/BasiliskII/src/AmigaOS/video_amiga.cpp deleted file mode 100644 index 5e870a9c..00000000 --- a/BasiliskII/src/AmigaOS/video_amiga.cpp +++ /dev/null @@ -1,1165 +0,0 @@ -/* - * video_amiga.cpp - Video/graphics emulation, AmigaOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "adb.h" -#include "prefs.h" -#include "user_strings.h" -#include "video.h" - -#define DEBUG 0 -#include "debug.h" - - -// Supported video modes -static vector VideoModes; - -// Display types -enum { - DISPLAY_WINDOW, - DISPLAY_PIP, - DISPLAY_SCREEN_P96, - DISPLAY_SCREEN_CGFX -}; - -// Global variables -static int32 frame_skip; -static UWORD *null_pointer = NULL; // Blank mouse pointer data -static UWORD *current_pointer = (UWORD *)-1; // Currently visible mouse pointer data -static struct Process *periodic_proc = NULL; // Periodic process - -extern struct Task *MainTask; // Pointer to main task (from main_amiga.cpp) - - -// Amiga -> Mac raw keycode translation table -static const uint8 keycode2mac[0x80] = { - 0x0a, 0x12, 0x13, 0x14, 0x15, 0x17, 0x16, 0x1a, // ` 1 2 3 4 5 6 7 - 0x1c, 0x19, 0x1d, 0x1b, 0x18, 0x2a, 0xff, 0x52, // 8 9 0 - = \ inv 0 - 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x10, 0x20, 0x22, // Q W E R T Y U I - 0x1f, 0x23, 0x21, 0x1e, 0xff, 0x53, 0x54, 0x55, // O P [ ] inv 1 2 3 - 0x00, 0x01, 0x02, 0x03, 0x05, 0x04, 0x26, 0x28, // A S D F G H J K - 0x25, 0x29, 0x27, 0x2a, 0xff, 0x56, 0x57, 0x58, // L ; ' # inv 4 5 6 - 0x32, 0x06, 0x07, 0x08, 0x09, 0x0b, 0x2d, 0x2e, // < Z X C V B N M - 0x2b, 0x2f, 0x2c, 0xff, 0x41, 0x59, 0x5b, 0x5c, // , . / inv . 7 8 9 - 0x31, 0x33, 0x30, 0x4c, 0x24, 0x35, 0x75, 0xff, // SPC BSP TAB ENT RET ESC DEL inv - 0xff, 0xff, 0x4e, 0xff, 0x3e, 0x3d, 0x3c, 0x3b, // inv inv - inv CUP CDN CRT CLF - 0x7a, 0x78, 0x63, 0x76, 0x60, 0x61, 0x62, 0x64, // F1 F2 F3 F4 F5 F6 F7 F8 - 0x65, 0x6d, 0x47, 0x51, 0x4b, 0x43, 0x45, 0x72, // F9 F10 ( ) / * + HLP - 0x38, 0x38, 0x39, 0x36, 0x3a, 0x3a, 0x37, 0x37, // SHL SHR CAP CTL ALL ALR AML AMR - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv -}; - - -class Amiga_monitor_desc : public monitor_desc { -public: - Amiga_monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id, int default_display_type) - : monitor_desc(available_modes, default_depth, default_id), display_type(default_display_type) {}; - ~Amiga_monitor_desc() {}; - - virtual void switch_to_current_mode(void); - virtual void set_palette(uint8 *pal, int num); - - bool video_open(void); - void video_close(void); -public: - int display_type; // See enum above -}; - - -/* - * Display "driver" classes - */ - -class driver_base { -public: - driver_base(Amiga_monitor_desc &m); - virtual ~driver_base(); - - virtual void set_palette(uint8 *pal, int num) {}; - virtual struct BitMap *get_bitmap() { return NULL; }; -public: - Amiga_monitor_desc &monitor; // Associated video monitor - const video_mode &mode; // Video mode handled by the driver - BOOL init_ok; // Initialization succeeded (we can't use exceptions because of -fomit-frame-pointer) - struct Window *the_win; -}; - - -class driver_window : public driver_base { -public: - driver_window(Amiga_monitor_desc &m, int width, int height); - ~driver_window(); - - struct BitMap *get_bitmap() { return the_bitmap; }; - -private: - LONG black_pen, white_pen; - struct BitMap *the_bitmap; -}; - -class driver_pip : public driver_base { -public: - driver_pip(Amiga_monitor_desc &m, int width, int height); - ~driver_pip(); - - struct BitMap *get_bitmap() { return the_bitmap; }; - -private: - struct BitMap *the_bitmap; -}; - -class driver_screen_p96 : public driver_base { -public: - driver_screen_p96(Amiga_monitor_desc &m, ULONG mode_id); - ~driver_screen_p96(); - - void set_palette(uint8 *pal, int num); - -private: - struct Screen *the_screen; -}; - -class driver_screen_cgfx : public driver_base { -public: - driver_screen_cgfx(Amiga_monitor_desc &m, ULONG mode_id); - ~driver_screen_cgfx(); - - void set_palette(uint8 *pal, int num); - -private: - struct Screen *the_screen; -}; - - -static driver_base *drv = NULL; // Pointer to currently used driver object - - - -// Prototypes -static void periodic_func(void); -static void add_mode(uint32 width, uint32 height, uint32 resolution_id, uint32 bytes_per_row, video_depth depth); -static void add_modes(uint32 width, uint32 height, video_depth depth); -static ULONG find_mode_for_depth(uint32 width, uint32 height, uint32 depth); -static ULONG bits_from_depth(video_depth depth); -static bool is_valid_modeid(int display_type, ULONG mode_id); -static bool check_modeid_p96(ULONG mode_id); -static bool check_modeid_cgfx(ULONG mode_id); - - -/* - * Initialization - */ - - -bool VideoInit(bool classic) -{ - video_depth default_depth = VDEPTH_1BIT; - int default_width, default_height; - int default_display_type = DISPLAY_WINDOW; - int window_width, window_height; // width and height for window display - ULONG screen_mode_id; // mode ID for screen display - - // Allocate blank mouse pointer data - null_pointer = (UWORD *)AllocMem(12, MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR); - if (null_pointer == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - return false; - } - - // Read frame skip prefs - frame_skip = PrefsFindInt32("frameskip"); - if (frame_skip == 0) - frame_skip = 1; - - // Get screen mode from preferences - const char *mode_str; - if (classic) - mode_str = "win/512/342"; - else - mode_str = PrefsFindString("screen"); - - default_width = window_width = 512; - default_height = window_height = 384; - - if (mode_str) { - if (sscanf(mode_str, "win/%d/%d", &window_width, &window_height) == 2) - default_display_type = DISPLAY_WINDOW; - else if (sscanf(mode_str, "pip/%d/%d", &window_width, &window_height) == 2 && P96Base) - default_display_type = DISPLAY_PIP; - else if (sscanf(mode_str, "scr/%08lx", &screen_mode_id) == 1 && (CyberGfxBase || P96Base)) { - if (P96Base && p96GetModeIDAttr(screen_mode_id, P96IDA_ISP96)) - default_display_type = DISPLAY_SCREEN_P96; - else if (CyberGfxBase && IsCyberModeID(screen_mode_id)) - default_display_type = DISPLAY_SCREEN_CGFX; - else { - ErrorAlert(STR_NO_P96_MODE_ERR); - return false; - } - } - } - - D(bug("default_display_type %d, window_width %d, window_height %d\n", default_display_type, window_width, window_height)); - - // Construct list of supported modes - switch (default_display_type) { - case DISPLAY_WINDOW: - default_width = window_width; - default_height = window_height; - default_depth = VDEPTH_1BIT; - add_modes(window_width, window_height, VDEPTH_1BIT); - break; - - case DISPLAY_PIP: - default_width = window_width; - default_height = window_height; - default_depth = VDEPTH_16BIT; - add_modes(window_width, window_height, VDEPTH_16BIT); - break; - - case DISPLAY_SCREEN_P96: - case DISPLAY_SCREEN_CGFX: - struct DimensionInfo dimInfo; - DisplayInfoHandle handle = FindDisplayInfo(screen_mode_id); - - if (handle == NULL) - return false; - - if (GetDisplayInfoData(handle, (UBYTE *) &dimInfo, sizeof(dimInfo), DTAG_DIMS, 0) <= 0) - return false; - - default_width = 1 + dimInfo.Nominal.MaxX - dimInfo.Nominal.MinX; - default_height = 1 + dimInfo.Nominal.MaxY - dimInfo.Nominal.MinY; - - switch (dimInfo.MaxDepth) { - case 1: - default_depth = VDEPTH_1BIT; - break; - case 8: - default_depth = VDEPTH_8BIT; - break; - case 15: - case 16: - default_depth = VDEPTH_16BIT; - break; - case 24: - case 32: - default_depth = VDEPTH_32BIT; - break; - } - - for (unsigned d=VDEPTH_8BIT; d<=VDEPTH_32BIT; d++) { - ULONG mode_id = find_mode_for_depth(default_width, default_height, bits_from_depth(video_depth(d))); - - if (is_valid_modeid(default_display_type, mode_id)) - add_modes(default_width, default_height, video_depth(d)); - } - break; - } - -#if DEBUG - bug("Available video modes:\n"); - vector::const_iterator i = VideoModes.begin(), end = VideoModes.end(); - while (i != end) { - bug(" %ld x %ld (ID %02lx), %ld colors\n", i->x, i->y, i->resolution_id, 1 << bits_from_depth(i->depth)); - ++i; - } -#endif - - D(bug("VideoInit/%ld: def_width=%ld def_height=%ld def_depth=%ld\n", \ - __LINE__, default_width, default_height, default_depth)); - - // Find requested default mode and open display - if (VideoModes.size() == 1) { - uint32 default_id ; - - // Create Amiga_monitor_desc for this (the only) display - default_id = VideoModes[0].resolution_id; - D(bug("VideoInit/%ld: default_id=%ld\n", __LINE__, default_id)); - Amiga_monitor_desc *monitor = new Amiga_monitor_desc(VideoModes, default_depth, default_id, default_display_type); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); - - } else { - - // Find mode with specified dimensions - std::vector::const_iterator i, end = VideoModes.end(); - for (i = VideoModes.begin(); i != end; ++i) { - D(bug("VideoInit/%ld: w=%ld h=%ld d=%ld\n", __LINE__, i->x, i->y, bits_from_depth(i->depth))); - if (i->x == default_width && i->y == default_height && i->depth == default_depth) { - // Create Amiga_monitor_desc for this (the only) display - uint32 default_id = i->resolution_id; - D(bug("VideoInit/%ld: default_id=%ld\n", __LINE__, default_id)); - Amiga_monitor_desc *monitor = new Amiga_monitor_desc(VideoModes, default_depth, default_id, default_display_type); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); - } - } - - // Create Amiga_monitor_desc for this (the only) display - uint32 default_id = VideoModes[0].resolution_id; - D(bug("VideoInit/%ld: default_id=%ld\n", __LINE__, default_id)); - Amiga_monitor_desc *monitor = new Amiga_monitor_desc(VideoModes, default_depth, default_id, default_display_type); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); - } - - return true; -} - - -bool Amiga_monitor_desc::video_open() -{ - const video_mode &mode = get_current_mode(); - ULONG depth_bits = bits_from_depth(mode.depth); - ULONG ID = find_mode_for_depth(mode.x, mode.y, depth_bits); - - D(bug("video_open/%ld: width=%ld height=%ld depth=%ld ID=%08lx\n", __LINE__, mode.x, mode.y, depth_bits, ID)); - - if (ID == INVALID_ID) { - ErrorAlert(STR_NO_VIDEO_MODE_ERR); - return false; - } - - D(bug("video_open/%ld: display_type=%ld\n", __LINE__, display_type)); - - // Open display - switch (display_type) { - case DISPLAY_WINDOW: - drv = new driver_window(*this, mode.x, mode.y); - break; - - case DISPLAY_PIP: - drv = new driver_pip(*this, mode.x, mode.y); - break; - - case DISPLAY_SCREEN_P96: - drv = new driver_screen_p96(*this, ID); - break; - - case DISPLAY_SCREEN_CGFX: - drv = new driver_screen_cgfx(*this, ID); - break; - } - - D(bug("video_open/%ld: drv=%08lx\n", __LINE__, drv)); - - if (drv == NULL) - return false; - - D(bug("video_open/%ld: init_ok=%ld\n", __LINE__, drv->init_ok)); - if (!drv->init_ok) { - delete drv; - drv = NULL; - return false; - } - - // Start periodic process - periodic_proc = CreateNewProcTags( - NP_Entry, (ULONG)periodic_func, - NP_Name, (ULONG)"Basilisk II IDCMP Handler", - NP_Priority, 0, - TAG_END - ); - - D(bug("video_open/%ld: periodic_proc=%08lx\n", __LINE__, periodic_proc)); - - if (periodic_proc == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - return false; - } - - return true; -} - - -void Amiga_monitor_desc::video_close() -{ - // Stop periodic process - if (periodic_proc) { - SetSignal(0, SIGF_SINGLE); - Signal(&periodic_proc->pr_Task, SIGBREAKF_CTRL_C); - Wait(SIGF_SINGLE); - } - - delete drv; - drv = NULL; - - // Free mouse pointer - if (null_pointer) { - FreeMem(null_pointer, 12); - null_pointer = NULL; - } -} - - -/* - * Deinitialization - */ - -void VideoExit(void) -{ - // Close displays - vector::iterator i, end = VideoMonitors.end(); - for (i = VideoMonitors.begin(); i != end; ++i) - dynamic_cast(*i)->video_close(); -} - - -/* - * Set palette - */ - -void Amiga_monitor_desc::set_palette(uint8 *pal, int num) -{ - drv->set_palette(pal, num); -} - - -/* - * Switch video mode - */ - -void Amiga_monitor_desc::switch_to_current_mode() -{ - // Close and reopen display - video_close(); - if (!video_open()) { - ErrorAlert(STR_OPEN_WINDOW_ERR); - QuitEmulator(); - } -} - - -/* - * Close down full-screen mode (if bringing up error alerts is unsafe while in full-screen mode) - */ - -void VideoQuitFullScreen(void) -{ -} - - -/* - * Video message handling (not neccessary under AmigaOS, handled by periodic_func()) - */ - -void VideoInterrupt(void) -{ -} - - -/* - * Process for window refresh and message handling - */ - -static __saveds void periodic_func(void) -{ - struct MsgPort *timer_port = NULL; - struct timerequest *timer_io = NULL; - struct IntuiMessage *msg; - ULONG win_mask = 0, timer_mask = 0; - - D(bug("periodic_func/%ld: \n", __LINE__)); - - // Create message port for window and attach it - struct MsgPort *win_port = CreateMsgPort(); - if (win_port) { - win_mask = 1 << win_port->mp_SigBit; - drv->the_win->UserPort = win_port; - ModifyIDCMP(drv->the_win, IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_RAWKEY | - ((drv->monitor.display_type == DISPLAY_SCREEN_P96 || drv->monitor.display_type == DISPLAY_SCREEN_CGFX) ? IDCMP_DELTAMOVE : 0)); - } - - D(bug("periodic_func/%ld: \n", __LINE__)); - - // Start 60Hz timer for window refresh - if (drv->monitor.display_type == DISPLAY_WINDOW) { - timer_port = CreateMsgPort(); - if (timer_port) { - timer_io = (struct timerequest *)CreateIORequest(timer_port, sizeof(struct timerequest)); - if (timer_io) { - if (!OpenDevice((UBYTE *) TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timer_io, 0)) { - timer_mask = 1 << timer_port->mp_SigBit; - timer_io->tr_node.io_Command = TR_ADDREQUEST; - timer_io->tr_time.tv_secs = 0; - timer_io->tr_time.tv_micro = 16667 * frame_skip; - SendIO((struct IORequest *)timer_io); - } - } - } - } - - D(bug("periodic_func/%ld: \n", __LINE__)); - - // Main loop - for (;;) { - const video_mode &mode = drv->monitor.get_current_mode(); - - // Wait for timer and/or window (CTRL_C is used for quitting the task) - ULONG sig = Wait(win_mask | timer_mask | SIGBREAKF_CTRL_C); - - if (sig & SIGBREAKF_CTRL_C) - break; - -// D(bug("periodic_func/%ld: display_type=%ld the_win=%08lx\n", __LINE__, drv->monitor.display_type, drv->the_win)); - - if (sig & timer_mask) { - if (drv->get_bitmap()) { - // Timer tick, update display - BltTemplate(drv->get_bitmap()->Planes[0], 0, - drv->get_bitmap()->BytesPerRow, drv->the_win->RPort, - drv->the_win->BorderLeft, drv->the_win->BorderTop, - mode.x, mode.y); - } - - // Restart timer - timer_io->tr_node.io_Command = TR_ADDREQUEST; - timer_io->tr_time.tv_secs = 0; - timer_io->tr_time.tv_micro = 16667 * frame_skip; - SendIO((struct IORequest *)timer_io); - } - - if (sig & win_mask) { - - // Handle window messages - while (msg = (struct IntuiMessage *)GetMsg(win_port)) { - - // Get data from message and reply - ULONG cl = msg->Class; - UWORD code = msg->Code; - UWORD qualifier = msg->Qualifier; - WORD mx = msg->MouseX; - WORD my = msg->MouseY; - ReplyMsg((struct Message *)msg); - - // Handle message according to class - switch (cl) { - case IDCMP_MOUSEMOVE: - switch (drv->monitor.display_type) { - case DISPLAY_SCREEN_P96: - case DISPLAY_SCREEN_CGFX: -// D(bug("periodic_func/%ld: IDCMP_MOUSEMOVE mx=%ld my=%ld\n", __LINE__, mx, my)); - ADBMouseMoved(mx, my); - break; - default: -// D(bug("periodic_func/%ld: IDCMP_MOUSEMOVE mx=%ld my=%ld\n", __LINE__, mx - drv->the_win->BorderLeft, my - drv->the_win->BorderTop)); - ADBMouseMoved(mx - drv->the_win->BorderLeft, my - drv->the_win->BorderTop); - if (mx < drv->the_win->BorderLeft - || my < drv->the_win->BorderTop - || mx >= drv->the_win->BorderLeft + mode.x - || my >= drv->the_win->BorderTop + mode.y) { - if (current_pointer) { - ClearPointer(drv->the_win); - current_pointer = NULL; - } - } else { - if (current_pointer != null_pointer) { - // Hide mouse pointer inside window - SetPointer(drv->the_win, null_pointer, 1, 16, 0, 0); - current_pointer = null_pointer; - } - } - break; - } - break; - - case IDCMP_MOUSEBUTTONS: - if (code == SELECTDOWN) - ADBMouseDown(0); - else if (code == SELECTUP) - ADBMouseUp(0); - else if (code == MENUDOWN) - ADBMouseDown(1); - else if (code == MENUUP) - ADBMouseUp(1); - else if (code == MIDDLEDOWN) - ADBMouseDown(2); - else if (code == MIDDLEUP) - ADBMouseUp(2); - break; - - case IDCMP_RAWKEY: - if (qualifier & IEQUALIFIER_REPEAT) // Keyboard repeat is done by MacOS - break; - if ((qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_LSHIFT | IEQUALIFIER_CONTROL)) == - (IEQUALIFIER_LALT | IEQUALIFIER_LSHIFT | IEQUALIFIER_CONTROL) && code == 0x5f) { - SetInterruptFlag(INTFLAG_NMI); - TriggerInterrupt(); - break; - } - - if (code & IECODE_UP_PREFIX) - ADBKeyUp(keycode2mac[code & 0x7f]); - else - ADBKeyDown(keycode2mac[code & 0x7f]); - break; - } - } - } - } - - D(bug("periodic_func/%ld: \n", __LINE__)); - - // Stop timer - if (timer_io) { - if (!CheckIO((struct IORequest *)timer_io)) - AbortIO((struct IORequest *)timer_io); - WaitIO((struct IORequest *)timer_io); - CloseDevice((struct IORequest *)timer_io); - DeleteIORequest(timer_io); - } - if (timer_port) - DeleteMsgPort(timer_port); - - // Remove port from window and delete it - Forbid(); - msg = (struct IntuiMessage *)win_port->mp_MsgList.lh_Head; - struct Node *succ; - while (succ = msg->ExecMessage.mn_Node.ln_Succ) { - if (msg->IDCMPWindow == drv->the_win) { - Remove((struct Node *)msg); - ReplyMsg((struct Message *)msg); - } - msg = (struct IntuiMessage *)succ; - } - drv->the_win->UserPort = NULL; - ModifyIDCMP(drv->the_win, 0); - Permit(); - DeleteMsgPort(win_port); - - // Main task asked for termination, send signal - Forbid(); - Signal(MainTask, SIGF_SINGLE); -} - - -// Add mode to list of supported modes -static void add_mode(uint32 width, uint32 height, uint32 resolution_id, uint32 bytes_per_row, video_depth depth) -{ - video_mode mode; - mode.x = width; - mode.y = height; - mode.resolution_id = resolution_id; - mode.bytes_per_row = bytes_per_row; - mode.depth = depth; - - D(bug("Added video mode: w=%ld h=%ld d=%ld\n", width, height, depth)); - - VideoModes.push_back(mode); -} - -// Add standard list of modes for given color depth -static void add_modes(uint32 width, uint32 height, video_depth depth) -{ - D(bug("add_modes: w=%ld h=%ld d=%ld\n", width, height, depth)); - - if (width >= 512 && height >= 384) - add_mode(512, 384, 0x80, TrivialBytesPerRow(512, depth), depth); - if (width >= 640 && height >= 480) - add_mode(640, 480, 0x81, TrivialBytesPerRow(640, depth), depth); - if (width >= 800 && height >= 600) - add_mode(800, 600, 0x82, TrivialBytesPerRow(800, depth), depth); - if (width >= 1024 && height >= 768) - add_mode(1024, 768, 0x83, TrivialBytesPerRow(1024, depth), depth); - if (width >= 1152 && height >= 870) - add_mode(1152, 870, 0x84, TrivialBytesPerRow(1152, depth), depth); - if (width >= 1280 && height >= 1024) - add_mode(1280, 1024, 0x85, TrivialBytesPerRow(1280, depth), depth); - if (width >= 1600 && height >= 1200) - add_mode(1600, 1200, 0x86, TrivialBytesPerRow(1600, depth), depth); -} - - -static ULONG find_mode_for_depth(uint32 width, uint32 height, uint32 depth) -{ - ULONG ID = BestModeID(BIDTAG_NominalWidth, width, - BIDTAG_NominalHeight, height, - BIDTAG_Depth, depth, - BIDTAG_DIPFMustNotHave, DIPF_IS_ECS | DIPF_IS_HAM | DIPF_IS_AA, - TAG_END); - - return ID; -} - - -static ULONG bits_from_depth(video_depth depth) -{ - int bits = 1 << depth; - if (bits == 16) - bits = 15; - else if (bits == 32) - bits = 24; - - return bits; -} - - -static bool is_valid_modeid(int display_type, ULONG mode_id) -{ - if (INVALID_ID == mode_id) - return false; - - switch (display_type) { - case DISPLAY_SCREEN_P96: - return check_modeid_p96(mode_id); - break; - case DISPLAY_SCREEN_CGFX: - return check_modeid_cgfx(mode_id); - break; - default: - return false; - break; - } -} - - -static bool check_modeid_p96(ULONG mode_id) -{ - // Check if the mode is one we can handle - uint32 depth = p96GetModeIDAttr(mode_id, P96IDA_DEPTH); - uint32 format = p96GetModeIDAttr(mode_id, P96IDA_RGBFORMAT); - - D(bug("check_modeid_p96: mode_id=%08lx depth=%ld format=%ld\n", mode_id, depth, format)); - - if (!p96GetModeIDAttr(mode_id, P96IDA_ISP96)) - return false; - - switch (depth) { - case 8: - break; - case 15: - case 16: - if (format != RGBFB_R5G5B5) - return false; - break; - case 24: - case 32: - if (format != RGBFB_A8R8G8B8) - return false; - break; - default: - return false; - } - - return true; -} - - -static bool check_modeid_cgfx(ULONG mode_id) -{ - uint32 depth = GetCyberIDAttr(CYBRIDATTR_DEPTH, mode_id); - uint32 format = GetCyberIDAttr(CYBRIDATTR_PIXFMT, mode_id); - - D(bug("check_modeid_cgfx: mode_id=%08lx depth=%ld format=%ld\n", mode_id, depth, format)); - - if (!IsCyberModeID(mode_id)) - return false; - - switch (depth) { - case 8: - break; - case 15: - case 16: - if (format != PIXFMT_RGB15) - return false; - break; - case 24: - case 32: - if (format != PIXFMT_ARGB32) - return false; - break; - default: - return false; - } - - return true; -} - - -driver_base::driver_base(Amiga_monitor_desc &m) - : monitor(m), mode(m.get_current_mode()), init_ok(false) -{ -} - -driver_base::~driver_base() -{ -} - - -// Open window -driver_window::driver_window(Amiga_monitor_desc &m, int width, int height) - : black_pen(-1), white_pen(-1), driver_base(m) -{ - // Set absolute mouse mode - ADBSetRelMouseMode(false); - - // Open window - the_win = OpenWindowTags(NULL, - WA_Left, 0, WA_Top, 0, - WA_InnerWidth, width, WA_InnerHeight, height, - WA_SimpleRefresh, true, - WA_NoCareRefresh, true, - WA_Activate, true, - WA_RMBTrap, true, - WA_ReportMouse, true, - WA_DragBar, true, - WA_DepthGadget, true, - WA_SizeGadget, false, - WA_Title, (ULONG)GetString(STR_WINDOW_TITLE), - TAG_END - ); - if (the_win == NULL) { - init_ok = false; - ErrorAlert(STR_OPEN_WINDOW_ERR); - return; - } - - // Create bitmap ("height + 2" for safety) - the_bitmap = AllocBitMap(width, height + 2, 1, BMF_CLEAR, NULL); - if (the_bitmap == NULL) { - init_ok = false; - ErrorAlert(STR_NO_MEM_ERR); - return; - } - - // Add resolution and set VideoMonitor - monitor.set_mac_frame_base((uint32)the_bitmap->Planes[0]); - - // Set FgPen and BgPen - black_pen = ObtainBestPenA(the_win->WScreen->ViewPort.ColorMap, 0, 0, 0, NULL); - white_pen = ObtainBestPenA(the_win->WScreen->ViewPort.ColorMap, 0xffffffff, 0xffffffff, 0xffffffff, NULL); - SetAPen(the_win->RPort, black_pen); - SetBPen(the_win->RPort, white_pen); - SetDrMd(the_win->RPort, JAM2); - - init_ok = true; -} - - -driver_window::~driver_window() -{ - // Window mode, free bitmap - if (the_bitmap) { - WaitBlit(); - FreeBitMap(the_bitmap); - } - - // Free pens and close window - if (the_win) { - ReleasePen(the_win->WScreen->ViewPort.ColorMap, black_pen); - ReleasePen(the_win->WScreen->ViewPort.ColorMap, white_pen); - - CloseWindow(the_win); - the_win = NULL; - } -} - - -// Open PIP (requires Picasso96) -driver_pip::driver_pip(Amiga_monitor_desc &m, int width, int height) - : driver_base(m) -{ - // Set absolute mouse mode - ADBSetRelMouseMode(false); - - D(bug("driver_pip(%d,%d)\n", width, height)); - - // Open window - ULONG error = 0; - the_win = p96PIP_OpenTags( - P96PIP_SourceFormat, RGBFB_R5G5B5, - P96PIP_SourceWidth, width, - P96PIP_SourceHeight, height, - P96PIP_ErrorCode, (ULONG)&error, - P96PIP_AllowCropping, true, - WA_Left, 0, WA_Top, 0, - WA_InnerWidth, width, WA_InnerHeight, height, - WA_SimpleRefresh, true, - WA_NoCareRefresh, true, - WA_Activate, true, - WA_RMBTrap, true, - WA_ReportMouse, true, - WA_DragBar, true, - WA_DepthGadget, true, - WA_SizeGadget, false, - WA_Title, (ULONG)GetString(STR_WINDOW_TITLE), - WA_PubScreenName, (ULONG)"Workbench", - TAG_END - ); - if (the_win == NULL || error) { - init_ok = false; - ErrorAlert(STR_OPEN_WINDOW_ERR); - return; - } - - // Find bitmap - p96PIP_GetTags(the_win, P96PIP_SourceBitMap, (ULONG)&the_bitmap, TAG_END); - - // Add resolution and set VideoMonitor - monitor.set_mac_frame_base(p96GetBitMapAttr(the_bitmap, P96BMA_MEMORY)); - - init_ok = true; -} - -driver_pip::~driver_pip() -{ - // Close PIP - if (the_win) - p96PIP_Close(the_win); -} - - -// Open Picasso96 screen -driver_screen_p96::driver_screen_p96(Amiga_monitor_desc &m, ULONG mode_id) - : driver_base(m) -{ - // Set relative mouse mode - ADBSetRelMouseMode(true); - - // Check if the mode is one we can handle - if (!check_modeid_p96(mode_id)) - { - init_ok = false; - ErrorAlert(STR_WRONG_SCREEN_FORMAT_ERR); - return; - } - - // Yes, get width and height - uint32 depth = p96GetModeIDAttr(mode_id, P96IDA_DEPTH); - uint32 width = p96GetModeIDAttr(mode_id, P96IDA_WIDTH); - uint32 height = p96GetModeIDAttr(mode_id, P96IDA_HEIGHT); - - // Open screen - the_screen = p96OpenScreenTags( - P96SA_DisplayID, mode_id, - P96SA_Title, (ULONG)GetString(STR_WINDOW_TITLE), - P96SA_Quiet, true, - P96SA_NoMemory, true, - P96SA_NoSprite, true, - P96SA_Exclusive, true, - TAG_END - ); - if (the_screen == NULL) { - ErrorAlert(STR_OPEN_SCREEN_ERR); - init_ok = false; - return; - } - - // Open window - the_win = OpenWindowTags(NULL, - WA_Left, 0, WA_Top, 0, - WA_Width, width, WA_Height, height, - WA_SimpleRefresh, true, - WA_NoCareRefresh, true, - WA_Borderless, true, - WA_Activate, true, - WA_RMBTrap, true, - WA_ReportMouse, true, - WA_CustomScreen, (ULONG)the_screen, - TAG_END - ); - if (the_win == NULL) { - ErrorAlert(STR_OPEN_WINDOW_ERR); - init_ok = false; - return; - } - - ScreenToFront(the_screen); - - // Add resolution and set VideoMonitor - monitor.set_mac_frame_base(p96GetBitMapAttr(the_screen->RastPort.BitMap, P96BMA_MEMORY)); - - init_ok = true; -} - - -driver_screen_p96::~driver_screen_p96() -{ - // Close window - if (the_win) - { - CloseWindow(the_win); - the_win = NULL; - } - - // Close screen - if (the_screen) { - p96CloseScreen(the_screen); - the_screen = NULL; - } -} - - -void driver_screen_p96::set_palette(uint8 *pal, int num) -{ - // Convert palette to 32 bits - ULONG table[2 + 256 * 3]; - table[0] = num << 16; - table[num * 3 + 1] = 0; - for (int i=0; iViewPort, table); -} - - -// Open CyberGraphX screen -driver_screen_cgfx::driver_screen_cgfx(Amiga_monitor_desc &m, ULONG mode_id) - : driver_base(m) -{ - D(bug("driver_screen_cgfx/%ld: mode_id=%08lx\n", __LINE__, mode_id)); - - // Set absolute mouse mode - ADBSetRelMouseMode(true); - - // Check if the mode is one we can handle - if (!check_modeid_cgfx(mode_id)) - { - ErrorAlert(STR_WRONG_SCREEN_FORMAT_ERR); - init_ok = false; - return; - } - - // Yes, get width and height - uint32 depth = GetCyberIDAttr(CYBRIDATTR_DEPTH, mode_id); - uint32 width = GetCyberIDAttr(CYBRIDATTR_WIDTH, mode_id); - uint32 height = GetCyberIDAttr(CYBRIDATTR_HEIGHT, mode_id); - - // Open screen - the_screen = OpenScreenTags(NULL, - SA_DisplayID, mode_id, - SA_Title, (ULONG)GetString(STR_WINDOW_TITLE), - SA_Quiet, true, - SA_Exclusive, true, - TAG_END - ); - if (the_screen == NULL) { - ErrorAlert(STR_OPEN_SCREEN_ERR); - init_ok = false; - return; - } - - // Open window - the_win = OpenWindowTags(NULL, - WA_Left, 0, WA_Top, 0, - WA_Width, width, WA_Height, height, - WA_SimpleRefresh, true, - WA_NoCareRefresh, true, - WA_Borderless, true, - WA_Activate, true, - WA_RMBTrap, true, - WA_ReportMouse, true, - WA_CustomScreen, (ULONG)the_screen, - TAG_END - ); - if (the_win == NULL) { - ErrorAlert(STR_OPEN_WINDOW_ERR); - init_ok = false; - return; - } - - ScreenToFront(the_screen); - static UWORD ptr[] = { 0, 0, 0, 0 }; - SetPointer(the_win, ptr, 0, 0, 0, 0); // Hide mouse pointer - - // Set VideoMonitor - ULONG frame_base; - APTR handle = LockBitMapTags(the_screen->RastPort.BitMap, - LBMI_BASEADDRESS, (ULONG)&frame_base, - TAG_END - ); - UnLockBitMap(handle); - - D(bug("driver_screen_cgfx/%ld: frame_base=%08lx\n", __LINE__, frame_base)); - - monitor.set_mac_frame_base(frame_base); - - init_ok = true; -} - - -driver_screen_cgfx::~driver_screen_cgfx() -{ - D(bug("~driver_screen_cgfx/%ld: \n", __LINE__)); - - // Close window - if (the_win) - { - CloseWindow(the_win); - the_win = NULL; - } - - // Close screen - if (the_screen) { - CloseScreen(the_screen); - the_screen = NULL; - } -} - - -void driver_screen_cgfx::set_palette(uint8 *pal, int num) -{ - // Convert palette to 32 bits - ULONG table[2 + 256 * 3]; - table[0] = num << 16; - table[num * 3 + 1] = 0; - for (int i=0; iViewPort, table); -} diff --git a/BasiliskII/src/AmigaOS/xpram_amiga.cpp b/BasiliskII/src/AmigaOS/xpram_amiga.cpp deleted file mode 100644 index 69195d11..00000000 --- a/BasiliskII/src/AmigaOS/xpram_amiga.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * xpram_amiga.cpp - XPRAM handling, AmigaOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#define __USE_SYSBASE -#include -#include - -#include "sysdeps.h" -#include "xpram.h" - - -// XPRAM file name -#if POWERPC_ROM -static char XPRAM_FILE_NAME[] = "ENV:SheepShaver_NVRAM"; -static char XPRAM_FILE_NAME_ARC[] = "ENVARC:SheepShaver_NVRAM"; -#else -static char XPRAM_FILE_NAME[] = "ENV:BasiliskII_XPRAM"; -static char XPRAM_FILE_NAME_ARC[] = "ENVARC:BasiliskII_XPRAM"; -#endif - - -/* - * Load XPRAM from settings file - */ - -void LoadXPRAM(void) -{ - BPTR fh; - if ((fh = Open(XPRAM_FILE_NAME, MODE_OLDFILE)) != NULL) { - Read(fh, XPRAM, XPRAM_SIZE); - Close(fh); - } -} - - -/* - * Save XPRAM to settings file - */ - -void SaveXPRAM(void) -{ - BPTR fh; - if ((fh = Open(XPRAM_FILE_NAME, MODE_NEWFILE)) != NULL) { - Write(fh, XPRAM, XPRAM_SIZE); - Close(fh); - } - if ((fh = Open(XPRAM_FILE_NAME_ARC, MODE_NEWFILE)) != NULL) { - Write(fh, XPRAM, XPRAM_SIZE); - Close(fh); - } -} - - -/* - * Delete PRAM file - */ - -void ZapPRAM(void) -{ - DeleteFile(XPRAM_FILE_NAME); - DeleteFile(XPRAM_FILE_NAME_ARC); -} diff --git a/BasiliskII/src/BeOS/Makefile b/BasiliskII/src/BeOS/Makefile deleted file mode 100644 index e7feb636..00000000 --- a/BasiliskII/src/BeOS/Makefile +++ /dev/null @@ -1,151 +0,0 @@ -## BeOS Generic Makefile v2.1 ## - -## Fill in this file to specify the project being created, and the referenced -## makefile-engine will do all of the hard work for you. This handles both -## Intel and PowerPC builds of the BeOS. - -## Application Specific Settings --------------------------------------------- - -# specify the name of the binary -NAME= BasiliskII - -# specify the type of binary -# APP: Application -# SHARED: Shared library or add-on -# STATIC: Static library archive -# DRIVER: Kernel Driver -TYPE= APP - -# add support for new Pe and Eddie features -# to fill in generic makefile - -#%{ -# @src->@ - -# specify the source files to use -# full paths or paths relative to the makefile can be included -# all files, regardless of directory, will have their object -# files created in the common object directory. -# Note that this means this makefile will not work correctly -# if two source files with the same name (source.c or source.cpp) -# are included from different directories. Also note that spaces -# in folder names do not work well with this makefile. -MACHINE=$(shell uname -m) -ifeq ($(MACHINE), BePC) - CPUSRCS = ../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp \ - ../uae_cpu/readcpu.cpp ../uae_cpu/fpu/fpu_x86.cpp cpustbl.cpp cpudefs.cpp cpufast.s -else -# CPUSRCS = ../powerrom_cpu/powerrom_cpu.cpp - CPUSRCS = ../uae_cpu/basilisk_glue.cpp ../uae_cpu/newcpu.cpp \ - ../uae_cpu/readcpu.cpp ../uae_cpu/fpu/fpu_uae.cpp cpustbl.cpp cpudefs.cpp cpuemu.cpp -endif -SRCS = ../main.cpp main_beos.cpp ../prefs.cpp ../prefs_items.cpp prefs_beos.cpp \ - prefs_editor_beos.cpp sys_beos.cpp ../rom_patches.cpp ../slot_rom.cpp \ - ../rsrc_patches.cpp ../emul_op.cpp ../macos_util.cpp ../xpram.cpp \ - xpram_beos.cpp ../timer.cpp timer_beos.cpp clip_beos.cpp ../adb.cpp \ - ../serial.cpp serial_beos.cpp ../ether.cpp ether_beos.cpp ../sony.cpp \ - ../disk.cpp ../cdrom.cpp ../scsi.cpp scsi_beos.cpp ../video.cpp \ - video_beos.cpp ../audio.cpp audio_beos.cpp ../extfs.cpp extfs_beos.cpp \ - ../user_strings.cpp user_strings_beos.cpp about_window.cpp \ - $(CPUSRCS) - -# specify the resource files to use -# full path or a relative path to the resource file can be used. -RSRCS= - -# @<-src@ -#%} - -# end support for Pe and Eddie - -# specify additional libraries to link against -# there are two acceptable forms of library specifications -# - if your library follows the naming pattern of: -# libXXX.so or libXXX.a you can simply specify XXX -# library: libbe.so entry: be -# -# - if your library does not follow the standard library -# naming scheme you need to specify the path to the library -# and it's name -# library: my_lib.a entry: my_lib.a or path/my_lib.a -LIBS=be game media device textencoding tracker net - -# specify additional paths to directories following the standard -# libXXX.so or libXXX.a naming scheme. You can specify full paths -# or paths relative to the makefile. The paths included may not -# be recursive, so include all of the paths where libraries can -# be found. Directories where source files are found are -# automatically included. -LIBPATHS= - -# additional paths to look for system headers -# thes use the form: #include
-# source file directories are NOT auto-included here -SYSTEM_INCLUDE_PATHS = - -# additional paths to look for local headers -# thes use the form: #include "header" -# source file directories are automatically included -LOCAL_INCLUDE_PATHS = ../include SheepDriver SheepNet - -# specify the level of optimization that you desire -# NONE, SOME, FULL -OPTIMIZE= FULL - -# specify any preprocessor symbols to be defined. The symbols will not -# have their values set automatically; you must supply the value (if any) -# to use. For example, setting DEFINES to "DEBUG=1" will cause the -# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" -# would pass "-DDEBUG" on the compiler's command line. -DEFINES= FPU_X86 SIZEOF_FLOAT=4 SIZEOF_DOUBLE=8 SIZEOF_LONG_DOUBLE=10 - -# specify special warning levels -# if unspecified default warnings will be used -# NONE = supress all warnings -# ALL = enable all warnings -WARNINGS = - -# specify whether image symbols will be created -# so that stack crawls in the debugger are meaningful -# if TRUE symbols will be created -SYMBOLS = - -# specify debug settings -# if TRUE will allow application to be run from -# a source-level debugger -DEBUGGER = - -# specify additional compiler flags for all files -COMPILER_FLAGS = -fomit-frame-pointer -fno-PIC - -# specify additional linker flags -LINKER_FLAGS = - - -## include the makefile-engine -include /boot/system/develop/etc/makefile-engine - - -# special handling of UAE CPU engine -$(OBJ_DIR)/%.o : %.s - $(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuopti: $(OBJ_DIR)/cpuopti.o - $(CC) $(LDFLAGS) -o $(OBJ_DIR)/cpuopti $(OBJ_DIR)/cpuopti.o -$(OBJ_DIR)/build68k: $(OBJ_DIR)/build68k.o - $(CC) $(LDFLAGS) -o $(OBJ_DIR)/build68k $(OBJ_DIR)/build68k.o -$(OBJ_DIR)/gencpu: $(OBJ_DIR)/gencpu.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o - $(CC) $(LDFLAGS) -o $(OBJ_DIR)/gencpu $(OBJ_DIR)/gencpu.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o -cpudefs.cpp: $(OBJ_DIR)/build68k ../uae_cpu/table68k - $(OBJ_DIR)/build68k <../uae_cpu/table68k >cpudefs.cpp -cpuemu.cpp: $(OBJ_DIR)/gencpu - $(OBJ_DIR)/gencpu -cpustbl.cpp: cpuemu.cpp -cputbl.h: cpuemu.cpp -cpufast.s: cpuemu.cpp $(OBJ_DIR)/cpuopti - $(CXX) $(INCLUDES) -S $(CFLAGS) $< -o cputmp.s - $(OBJ_DIR)/cpuopti $@ || mv cputmp.s $@ - rm -f cputmp.s - -streifenfrei: - -rm -f $(OBJ_DIR)/gencpu $(OBJ_DIR)/build68k $(OBJ_DIR)/cpuopti - -rm -f cpuemu.cpp cpudefs.cpp cputmp.s cpufast*.s cpustbl.cpp cputbl.h diff --git a/BasiliskII/src/BeOS/SheepDriver/Makefile b/BasiliskII/src/BeOS/SheepDriver/Makefile deleted file mode 100644 index 52b2b70e..00000000 --- a/BasiliskII/src/BeOS/SheepDriver/Makefile +++ /dev/null @@ -1,117 +0,0 @@ -## BeOS Generic Makefile v2.1 ## - -## Fill in this file to specify the project being created, and the referenced -## makefile-engine will do all of the hard work for you. This handles both -## Intel and PowerPC builds of the BeOS. - -## Application Specific Settings --------------------------------------------- - -# specify the name of the binary -NAME= sheep - -# specify the type of binary -# APP: Application -# SHARED: Shared library or add-on -# STATIC: Static library archive -# DRIVER: Kernel Driver -TYPE= DRIVER - -# add support for new Pe and Eddie features -# to fill in generic makefile - -#%{ -# @src->@ - -# specify the source files to use -# full paths or paths relative to the makefile can be included -# all files, regardless of directory, will have their object -# files created in the common object directory. -# Note that this means this makefile will not work correctly -# if two source files with the same name (source.c or source.cpp) -# are included from different directories. Also note that spaces -# in folder names do not work well with this makefile. -SRCS= sheep_driver.c - -# specify the resource files to use -# full path or a relative path to the resource file can be used. -RSRCS= - -# @<-src@ -#%} - -# end support for Pe and Eddie - -# specify additional libraries to link against -# there are two acceptable forms of library specifications -# - if your library follows the naming pattern of: -# libXXX.so or libXXX.a you can simply specify XXX -# library: libbe.so entry: be -# -# - if your library does not follow the standard library -# naming scheme you need to specify the path to the library -# and it's name -# library: my_lib.a entry: my_lib.a or path/my_lib.a -LIBS= - -# specify additional paths to directories following the standard -# libXXX.so or libXXX.a naming scheme. You can specify full paths -# or paths relative to the makefile. The paths included may not -# be recursive, so include all of the paths where libraries can -# be found. Directories where source files are found are -# automatically included. -LIBPATHS= - -# additional paths to look for system headers -# thes use the form: #include
-# source file directories are NOT auto-included here -SYSTEM_INCLUDE_PATHS = - -# additional paths to look for local headers -# thes use the form: #include "header" -# source file directories are automatically included -LOCAL_INCLUDE_PATHS = - -# specify the level of optimization that you desire -# NONE, SOME, FULL -OPTIMIZE= FULL - -# specify any preprocessor symbols to be defined. The symbols will not -# have their values set automatically; you must supply the value (if any) -# to use. For example, setting DEFINES to "DEBUG=1" will cause the -# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" -# would pass "-DDEBUG" on the compiler's command line. -DEFINES= - -# specify special warning levels -# if unspecified default warnings will be used -# NONE = supress all warnings -# ALL = enable all warnings -WARNINGS = - -# specify whether image symbols will be created -# so that stack crawls in the debugger are meaningful -# if TRUE symbols will be created -SYMBOLS = - -# specify debug settings -# if TRUE will allow application to be run from a source-level -# debugger. Note that this will disable all optimzation. -DEBUGGER = - -# specify additional compiler flags for all files -COMPILER_FLAGS = - -# specify additional linker flags -LINKER_FLAGS = - - -## include the makefile-engine -include /boot/develop/etc/makefile-engine - -install: $(TARGET) - cp $(TARGET) /boot/home/config/add-ons/kernel/drivers/bin - ln -sf /boot/home/config/add-ons/kernel/drivers/bin/$(NAME) /boot/home/config/add-ons/kernel/drivers/dev/$(NAME) - -uninstall: - rm /boot/home/config/add-ons/kernel/drivers/bin/$(NAME) - rm /boot/home/config/add-ons/kernel/drivers/dev/$(NAME) diff --git a/BasiliskII/src/BeOS/SheepDriver/sheep_driver.c b/BasiliskII/src/BeOS/SheepDriver/sheep_driver.c deleted file mode 100644 index 859d82e2..00000000 --- a/BasiliskII/src/BeOS/SheepDriver/sheep_driver.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * sheep_driver.c - Low memory and ROM access driver for SheepShaver and - * Basilisk II on PowerPC systems - * - * SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer - * Basilisk II (C) 1997-2002 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef __i386__ -#error The sheep driver only runs on PowerPC machines. -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "sheep_driver.h" - -#define DEBUG 0 - -#if DEBUG==1 -#define bug pprintf -#elif DEBUG==2 -#define bug dprintf -#endif - -#if DEBUG -#define D(x) (x) -#else -#define D(x) ; -#endif - -#define PORT_NAME "sheep_driver installed" - - -/* - * For debugging - */ - -static int pprintf(const char* format, ...) -{ - port_id PortNum; - int len, ret; - char Buffer[1024]; - va_list ap; - - if ((PortNum = find_port("PortLogger")) == B_NAME_NOT_FOUND) - return(PortNum); - for (len=0; len<1024; len++) - Buffer[len]='\0'; - va_start(ap, format); - vsprintf(Buffer, format, ap); - ret = write_port(PortNum, 0, Buffer, strlen(Buffer)); - return ret; -} - - -/* - * Page table functions - */ - -static uint32 *pte_address = 0; -static uint32 vsid; -static uint32 table_size; - -static status_t map_page(uint32 ea, uint32 ra, uint32 **free_pte, uint32 bits) -{ - int i; - int pte_class; - uint32 hash1, hash2, api, *pteg1, *pteg2; - - D(bug("Trying to map EA %p -> RA %p\n", ea, ra)); - - // Find PTEG addresses for given EA - hash1 = (vsid & 0x7ffff) ^ ((ea >> 12) & 0xffff); - hash2 = ~hash1 & 0x7ffff; - api = (ea >> 22) & 0x3f; - pteg1 = (uint32 *)((uint32)pte_address + ((hash1 << 6) & (table_size - 1))); - pteg2 = (uint32 *)((uint32)pte_address + ((hash2 << 6) & (table_size - 1))); - D(bug("PTEG1 at %p, PTEG2 at %p\n", pteg1, pteg2)); - - // Search all 8 PTEs of each PTEG - *free_pte = NULL; - pte_class = 0; - for (i=0; i<8; i++) { - D(bug(" found %08lx %08lx\n", pteg1[i*2], pteg1[i*2+1])); - if (pteg1[i*2] == (0x80000000 | (vsid << 7) | (pte_class << 6) | api)) { - *free_pte = pteg1 + i*2; - D(bug(" existing PTE found (PTEG1)\n")); - break; - } else if (!pteg1[i*2]) { - *free_pte = pteg1 + i*2; - D(bug(" free PTE found (PTEG1)\n")); - break; - } - } - if (*free_pte == NULL) { - pte_class = 1; - for (i=0; i<8; i++) { - D(bug(" found %08lx %08lx\n", pteg2[i*2], pteg2[i*2+1])); - if (pteg2[i*2] == (0x80000000 | (vsid << 7) | (pte_class << 6) | api)) { - *free_pte = pteg2 + i*2; - D(bug(" existing PTE found (PTEG2)\n")); - break; - } else if (!pteg2[i*2]) { - *free_pte = pteg2 + i*2; - D(bug(" free PTE found (PTEG2)\n")); - break; - } - } - } - - // Remap page - if (*free_pte == NULL) { - D(bug(" No free PTE found :-(\m")); - return B_DEVICE_FULL; - } else { - (*free_pte)[0] = 0x80000000 | (vsid << 7) | (pte_class << 6) | api; - (*free_pte)[1] = ra | bits; - D(bug(" written %08lx %08lx to PTE\n", (*free_pte)[0], (*free_pte)[1])); - return B_NO_ERROR; - } -} - -static status_t remap_page(uint32 *free_pte, uint32 ra, uint32 bits) -{ - D(bug("Remapping PTE %p -> RA %p\n", free_pte, ra)); - - // Remap page - if (free_pte == NULL) { - D(bug(" Invalid PTE :-(\n")); - return B_BAD_ADDRESS; - } else { - free_pte[1] = ra | bits; - D(bug(" written %08lx %08lx to PTE\n", free_pte[0], free_pte[1])); - return B_NO_ERROR; - } -} - - -/* - * Foward declarations for hook functions - */ - -static status_t sheep_open(const char *name, uint32 flags, void **cookie); -static status_t sheep_close(void *cookie); -static status_t sheep_free(void *cookie); -static status_t sheep_control(void *cookie, uint32 op, void *data, size_t len); -static status_t sheep_read(void *cookie, off_t pos, void *data, size_t *len); -static status_t sheep_write(void *cookie, off_t pos, const void *data, size_t *len); - - -/* - * Version of our driver - */ - -int32 api_version = B_CUR_DRIVER_API_VERSION; - - -/* - * Device_hooks structure - has function pointers to the - * various entry points for device operations - */ - -static device_hooks my_device_hooks = { - &sheep_open, - &sheep_close, - &sheep_free, - &sheep_control, - &sheep_read, - &sheep_write, - NULL, - NULL, - NULL, - NULL -}; - - -/* - * List of device names to be returned by publish_devices() - */ - -static char *device_name_list[] = { - "sheep", - 0 -}; - - -/* - * Init - do nothing - */ - -status_t init_hardware(void) -{ -#if DEBUG==2 - set_dprintf_enabled(true); -#endif - D(bug("init_hardware()\n")); - return B_NO_ERROR; -} - -status_t init_driver(void) -{ - D(bug("init_driver()\n")); - return B_NO_ERROR; -} - -void uninit_driver(void) -{ - D(bug("uninit_driver()\n")); -} - - -/* - * publish_devices - return list of device names implemented by this driver - */ - -const char **publish_devices(void) -{ - return device_name_list; -} - - -/* - * find_device - return device hooks for a specific device name - */ - -device_hooks *find_device(const char *name) -{ - if (!strcmp(name, device_name_list[0])) - return &my_device_hooks; - - return NULL; -} - - -/* - * sheep_open - hook function for the open call. - */ - -static status_t sheep_open(const char *name, uint32 flags, void **cookie) -{ - return B_NO_ERROR; -} - - -/* - * sheep_close - hook function for the close call. - */ - -static status_t sheep_close(void *cookie) -{ - return B_NO_ERROR; -} - - -/* - * sheep_free - hook function to free the cookie returned - * by the open hook. Since the open hook did not return - * a cookie, this is a no-op. - */ - -static status_t sheep_free(void *cookie) -{ - return B_NO_ERROR; -} - - -/* - * sheep_control - hook function for the ioctl call - */ - -static asm void inval_tlb(uint32 ea) -{ - isync - tlbie r3 - sync - blr -} - -static asm void tlbsync(void) -{ - machine 604 - tlbsync - sync - blr -} - -static status_t sheep_control(void *cookie, uint32 op, void *data, size_t len) -{ - static void *block; - static void *block_aligned; - physical_entry pe[2]; - system_info sysinfo; - area_id id; - area_info info; - cpu_status cpu_st; - status_t res; - uint32 ra0, ra1; - uint32 *free_pte_0, *free_pte_1; - int i; - - D(bug("control(%d) data %p, len %08x\n", op, data, len)); - - switch (op) { - case SHEEP_UP: - - // Already messed up? Then do nothing now - if (find_port(PORT_NAME) != B_NAME_NOT_FOUND) - return B_NO_ERROR; - - // Get system info - get_system_info(&sysinfo); - - // Prepare replacement memory - block = malloc(B_PAGE_SIZE * 3); - D(bug("3 pages malloc()ed at %p\n", block)); - block_aligned = (void *)(((uint32)block + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE-1)); - D(bug("Address aligned to %p\n", block_aligned)); - res = lock_memory(block_aligned, B_PAGE_SIZE * 2, 0); - if (res < 0) - return res; - - // Get memory mapping - D(bug("Memory locked\n")); - res = get_memory_map(block_aligned, B_PAGE_SIZE * 2, pe, 2); - D(bug("get_memory_map returned %d\n", res)); - if (res != B_NO_ERROR) - return res; - - // Find PTE table area - id = find_area("pte_table"); - get_area_info(id, &info); - pte_address = (uint32 *)info.address; - D(bug("PTE table seems to be at %p\n", pte_address)); - table_size = info.size; - D(bug("PTE table size: %dKB\n", table_size / 1024)); - - // Disable interrupts - cpu_st = disable_interrupts(); - - // Find vsid and real addresses of replacement memory - for (i=0; i> 31),((pte_address[i*2]&0x7fffff80) >> 7), - ((pte_address[i*2]&0x00000040) >> 6),(pte_address[i*2] & 0x3f), - ((pte_address[i*2+1]&0xfffff000) >> 12),((pte_address[i*2+1]&0x00000100) >> 8), - ((pte_address[i*2+1]&0x00000080) >> 7),((pte_address[i*2+1]&0x00000078) >> 3), - (pte_address[i*2+1]&0x00000003))); - vsid = (pte_address[i*2]&0x7fffff80) >> 7; - ra0 = (uint32)pe[0].address & 0xfffff000; - } - if ((uint32)pe[0].size == B_PAGE_SIZE) { - if (((uint32)pe[1].address & 0xfffff000)==(pte_address[i*2+1]&0xfffff000)) { - D(bug("Found page 1f PtePos %04x V%x VSID %03x H%x API %02x RPN %03x R%1x C%1x WIMG%1x PP%1x \n", - i << 2, - ((pte_address[i*2]&0x80000000) >> 31), ((pte_address[i*2]&0x7fffff80) >> 7), - ((pte_address[i*2]&0x00000040) >> 6), (pte_address[i*2] & 0x3f), - ((pte_address[i*2+1]&0xfffff000) >> 12), ((pte_address[i*2+1]&0x00000100) >> 8), - ((pte_address[i*2+1]&0x00000080) >> 7), ((pte_address[i*2+1]&0x00000078) >> 3), - (pte_address[i*2+1]&0x00000003))); - ra1 = (uint32)pe[1].address & 0xfffff000; - } - } else { - if ((((uint32)pe[0].address + B_PAGE_SIZE) & 0xfffff000)==(pte_address[i*2+1]&0xfffff000)) { - D(bug("Found page 1d PtePos %04x V%x VSID %03x H%x API %02x RPN %03x R%1x C%1x WIMG%1x PP%1x \n", - i << 2, - ((pte_address[i*2]&0x80000000) >> 31), ((pte_address[i*2]&0x7fffff80) >> 7), - ((pte_address[i*2]&0x00000040) >> 6), (pte_address[i*2] & 0x3f), - ((pte_address[i*2+1]&0xfffff000) >> 12), ((pte_address[i*2+1]&0x00000100) >> 8), - ((pte_address[i*2+1]&0x00000080) >> 7), ((pte_address[i*2+1]&0x00000078) >> 3), - (pte_address[i*2+1]&0x00000003))); - ra1 = ((uint32)pe[0].address + B_PAGE_SIZE) & 0xfffff000; - } - } - } - - // Map low memory for emulator - free_pte_0 = NULL; - free_pte_1 = NULL; - __sync(); - __isync(); - inval_tlb(0); - inval_tlb(B_PAGE_SIZE); - if (sysinfo.cpu_type != B_CPU_PPC_603 && sysinfo.cpu_type != B_CPU_PPC_603e) - tlbsync(); - res = map_page(0, ra0, &free_pte_0, 0x12); - if (res == B_NO_ERROR) - res = map_page(B_PAGE_SIZE, ra1, &free_pte_1, 0x12); - inval_tlb(0); - inval_tlb(B_PAGE_SIZE); - if (sysinfo.cpu_type != B_CPU_PPC_603 && sysinfo.cpu_type != B_CPU_PPC_603e) - tlbsync(); - __sync(); - __isync(); - - // Restore interrupts - restore_interrupts(cpu_st); - - // Create port so we know that messing was successful - set_port_owner(create_port(1, PORT_NAME), B_SYSTEM_TEAM); - return B_NO_ERROR; - - case SHEEP_DOWN: - return B_NO_ERROR; - - default: - return B_BAD_VALUE; - } -} - - -/* - * sheep_read - hook function for the read call - */ - -static status_t sheep_read(void *cookie, off_t pos, void *data, size_t *len) -{ - void *rom_adr; - area_id area; - system_info info; - - D(bug("read() pos %Lx, data %p, len %08x\n", pos, data, *len)); - - get_system_info(&info); - if (info.platform_type == B_BEBOX_PLATFORM) { - *len = 0; - return B_ERROR; - } - if (*len != 0x400000 && pos != 0) { - *len = 0; - return B_BAD_VALUE; - } - area = map_physical_memory("mac_rom", (void *)0xff000000, 0x00400000, B_ANY_KERNEL_ADDRESS, B_READ_AREA, &rom_adr); - D(bug("Mapped ROM to %p, area id %d\n", rom_adr, area)); - if (area < 0) { - *len = 0; - return area; - } - D(bug("Copying ROM\n")); - memcpy(data, rom_adr, *len); - D(bug("Deleting area\n")); - delete_area(area); - return B_NO_ERROR; -} - - -/* - * sheep_write - hook function for the write call - */ - -static status_t sheep_write(void *cookie, off_t pos, const void *data, size_t *len) -{ - D(bug("write() pos %Lx, data %p, len %08x\n", pos, data, *len)); - return B_READ_ONLY_DEVICE; -} diff --git a/BasiliskII/src/BeOS/SheepDriver/sheep_driver.h b/BasiliskII/src/BeOS/SheepDriver/sheep_driver.h deleted file mode 100644 index 8486a021..00000000 --- a/BasiliskII/src/BeOS/SheepDriver/sheep_driver.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * sheep_driver.h - Low memory and ROM access driver for SheepShaver and - * Basilisk II on PowerPC systems - * - * SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SHEEP_DRIVER_H -#define SHEEP_DRIVER_H - -#include - -enum { - SHEEP_UP = B_DEVICE_OP_CODES_END + 1, - SHEEP_DOWN -}; - -#endif diff --git a/BasiliskII/src/BeOS/SheepNet/Makefile b/BasiliskII/src/BeOS/SheepNet/Makefile deleted file mode 100644 index 36b882fc..00000000 --- a/BasiliskII/src/BeOS/SheepNet/Makefile +++ /dev/null @@ -1,115 +0,0 @@ -## BeOS Generic Makefile v2.1 ## - -## Fill in this file to specify the project being created, and the referenced -## makefile-engine will do all of the hard work for you. This handles both -## Intel and PowerPC builds of the BeOS. - -## Application Specific Settings --------------------------------------------- - -# specify the name of the binary -NAME= sheep_net - -# specify the type of binary -# APP: Application -# SHARED: Shared library or add-on -# STATIC: Static library archive -# DRIVER: Kernel Driver -TYPE= SHARED - -# add support for new Pe and Eddie features -# to fill in generic makefile - -#%{ -# @src->@ - -# specify the source files to use -# full paths or paths relative to the makefile can be included -# all files, regardless of directory, will have their object -# files created in the common object directory. -# Note that this means this makefile will not work correctly -# if two source files with the same name (source.c or source.cpp) -# are included from different directories. Also note that spaces -# in folder names do not work well with this makefile. -SRCS= sheep_net.cpp - -# specify the resource files to use -# full path or a relative path to the resource file can be used. -RSRCS= - -# @<-src@ -#%} - -# end support for Pe and Eddie - -# specify additional libraries to link against -# there are two acceptable forms of library specifications -# - if your library follows the naming pattern of: -# libXXX.so or libXXX.a you can simply specify XXX -# library: libbe.so entry: be -# -# - if your library does not follow the standard library -# naming scheme you need to specify the path to the library -# and it's name -# library: my_lib.a entry: my_lib.a or path/my_lib.a -LIBS= netdev - -# specify additional paths to directories following the standard -# libXXX.so or libXXX.a naming scheme. You can specify full paths -# or paths relative to the makefile. The paths included may not -# be recursive, so include all of the paths where libraries can -# be found. Directories where source files are found are -# automatically included. -LIBPATHS= - -# additional paths to look for system headers -# thes use the form: #include
-# source file directories are NOT auto-included here -SYSTEM_INCLUDE_PATHS = - -# additional paths to look for local headers -# thes use the form: #include "header" -# source file directories are automatically included -LOCAL_INCLUDE_PATHS = - -# specify the level of optimization that you desire -# NONE, SOME, FULL -OPTIMIZE= FULL - -# specify any preprocessor symbols to be defined. The symbols will not -# have their values set automatically; you must supply the value (if any) -# to use. For example, setting DEFINES to "DEBUG=1" will cause the -# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" -# would pass "-DDEBUG" on the compiler's command line. -DEFINES= - -# specify special warning levels -# if unspecified default warnings will be used -# NONE = supress all warnings -# ALL = enable all warnings -WARNINGS = - -# specify whether image symbols will be created -# so that stack crawls in the debugger are meaningful -# if TRUE symbols will be created -SYMBOLS = - -# specify debug settings -# if TRUE will allow application to be run from a source-level -# debugger. Note that this will disable all optimzation. -DEBUGGER = - -# specify additional compiler flags for all files -COMPILER_FLAGS = - -# specify additional linker flags -LINKER_FLAGS = - - -## include the makefile-engine -include /boot/develop/etc/makefile-engine - -install: $(TARGET) - cp $(TARGET) /boot/beos/system/add-ons/net_server/$(NAME) - -uninstall: - rm /boot/beos/system/add-ons/net_server/$(NAME) diff --git a/BasiliskII/src/BeOS/SheepNet/sheep_net.cpp b/BasiliskII/src/BeOS/SheepNet/sheep_net.cpp deleted file mode 100644 index c026293c..00000000 --- a/BasiliskII/src/BeOS/SheepNet/sheep_net.cpp +++ /dev/null @@ -1,294 +0,0 @@ -/* - * sheep_net.cpp - Net server add-on for SheepShaver and Basilisk II - * - * SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sheep_net.h" - -#define DEBUG 0 - -#if DEBUG==1 -#define bug pprintf -#elif DEBUG==2 -#define bug kprintf -#endif - -#if DEBUG -#define D(x) (x) -#else -#define D(x) ; -#endif - -static int pprintf(const char* format, ...) -{ - port_id PortNum; - int len,Ret; - char Buffer[1024]; - va_list ap; - - if ((PortNum = find_port("PortLogger")) == B_NAME_NOT_FOUND) - return(PortNum); - for (len=0; len<1024; len++) - Buffer[len]='\0'; - va_start(ap, format); - vsprintf(Buffer, format, ap); - Ret = write_port(PortNum, 0, Buffer, strlen(Buffer)); - return(Ret); -} - - -// Constants -#define NETDUMP_PRIO 1 // Default is 0 - -const uint32 buffer_size = (sizeof(net_buffer) / B_PAGE_SIZE + 1) * B_PAGE_SIZE; - - -// SheepNet add-on object -class SheepNetAddOn : public BNetProtocol, BPacketHandler { -public: - void AddDevice(BNetDevice *dev, const char *name); - bool PacketReceived(BNetPacket *buf, BNetDevice *dev); -}; - - -// Global variables -static bool shutdown_now = false; -static bool active = false; - -static thread_id write_thread; // Packet writer -static sem_id write_sem; // Semaphore to trigger packet writing -static BNetDevice *EtherCard = NULL; // The Ethernet card we are attached to -static area_id buffer_area; // Packet buffer area -static net_buffer *net_buffer_ptr; // Pointer to packet buffer - -static uint32 rd_pos; // Current read position in packet buffer -static uint32 wr_pos; // Current write position in packet buffer - - -/* - * Clear packet buffer - */ - -static void clear(void) -{ - int i; - for (i=0;iread[i].cmd = 0; - net_buffer_ptr->read[i].length = 0; - net_buffer_ptr->read[i].card = 0; - net_buffer_ptr->read[i].reserved = 0; - } - for (i=0;iwrite[i].cmd = 0; - net_buffer_ptr->write[i].length = 0; - net_buffer_ptr->write[i].card = 0; - net_buffer_ptr->write[i].reserved = 0; - } - rd_pos = wr_pos = 0; -} - - -/* - * Packet writer thread - */ - -static status_t write_packet_func(void *arg) -{ - while (!shutdown_now) { - - // Read and execute command - net_packet *p = &net_buffer_ptr->write[wr_pos]; - while (p->cmd & IN_USE) { - D(bug("wp: %d\n", wr_pos)); - switch (p->cmd >> 8) { - - case ACTIVATE_SHEEP_NET: - D(bug("activate sheep-net\n")); - active = false; - clear(); - active = true; - goto next; - - case DEACTIVATE_SHEEP_NET: - D(bug("deactivate sheep-net\n")); - active = false; - clear(); - goto next; - - case SHUTDOWN_SHEEP_NET: - D(bug("shutdown sheep-net\n")); - active = false; - clear(); - shutdown_now = true; - goto next; - - case ADD_MULTICAST: { - const char *data = (const char *)p->data; - D(bug("add multicast %02x %02x %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3], data[4], data[5])); - if (active) { - status_t result; - if ((result = EtherCard->AddMulticastAddress(data)) != B_OK) { - // !! handle error !! error while creating multicast address - D(bug("error while creating multicast address %d\n", result)); - } - } - break; - } - - case REMOVE_MULTICAST: { - const char *data = (const char *)p->data; - D(bug("remove multicast %02x %02x %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3], data[4], data[5])); - if (active) { - status_t result; - if ((result = EtherCard->RemoveMulticastAddress(data)) != B_OK) { - // !! handle error !! error while removing multicast address - D(bug("error while removing multicast address %d\n", result)); - } - } - break; - } - - case SHEEP_PACKET: { - uint32 length = p->length; - // D(bug("sheep packet %d\n", length)); - if (active) { - BStandardPacket *packet = new BStandardPacket(length); - packet->Write(0, (const char *)p->data, length); - EtherCard->SendPacket(packet); - } - break; - } - - default: - D(bug("error: unknown port packet type\n")); - break; - } - p->cmd = 0; // Free packet - wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT; - p = &net_buffer_ptr->write[wr_pos]; - } - - // Wait for next packet -next: acquire_sem_etc(write_sem, 1, B_TIMEOUT, 25000); - } - return 0; -} - - -/* - * Init the net add-on - */ - -static void init_addon() -{ - int i; - D(bug("init sheep-net\n")); - - // Create packet buffer - if ((buffer_area = create_area("packet buffer", (void **)&net_buffer_ptr, B_ANY_ADDRESS, buffer_size, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA)) < B_NO_ERROR) { - D(bug("FATAL ERROR: can't create shared area\n")); - return; - } - - // Init packet buffer - clear(); - EtherCard->Address((char *)net_buffer_ptr->ether_addr); - net_buffer_ptr->read_sem = -1; - net_buffer_ptr->read_ofs = (uint32)(net_buffer_ptr->read) - (uint32)net_buffer_ptr; - net_buffer_ptr->read_packet_size = sizeof(net_packet); - net_buffer_ptr->read_packet_count = READ_PACKET_COUNT; - if ((write_sem = create_sem(0, "ether write")) < B_NO_ERROR) { - D(bug("FATAL ERROR: can't create semaphore\n")); - return; - } - net_buffer_ptr->write_sem = write_sem; - net_buffer_ptr->write_ofs = (uint32)(net_buffer_ptr->write) - (uint32)net_buffer_ptr; - net_buffer_ptr->write_packet_size = sizeof(net_packet); - net_buffer_ptr->write_packet_count = WRITE_PACKET_COUNT; - - // Start packet writer thread - write_thread = spawn_thread(write_packet_func, "sheep_net ether write", B_URGENT_DISPLAY_PRIORITY, NULL); - resume_thread(write_thread); -} - - -/* - * Add-on attached to Ethernet card - */ - -void SheepNetAddOn::AddDevice(BNetDevice *dev, const char *name) -{ - if (dev->Type() != B_ETHER_NET_DEVICE) - return; - if (EtherCard != NULL) { - // !! handle error !! support for multiple ethernet cards ... - D(bug("error: SheepShaver doesn't support multiple Ethernetcards !\n")); - return; - } - EtherCard = dev; - init_addon(); - register_packet_handler(this, dev, NETDUMP_PRIO); -} - - -/* - * Ethernet packet received - */ - -bool SheepNetAddOn::PacketReceived(BNetPacket *pkt, BNetDevice *dev) -{ - if (shutdown_now) { - unregister_packet_handler(this, dev); - return false; - } -// D(bug("read_packet_func %d\n", pkt->Size())); - if (active) { - D(bug("rp: %d\n", rd_pos)); - net_packet *p = &net_buffer_ptr->read[rd_pos]; - if (p->cmd & IN_USE) { - D(bug("error: full read buffer ... lost packet\n")); - } else { - memcpy(p->data, pkt->Data(), pkt->Size()); - p->length = pkt->Size(); - p->cmd = IN_USE | (SHEEP_PACKET << 8); - rd_pos = (rd_pos + 1) % READ_PACKET_COUNT; - release_sem(net_buffer_ptr->read_sem); - } - } - //D(bug("%02x %02x %02x %02x %02x %02x", (uchar) (pkt->Data())[0],(uchar) (pkt->Data())[1],(uchar) (pkt->Data())[2],(uchar) (pkt->Data())[3],(uchar) (pkt->Data())[4],(uchar) (pkt->Data())[5])); - return false; -} - -#pragma export on -extern "C" BNetProtocol *open_protocol(const char *device) -{ - SheepNetAddOn *dev = new SheepNetAddOn; - return dev; -} -#pragma export off diff --git a/BasiliskII/src/BeOS/SheepNet/sheep_net.h b/BasiliskII/src/BeOS/SheepNet/sheep_net.h deleted file mode 100644 index d4585b4d..00000000 --- a/BasiliskII/src/BeOS/SheepNet/sheep_net.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * sheep_net.h - Net server add-on for SheepShaver and Basilisk II - * - * SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SHEEP_NET_H -#define SHEEP_NET_H - -// Net buffer dimensions -#define READ_PACKET_COUNT 10 -#define WRITE_PACKET_COUNT 10 - -// Net packet -struct net_packet { - uint32 cmd; // Command - uint32 length; // Data length - uint32 card; // Network card ID - uint32 reserved; - uint8 data[1584]; -}; - -// Net buffer (shared area) -struct net_buffer { - uint8 ether_addr[6]; // Ethernet address - uint8 filler1[2]; - sem_id read_sem; // Semaphore for read packets - uint32 read_ofs; - uint32 read_packet_size; - uint32 read_packet_count; - sem_id write_sem; // Semaphore for write packets - uint32 write_ofs; - uint32 write_packet_size; - uint32 write_packet_count; - uint8 filler[24]; - net_packet read[READ_PACKET_COUNT]; - net_packet write[WRITE_PACKET_COUNT]; -}; - -// Packet commands -#define SHEEP_PACKET 0 -#define ADD_MULTICAST 1 -#define REMOVE_MULTICAST 2 -#define ACTIVATE_SHEEP_NET 8 -#define DEACTIVATE_SHEEP_NET 9 -#define SHUTDOWN_SHEEP_NET 10 - -#define IN_USE 1 - -#endif diff --git a/BasiliskII/src/BeOS/about_window.cpp b/BasiliskII/src/BeOS/about_window.cpp deleted file mode 100644 index 94f9944e..00000000 --- a/BasiliskII/src/BeOS/about_window.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * about_window.cpp - "About" window - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include "sysdeps.h" -#include "version.h" -#include "user_strings.h" - -/* - * Display "About" window - */ - -void ShowAboutWindow(void) -{ - char str[512]; - sprintf(str, - "Basilisk II\nVersion %d.%d\n\n" - "Copyright " B_UTF8_COPYRIGHT " 1997-2008 Christian Bauer et al.\n" - "E-mail: Christian.Bauer@uni-mainz.de\n" - "http://www.uni-mainz.de/~bauec002/B2Main.html\n\n" - "Basilisk II comes with ABSOLUTELY NO\n" - "WARRANTY. This is free software, and\n" - "you are welcome to redistribute it\n" - "under the terms of the GNU General\n" - "Public License.\n", - VERSION_MAJOR, VERSION_MINOR - ); - BAlert *about = new BAlert("", str, GetString(STR_OK_BUTTON), NULL, NULL, B_WIDTH_FROM_LABEL); - BTextView *theText = about->TextView(); - if (theText) { - theText->SetStylable(true); - theText->Select(0, 11); - BFont ourFont; - theText->SetFontAndColor(be_bold_font); - theText->GetFontAndColor(2, &ourFont, NULL); - ourFont.SetSize(24); - theText->SetFontAndColor(&ourFont); - } - about->Go(); -} diff --git a/BasiliskII/src/BeOS/about_window.h b/BasiliskII/src/BeOS/about_window.h deleted file mode 100644 index 1960c976..00000000 --- a/BasiliskII/src/BeOS/about_window.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * about_window.h - "About" window - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef ABOUT_WINDOW_H -#define ABOUT_WINDOW_H - -// Display "About" window -extern void ShowAboutWindow(void); - -#endif diff --git a/BasiliskII/src/BeOS/audio_beos.cpp b/BasiliskII/src/BeOS/audio_beos.cpp deleted file mode 100644 index 02654587..00000000 --- a/BasiliskII/src/BeOS/audio_beos.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* - * audio_beos.cpp - Audio support, BeOS implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * Portions written by Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "audio.h" -#include "audio_defs.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static int audio_irq_done_sem = -1; // Signal from interrupt to streaming thread: data block read -static BSoundPlayer *the_player; - -// Prototypes -static void playbuffer_func(void *arg, void *buf, size_t size, const media_raw_audio_format &format); - - -/* - * Audio manager thread (for calling media kit functions; - * this is not safe under R4 when running on the MacOS stack in kernel space) - */ - -// Message constants -const uint32 MSG_QUIT_AUDIO_MANAGER = 'quit'; -const uint32 MSG_ENTER_STREAM = 'entr'; -const uint32 MSG_EXIT_STREAM = 'exit'; -const uint32 MSG_GET_VOLUME = 'getv'; -const uint32 MSG_SET_VOLUME = 'setv'; - -static thread_id am_thread = -1; -static sem_id am_done_sem = -1; - -static volatile float am_volume; - -static status_t audio_manager(void *arg) -{ - for (;;) { - - // Receive message - thread_id sender; - uint32 code = receive_data(&sender, NULL, 0); - D(bug("Audio manager received %08lx\n", code)); - switch (code) { - case MSG_QUIT_AUDIO_MANAGER: - return 0; - - case MSG_ENTER_STREAM: - the_player->Start(); - break; - - case MSG_EXIT_STREAM: - the_player->Stop(); - break; - - case MSG_GET_VOLUME: - am_volume = the_player->Volume(); - break; - - case MSG_SET_VOLUME: - the_player->SetVolume(am_volume); - break; - } - - // Acknowledge - release_sem(am_done_sem); - } -} - - -/* - * Initialization - */ - -// Set AudioStatus to reflect current audio stream format -static void set_audio_status_format(void) -{ - AudioStatus.sample_rate = audio_sample_rates[0]; - AudioStatus.sample_size = audio_sample_sizes[0]; - AudioStatus.channels = audio_channel_counts[0]; -} - -void AudioInit(void) -{ - // Init audio status and feature flags - audio_sample_rates.push_back(44100 << 16); - audio_sample_sizes.push_back(16); - audio_channel_counts.push_back(2); - set_audio_status_format(); - AudioStatus.mixer = 0; - AudioStatus.num_sources = 0; - audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; - - // Sound disabled in prefs? Then do nothing - if (PrefsFindBool("nosound")) - return; - - // Init semaphores - audio_irq_done_sem = create_sem(0, "Audio IRQ Done"); - am_done_sem = create_sem(0, "Audio Manager Done"); - - // Start audio manager thread - am_thread = spawn_thread(audio_manager, "Audio Manager", B_NORMAL_PRIORITY, NULL); - resume_thread(am_thread); - - // Start stream - media_raw_audio_format format; - format.frame_rate = AudioStatus.sample_rate >> 16; - format.channel_count = AudioStatus.channels; - format.format = media_raw_audio_format::B_AUDIO_SHORT; - format.byte_order = B_MEDIA_BIG_ENDIAN; - audio_frames_per_block = 4096; - size_t block_size = (AudioStatus.sample_size >> 3) * AudioStatus.channels * audio_frames_per_block; - D(bug("AudioInit: block size %d\n", block_size)); - format.buffer_size = block_size; - the_player = new BSoundPlayer(&format, "MacOS Audio", playbuffer_func, NULL, NULL); - if (the_player->InitCheck() != B_NO_ERROR) { - printf("FATAL: Cannot initialize BSoundPlayer\n"); - delete the_player; - the_player = NULL; - return; - } else - the_player->SetHasData(true); - - // Everything OK - audio_open = true; -} - - -/* - * Deinitialization - */ - -void AudioExit(void) -{ - // Stop stream - if (the_player) { - the_player->Stop(); - delete the_player; - the_player = NULL; - } - - // Stop audio manager - if (am_thread > 0) { - status_t l; - send_data(am_thread, MSG_QUIT_AUDIO_MANAGER, NULL, 0); - wait_for_thread(am_thread, &l); - } - - // Delete semaphores - delete_sem(am_done_sem); - delete_sem(audio_irq_done_sem); -} - - -/* - * First source added, start audio stream - */ - -void audio_enter_stream() -{ - while (send_data(am_thread, MSG_ENTER_STREAM, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(am_done_sem) == B_INTERRUPTED) ; -} - - -/* - * Last source removed, stop audio stream - */ - -void audio_exit_stream() -{ - while (send_data(am_thread, MSG_EXIT_STREAM, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(am_done_sem) == B_INTERRUPTED) ; -} - - -/* - * Streaming function - */ - -static uint32 apple_stream_info; // Mac address of SoundComponentData struct describing next buffer - -static void playbuffer_func(void *arg, void *buf, size_t size, const media_raw_audio_format &format) -{ - // Check if new buffer is available - if (acquire_sem_etc(audio_irq_done_sem, 1, B_TIMEOUT, 0) == B_NO_ERROR) { - - // Get size of audio data - D(bug("stream: new buffer present\n")); - uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (apple_stream_info) { - size_t work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels; - D(bug("stream: size %d, work_size %d\n", size, work_size)); - if (work_size > size) - work_size = size; - - if (format.format != media_raw_audio_format::B_AUDIO_SHORT) { - D(bug("Wrong audio format %04x\n", format.format)); - return; - } - - // Place data into Media Kit buffer - Mac2Host_memcpy(buf, ReadMacInt32(apple_stream_info + scd_buffer), work_size); - if (work_size != size) - memset((uint8 *)buf + work_size, 0, size - work_size); - } - - } else - memset(buf, 0, size); - - // Trigger audio interrupt to get new buffer - if (AudioStatus.num_sources) { - D(bug("stream: triggering irq\n")); - SetInterruptFlag(INTFLAG_AUDIO); - TriggerInterrupt(); - } -} - - -/* - * MacOS audio interrupt, read next data block - */ - -void AudioInterrupt(void) -{ - D(bug("AudioInterrupt\n")); - - // Get data from apple mixer - if (AudioStatus.mixer) { - M68kRegisters r; - r.a[0] = audio_data + adatStreamInfo; - r.a[1] = AudioStatus.mixer; - Execute68k(audio_data + adatGetSourceData, &r); - D(bug(" GetSourceData() returns %08lx\n", r.d[0])); - } else - WriteMacInt32(audio_data + adatStreamInfo, 0); - - // Signal stream function - release_sem(audio_irq_done_sem); - D(bug("AudioInterrupt done\n")); -} - - -/* - * Set sampling parameters - * "index" is an index into the audio_sample_rates[] etc. arrays - * It is guaranteed that AudioStatus.num_sources == 0 - */ - -bool audio_set_sample_rate(int index) -{ - return true; -} - -bool audio_set_sample_size(int index) -{ - return true; -} - -bool audio_set_channels(int index) -{ - return true; -} - - -/* - * Get/set audio info - */ - -bool audio_get_main_mute(void) -{ - return false; -} - -uint32 audio_get_main_volume(void) -{ - if (audio_open) { - while (send_data(am_thread, MSG_GET_VOLUME, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(am_done_sem) == B_INTERRUPTED) ; - return int(am_volume * 256.0) * 0x00010001; - } else - return 0x01000100; -} - -bool audio_get_speaker_mute(void) -{ - return false; -} - -uint32 audio_get_speaker_volume(void) -{ - return 0x01000100; -} - -void audio_set_main_mute(bool mute) -{ -} - -void audio_set_main_volume(uint32 vol) -{ - if (audio_open) { - am_volume = float((vol >> 16) + (vol & 0xffff)) / 512.0; - while (send_data(am_thread, MSG_SET_VOLUME, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(am_done_sem) == B_INTERRUPTED) ; - } -} - -void audio_set_speaker_mute(bool mute) -{ -} - -void audio_set_speaker_volume(uint32 vol) -{ -} diff --git a/BasiliskII/src/BeOS/clip_beos.cpp b/BasiliskII/src/BeOS/clip_beos.cpp deleted file mode 100644 index 10159ec6..00000000 --- a/BasiliskII/src/BeOS/clip_beos.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * clip_beos.cpp - Clipboard handling, BeOS implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include - -#include "clip.h" -#include "prefs.h" - -#define DEBUG 1 -#include "debug.h" - - -// Flag: Don't convert clipboard text -static bool no_clip_conversion; - - -/* - * Initialization - */ - -void ClipInit(void) -{ - no_clip_conversion = PrefsFindBool("noclipconversion"); -} - - -/* - * Deinitialization - */ - -void ClipExit(void) -{ -} - -/* - * Mac application zeroes clipboard - */ - -void ZeroScrap() -{ - -} - -/* - * Mac application reads clipboard - */ - -void GetScrap(void **handle, uint32 type, int32 offset) -{ - D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset)); -} - - -/* - * Mac application wrote to clipboard - */ - -void PutScrap(uint32 type, void *scrap, int32 length) -{ - D(bug("PutScrap type %08lx, data %08lx, length %ld\n", type, scrap, length)); - if (length <= 0) - return; - - switch (type) { - case 'TEXT': - D(bug(" clipping TEXT\n")); - if (be_clipboard->Lock()) { - be_clipboard->Clear(); - BMessage *clipper = be_clipboard->Data(); - - if (no_clip_conversion) { - - // Only convert CR->LF - char *buf = new char[length]; - for (int i=0; iAddData("text/plain", B_MIME_TYPE, buf, length); - be_clipboard->Commit(); - delete[] buf; - - } else { - - // Convert text from Mac charset to UTF-8 - int32 dest_length = length*3; - int32 state = 0; - char *buf = new char[dest_length]; - if (convert_to_utf8(B_MAC_ROMAN_CONVERSION, (char *)scrap, &length, buf, &dest_length, &state) == B_OK) { - for (int i=0; iAddData("text/plain", B_MIME_TYPE, buf, dest_length); - be_clipboard->Commit(); - } - delete[] buf; - } - be_clipboard->Unlock(); - } - break; - } -} diff --git a/BasiliskII/src/BeOS/ether_beos.cpp b/BasiliskII/src/BeOS/ether_beos.cpp deleted file mode 100644 index ebc85daa..00000000 --- a/BasiliskII/src/BeOS/ether_beos.cpp +++ /dev/null @@ -1,532 +0,0 @@ -/* - * ether_beos.cpp - Ethernet device driver, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * Portions written by Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef __HAIKU__ -#include -#include -#endif - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "macos_util.h" -#include "ether.h" -#include "ether_defs.h" - -#include "sheep_net.h" - -#define DEBUG 0 -#include "debug.h" - -#define MONITOR 0 - - -// List of attached protocols -struct NetProtocol { - uint16 type; - uint32 handler; -}; - -static BList prot_list; - - -// Global variables -static thread_id read_thread; // Packet reception thread -static bool ether_thread_active = true; // Flag for quitting the reception thread - -static area_id buffer_area; // Packet buffer area -static net_buffer *net_buffer_ptr; // Pointer to packet buffer -static uint32 rd_pos; // Current read position in packet buffer -static uint32 wr_pos; // Current write position in packet buffer -static sem_id read_sem, write_sem; // Semaphores to trigger packet reading/writing - -static int fd = -1; // UDP socket fd -static bool udp_tunnel = false; - - -// Prototypes -static status_t receive_proc(void *data); - - -/* - * Find protocol in list - */ - -static NetProtocol *find_protocol(uint16 type) -{ - // All 802.2 types are the same - if (type <= 1500) - type = 0; - - // Search list (we could use hashing here but there are usually only three - // handlers installed: 0x0000 for AppleTalk and 0x0800/0x0806 for TCP/IP) - NetProtocol *p; - for (int i=0; (p = (NetProtocol *)prot_list.ItemAt(i)) != NULL; i++) - if (p->type == type) - return p; - return NULL; -} - - -/* - * Remove all protocols - */ - -static void remove_all_protocols(void) -{ - NetProtocol *p; - while ((p = (NetProtocol *)prot_list.RemoveItem((long)0)) != NULL) - delete p; -} - - -/* - * Initialization - */ - -bool ether_init(void) -{ - // Do nothing if no Ethernet device specified - if (PrefsFindString("ether") == NULL) - return false; - - // Find net_server team -i_wanna_try_that_again: - bool found_add_on = false; - team_info t_info; - int32 t_cookie = 0; - image_info i_info; - int32 i_cookie = 0; - while (get_next_team_info(&t_cookie, &t_info) == B_NO_ERROR) { - if (strstr(t_info.args,"net_server")!=NULL) { - - // Check if sheep_net add-on is loaded - while (get_next_image_info(t_info.team, &i_cookie, &i_info) == B_NO_ERROR) { - if (strstr(i_info.name, "sheep_net") != NULL) { - found_add_on = true; - break; - } - } - } - if (found_add_on) break; - } - if (!found_add_on) { - - // Search for sheep_net in network config file - char str[1024]; - bool sheep_net_found = false; - FILE *fin = fopen("/boot/home/config/settings/network", "r"); - while (!feof(fin)) { - fgets(str, 1024, fin); - if (strstr(str, "PROTOCOLS")) - if (strstr(str, "sheep_net")) - sheep_net_found = true; - } - fclose(fin); - - // It was found, so something else must be wrong - if (sheep_net_found) { - WarningAlert(GetString(STR_NO_NET_ADDON_WARN)); - return false; - } - - // Not found, inform the user - if (!ChoiceAlert(GetString(STR_NET_CONFIG_MODIFY_WARN), GetString(STR_OK_BUTTON), GetString(STR_CANCEL_BUTTON))) - return false; - - // Change the network config file and restart the network - fin = fopen("/boot/home/config/settings/network", "r"); - FILE *fout = fopen("/boot/home/config/settings/network.2", "w"); - bool global_found = false; - bool modified = false; - while (!feof(fin)) { - str[0] = 0; - fgets(str, 1024, fin); - if (!global_found && strstr(str, "GLOBAL:")) { - global_found = true; - } else if (global_found && !modified && strstr(str, "PROTOCOLS")) { - str[strlen(str)-1] = 0; - strcat(str, " sheep_net\n"); - modified = true; - } else if (global_found && !modified && strlen(str) > 2 && str[strlen(str) - 2] == ':') { - fputs("\tPROTOCOLS = sheep_net\n", fout); - modified = true; - } - fputs(str, fout); - } - if (!modified) - fputs("\tPROTOCOLS = sheep_net\n", fout); - fclose(fout); - fclose(fin); - remove("/boot/home/config/settings/network.orig"); - rename("/boot/home/config/settings/network", "/boot/home/config/settings/network.orig"); - rename("/boot/home/config/settings/network.2", "/boot/home/config/settings/network"); - - app_info ai; - if (be_roster->GetAppInfo("application/x-vnd.Be-NETS", &ai) == B_OK) { - BMessenger msg(NULL, ai.team); - if (msg.IsValid()) { - while (be_roster->IsRunning("application/x-vnd.Be-NETS")) { - msg.SendMessage(B_QUIT_REQUESTED); - snooze(500000); - } - } - } - BPath path; - find_directory(B_BEOS_BOOT_DIRECTORY, &path); - path.Append("Netscript"); - const char *argv[3] = {"/bin/sh", path.Path(), NULL}; - thread_id net_server = load_image(2, argv, (const char **)environ); - resume_thread(net_server); - status_t l; - wait_for_thread(net_server, &l); - goto i_wanna_try_that_again; - } - - // Set up communications with add-on - area_id handler_buffer; - if ((handler_buffer = find_area("packet buffer")) < B_NO_ERROR) { - WarningAlert(GetString(STR_NET_ADDON_INIT_FAILED)); - return false; - } - if ((buffer_area = clone_area("local packet buffer", (void **)&net_buffer_ptr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, handler_buffer)) < B_NO_ERROR) { - D(bug("EtherInit: couldn't clone packet area\n")); - WarningAlert(GetString(STR_NET_ADDON_CLONE_FAILED)); - return false; - } - if ((read_sem = create_sem(0, "ether read")) < B_NO_ERROR) { - printf("FATAL: can't create Ethernet semaphore\n"); - return false; - } - net_buffer_ptr->read_sem = read_sem; - write_sem = net_buffer_ptr->write_sem; - read_thread = spawn_thread(receive_proc, "Ethernet Receiver", B_URGENT_DISPLAY_PRIORITY, NULL); - resume_thread(read_thread); - for (int i=0; iwrite[i].cmd = IN_USE | (ACTIVATE_SHEEP_NET << 8); - rd_pos = wr_pos = 0; - release_sem(write_sem); - - // Get Ethernet address - memcpy(ether_addr, net_buffer_ptr->ether_addr, 6); - D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); - - // Everything OK - return true; -} - - -/* - * Deinitialization - */ - -void ether_exit(void) -{ - // Close communications with add-on - for (int i=0; iwrite[i].cmd = IN_USE | (DEACTIVATE_SHEEP_NET << 8); - release_sem(write_sem); - - // Quit reception thread - ether_thread_active = false; - status_t result; - release_sem(read_sem); - wait_for_thread(read_thread, &result); - - delete_sem(read_sem); - delete_area(buffer_area); - - // Remove all protocols - remove_all_protocols(); -} - - -/* - * Reset - */ - -void ether_reset(void) -{ - remove_all_protocols(); -} - - -/* - * Add multicast address - */ - -int16 ether_add_multicast(uint32 pb) -{ - net_packet *p = &net_buffer_ptr->write[wr_pos]; - if (p->cmd & IN_USE) { - D(bug("WARNING: Couldn't enable multicast address\n")); - } else { - Mac2Host_memcpy(p->data, pb + eMultiAddr, 6); - p->length = 6; - p->cmd = IN_USE | (ADD_MULTICAST << 8); - wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT; - release_sem(write_sem); - } - return noErr; -} - - -/* - * Delete multicast address - */ - -int16 ether_del_multicast(uint32 pb) -{ - net_packet *p = &net_buffer_ptr->write[wr_pos]; - if (p->cmd & IN_USE) { - D(bug("WARNING: Couldn't enable multicast address\n")); - } else { - Mac2Host_memcpy(p->data, pb + eMultiAddr, 6); - p->length = 6; - p->cmd = IN_USE | (REMOVE_MULTICAST << 8); - wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT; - release_sem(write_sem); - } - return noErr; -} - - -/* - * Attach protocol handler - */ - -int16 ether_attach_ph(uint16 type, uint32 handler) -{ - // Already attached? - NetProtocol *p = find_protocol(type); - if (p != NULL) - return lapProtErr; - else { - // No, create and attach - p = new NetProtocol; - p->type = type; - p->handler = handler; - prot_list.AddItem(p); - return noErr; - } -} - - -/* - * Detach protocol handler - */ - -int16 ether_detach_ph(uint16 type) -{ - NetProtocol *p = find_protocol(type); - if (p != NULL) { - prot_list.RemoveItem(p); - delete p; - return noErr; - } else - return lapProtErr; -} - - -/* - * Transmit raw ethernet packet - */ - -int16 ether_write(uint32 wds) -{ - net_packet *p = &net_buffer_ptr->write[wr_pos]; - if (p->cmd & IN_USE) { - D(bug("WARNING: Couldn't transmit packet (buffer full)\n")); - } else { - - // Copy packet to buffer - int len = ether_wds_to_buffer(wds, p->data); - -#if MONITOR - bug("Sending Ethernet packet:\n"); - for (int i=0; idata[i]); - } - bug("\n"); -#endif - - // Notify add-on - p->length = len; - p->cmd = IN_USE | (SHEEP_PACKET << 8); - wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT; - release_sem(write_sem); - } - return noErr; -} - - -/* - * Packet reception thread (non-UDP) - */ - -static status_t receive_proc(void *data) -{ - while (ether_thread_active) { - if (net_buffer_ptr->read[rd_pos].cmd & IN_USE) { - D(bug(" packet received, triggering Ethernet interrupt\n")); - SetInterruptFlag(INTFLAG_ETHER); - TriggerInterrupt(); - } - acquire_sem_etc(read_sem, 1, B_TIMEOUT, 25000); - } - return 0; -} - - -/* - * Packet reception thread (UDP) - */ - -static status_t receive_proc_udp(void *data) -{ - while (ether_thread_active) { - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - struct timeval timeout; - timeout.tv_sec = 1; - timeout.tv_usec = 0; - if (select(fd+1, &readfds, NULL, NULL, &timeout) > 0) { - D(bug(" packet received, triggering Ethernet interrupt\n")); - SetInterruptFlag(INTFLAG_ETHER); - TriggerInterrupt(); - } - } - return 0; -} - - -/* - * Start UDP packet reception thread - */ - -bool ether_start_udp_thread(int socket_fd) -{ - fd = socket_fd; - udp_tunnel = true; - ether_thread_active = true; - read_thread = spawn_thread(receive_proc_udp, "UDP Receiver", B_URGENT_DISPLAY_PRIORITY, NULL); - resume_thread(read_thread); - return true; -} - - -/* - * Stop UDP packet reception thread - */ - -void ether_stop_udp_thread(void) -{ - ether_thread_active = false; - status_t result; - wait_for_thread(read_thread, &result); -} - - -/* - * Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers - */ - -void EtherInterrupt(void) -{ - D(bug("EtherIRQ\n")); - EthernetPacket ether_packet; - uint32 packet = ether_packet.addr(); - - if (udp_tunnel) { - - ssize_t length; - - // Read packets from socket and hand to ether_udp_read() for processing - while (true) { - struct sockaddr_in from; - socklen_t from_len = sizeof(from); - length = recvfrom(fd, Mac2HostAddr(packet), 1514, 0, (struct sockaddr *)&from, &from_len); - if (length < 14) - break; - ether_udp_read(packet, length, &from); - } - - } else { - - // Call protocol handler for received packets - net_packet *p = &net_buffer_ptr->read[rd_pos]; - while (p->cmd & IN_USE) { - if ((p->cmd >> 8) == SHEEP_PACKET) { - Host2Mac_memcpy(packet, p->data, p->length); -#if MONITOR - bug("Receiving Ethernet packet:\n"); - for (int i=0; ilength; i++) { - bug("%02x ", ReadMacInt8(packet + i)); - } - bug("\n"); -#endif - // Get packet type - uint16 type = ReadMacInt16(packet + 12); - - // Look for protocol - NetProtocol *prot = find_protocol(type); - if (prot == NULL) - goto next; - - // No default handler - if (prot->handler == 0) - goto next; - - // Copy header to RHA - Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14); - D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12))); - - // Call protocol handler - M68kRegisters r; - r.d[0] = type; // Packet type - r.d[1] = p->length - 14; // Remaining packet length (without header, for ReadPacket) - r.a[0] = packet + 14; // Pointer to packet (Mac address, for ReadPacket) - r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA - r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines - D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4])); - Execute68k(prot->handler, &r); - } -next: p->cmd = 0; // Free packet - rd_pos = (rd_pos + 1) % READ_PACKET_COUNT; - p = &net_buffer_ptr->read[rd_pos]; - } - } - D(bug(" EtherIRQ done\n")); -} diff --git a/BasiliskII/src/BeOS/extfs_beos.cpp b/BasiliskII/src/BeOS/extfs_beos.cpp deleted file mode 100644 index 5b7ab4d6..00000000 --- a/BasiliskII/src/BeOS/extfs_beos.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/* - * extfs_beos.cpp - MacOS file system for access native file system access, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "extfs.h" -#include "extfs_defs.h" - -#define DEBUG 0 -#include "debug.h" - - -// Default Finder flags -const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited; - -// Temporary buffer for transfers from/to kernel space -const int TMP_BUF_SIZE = 0x10000; -static uint8 *tmp_buf = NULL; - - -/* - * Initialization - */ - -void extfs_init(void) -{ - // Allocate temporary buffer - tmp_buf = new uint8[TMP_BUF_SIZE]; -} - - -/* - * Deinitialization - */ - -void extfs_exit(void) -{ - // Delete temporary buffer - delete[] tmp_buf; -} - - -/* - * Add component to path name - */ - -void add_path_component(char *path, const char *component) -{ - int l = strlen(path); - if (l < MAX_PATH_LENGTH-1 && path[l-1] != '/') { - path[l] = '/'; - path[l+1] = 0; - } - strncat(path, component, MAX_PATH_LENGTH-1); -} - - -/* - * Get/set finder info for file/directory specified by full path - */ - -struct mime2type { - const char *mime; - uint32 type; - uint32 creator; - bool reversible; // type -> mime translation possible -}; - -static const mime2type m2t_translation[] = { - {"application/x-compress", 'ZIVM', 'LZIV', true}, - {"application/x-gzip", 'Gzip', 'Gzip', true}, - {"application/x-macbinary", 'BINA', '????', false}, - {"application/mac-binhex40", 'TEXT', 'SITx', false}, - {"application/pdf", 'PDF ', 'CARO', true}, - {"application/postscript", 'TEXT', 'ttxt', false}, - {"application/x-stuffit", 'SIT!', 'SITx', true}, - {"application/x-tar", 'TARF', 'TAR ', true}, - {"application/x-uuencode", 'TEXT', 'SITx', false}, - {"application/zip", 'ZIP ', 'ZIP ', true}, - {"audio/x-8svx", '8SVX', 'SNDM', true}, - {"audio/x-aifc", 'AIFC', 'TVOD', true}, - {"audio/x-aiff", 'AIFF', 'TVOD', true}, - {"audio/basic", 'ULAW', 'TVOD', true}, - {"audio/x-midi", 'MIDI', 'TVOD', true}, - {"audio/x-mpeg", 'MPG ', 'TVOD', true}, - {"audio/x-wav", 'WAVE', 'TVOD', true}, - {"image/x-bmp", 'BMPf', 'ogle', true}, - {"image/gif", 'GIFf', 'ogle', true}, - {"image/x-ilbm", 'ILBM', 'GKON', true}, - {"image/jpeg", 'JPEG', 'ogle', true}, - {"image/jpeg", 'JFIF', 'ogle', true}, - {"image/x-photoshop", '8BPS', '8BIM', true}, - {"image/pict", 'PICT', 'ogle', true}, - {"image/png", 'PNGf', 'ogle', true}, - {"image/x-sgi", '.SGI', 'ogle', true}, - {"image/x-targa", 'TPIC', 'ogle', true}, - {"image/tiff", 'TIFF', 'ogle', true}, - {"text/html", 'TEXT', 'MOSS', false}, - {"text/plain", 'TEXT', 'ttxt', true}, - {"text/rtf", 'TEXT', 'MSWD', false}, - {"text/x-source-code", 'TEXT', 'R*ch', false}, - {"video/mpeg", 'MPEG', 'TVOD', true}, - {"video/quicktime", 'MooV', 'TVOD', true}, - {"video/x-flc", 'FLI ', 'TVOD', true}, - {"video/x-msvideo", 'VfW ', 'TVOD', true}, - {NULL, 0, 0, false} // End marker -}; - -void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Set default finder info - Mac_memset(finfo, 0, SIZEOF_FInfo); - if (fxinfo) - Mac_memset(fxinfo, 0, SIZEOF_FXInfo); - WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS); - WriteMacInt32(finfo + fdLocation, (uint32)-1); - - // Open file - int fd = open(path, O_RDONLY); - if (fd < 0) - return; - - if (!is_dir) { - - // Read BeOS MIME type - ssize_t actual = fs_read_attr(fd, "BEOS:TYPE", B_MIME_STRING_TYPE, 0, tmp_buf, 256); - tmp_buf[255] = 0; - - if (actual > 0) { - - // Translate MIME type to MacOS type/creator - uint8 mactype[4]; - if (sscanf((char *)tmp_buf, "application/x-MacOS-%c%c%c%c", mactype, mactype+1, mactype+2, mactype+3) == 4) { - - // MacOS style type - WriteMacInt32(finfo + fdType, (mactype[0] << 24) | (mactype[1] << 16) | (mactype[2] << 8) | mactype[3]); - - } else { - - // MIME string, look in table - for (int i=0; m2t_translation[i].mime; i++) { - if (!strcmp((char *)tmp_buf, m2t_translation[i].mime)) { - WriteMacInt32(finfo + fdType, m2t_translation[i].type); - WriteMacInt32(finfo + fdCreator, m2t_translation[i].creator); - break; - } - } - } - } - - // Override file type with MACOS:CREATOR attribute - if (fs_read_attr(fd, "MACOS:CREATOR", B_UINT32_TYPE, 0, tmp_buf, 4) == 4) - WriteMacInt32(finfo + fdCreator, (tmp_buf[0] << 24) | (tmp_buf[1] << 16) | (tmp_buf[2] << 8) | tmp_buf[3]); - } - - // Read MACOS:HFS_FLAGS attribute - if (fs_read_attr(fd, "MACOS:HFS_FLAGS", B_UINT16_TYPE, 0, tmp_buf, 2) == 2) - WriteMacInt16(finfo + fdFlags, (tmp_buf[0] << 8) | tmp_buf[1]); - - // Close file - close(fd); -} - -void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Open file - int fd = open(path, O_WRONLY); - if (fd < 0) - return; - - if (!is_dir) { - - // Set BEOS:TYPE attribute - uint32 type = ReadMacInt32(finfo + fdType); - if (type) { - for (int i=0; m2t_translation[i].mime; i++) { - if (m2t_translation[i].type == type && m2t_translation[i].reversible) { - fs_write_attr(fd, "BEOS:TYPE", B_MIME_STRING_TYPE, 0, m2t_translation[i].mime, strlen(m2t_translation[i].mime) + 1); - break; - } - } - } - - // Set MACOS:CREATOR attribute - uint32 creator = ReadMacInt32(finfo + fdCreator); - if (creator) { - tmp_buf[0] = creator >> 24; - tmp_buf[1] = creator >> 16; - tmp_buf[2] = creator >> 8; - tmp_buf[3] = creator; - fs_write_attr(fd, "MACOS:CREATOR", B_UINT32_TYPE, 0, tmp_buf, 4); - } - } - - // Write MACOS:HFS_FLAGS attribute - uint16 flags = ReadMacInt16(finfo + fdFlags); - if (flags != DEFAULT_FINDER_FLAGS) { - tmp_buf[0] = flags >> 8; - tmp_buf[1] = flags; - fs_write_attr(fd, "MACOS:HFS_FLAGS", B_UINT16_TYPE, 0, tmp_buf, 2); - } else - fs_remove_attr(fd, "MACOS:HFS_FLAGS"); - - // Close file - close(fd); -} - - -/* - * Resource fork emulation functions - */ - -uint32 get_rfork_size(const char *path) -{ - // Open file - int fd = open(path, O_RDONLY); - if (fd < 0) - return 0; - - // Get size of MACOS:RFORK attribute - struct attr_info info; - if (fs_stat_attr(fd, "MACOS:RFORK", &info) < 0) - info.size = 0; - - // Close file and return size - close(fd); - return info.size; -} - -int open_rfork(const char *path, int flag) -{ - // Open original file - int fd = open(path, flag); - if (fd < 0) - return -1; - - // Open temporary file for resource fork - char rname[L_tmpnam]; - tmpnam(rname); - int rfd = open(rname, O_RDWR | O_CREAT | O_TRUNC, 0666); - if (rfd < 0) { - close(fd); - return -1; - } - unlink(rname); // File will be deleted when closed - - // Get size of MACOS:RFORK attribute - struct attr_info info; - if (fs_stat_attr(fd, "MACOS:RFORK", &info) < 0) - info.size = 0; - - // Copy resource data from attribute to temporary file - if (info.size > 0) { - - // Allocate buffer - void *buf = malloc(info.size); - if (buf == NULL) { - close(rfd); - close(fd); - return -1; - } - - // Copy data - fs_read_attr(fd, "MACOS:RFORK", B_RAW_TYPE, 0, buf, info.size); - write(rfd, buf, info.size); - lseek(rfd, 0, SEEK_SET); - - // Free buffer - if (buf) - free(buf); - } - - // Close original file - close(fd); - return rfd; -} - -void close_rfork(const char *path, int fd) -{ - if (fd < 0) - return; - - // Get size of temporary file - struct stat st; - if (fstat(fd, &st) < 0) - st.st_size = 0; - - // Open original file - int ofd = open(path, O_WRONLY); - if (ofd > 0) { - - // Copy resource data to MACOS:RFORK attribute - if (st.st_size > 0) { - - // Allocate buffer - void *buf = malloc(st.st_size); - if (buf == NULL) { - close(ofd); - close(fd); - return; - } - - // Copy data - lseek(fd, 0, SEEK_SET); - read(fd, buf, st.st_size); - fs_write_attr(ofd, "MACOS:RFORK", B_RAW_TYPE, 0, buf, st.st_size); - - // Free buffer - if (buf) - free(buf); - - } else - fs_remove_attr(ofd, "MACOS:RFORK"); - - // Close original file - close(ofd); - } - - // Close temporary file - close(fd); -} - - -/* - * Read "length" bytes from file to "buffer", - * returns number of bytes read (or -1 on error) - */ - -static inline ssize_t sread(int fd, void *buf, size_t count) -{ - ssize_t res; - while ((res = read(fd, buf, count)) == B_INTERRUPTED) ; - return res; -} - -ssize_t extfs_read(int fd, void *buffer, size_t length) -{ - // Buffer in kernel space? - if ((uint32)buffer < 0x80000000) { - - // Yes, transfer via buffer - ssize_t actual = 0; - while (length) { - size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - ssize_t res = sread(fd, tmp_buf, transfer_size); - if (res < 0) - return res; - memcpy(buffer, tmp_buf, res); - buffer = (void *)((uint8 *)buffer + res); - length -= res; - actual += res; - if (res != transfer_size) - return actual; - } - return actual; - - } else { - - // No, transfer directly - return sread(fd, buffer, length); - } -} - - -/* - * Write "length" bytes from "buffer" to file, - * returns number of bytes written (or -1 on error) - */ - -static inline ssize_t swrite(int fd, void *buf, size_t count) -{ - ssize_t res; - while ((res = write(fd, buf, count)) == B_INTERRUPTED) ; - return res; -} - -ssize_t extfs_write(int fd, void *buffer, size_t length) -{ - // Buffer in kernel space? - if ((uint32)buffer < 0x80000000) { - - // Yes, transfer via buffer - ssize_t actual = 0; - while (length) { - size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - memcpy(tmp_buf, buffer, transfer_size); - ssize_t res = swrite(fd, tmp_buf, transfer_size); - if (res < 0) - return res; - buffer = (void *)((uint8 *)buffer + res); - length -= res; - actual += res; - if (res != transfer_size) - return actual; - } - return actual; - - } else { - - // No, transfer directly - return swrite(fd, buffer, length); - } -} - - -/* - * Remove file/directory, returns false on error (and sets errno) - */ - -bool extfs_remove(const char *path) -{ - if (remove(path) < 0) { - if (errno == EISDIR) - return rmdir(path) == 0; - else - return false; - } - return true; -} - - -/* - * Rename/move file/directory, returns false on error (and sets errno) - */ - -bool extfs_rename(const char *old_path, const char *new_path) -{ - return rename(old_path, new_path) == 0; -} - -/* - * Strings (filenames) conversion - */ - -// Convert from the host OS filename encoding to MacRoman -const char *host_encoding_to_macroman(const char *filename) -{ - int32 state = 0; - static char buffer[512]; - int32 size = sizeof(buffer) - 1; - int32 insize = strlen(filename); - convert_from_utf8(B_MAC_ROMAN_CONVERSION, filename, &insize, buffer, &size, &state); - buffer[size] = 0; - return buffer; -} - -// Convert from MacRoman to host OS filename encoding -const char *macroman_to_host_encoding(const char *filename) -{ - int32 state = 0; - static char buffer[512]; - int32 insize = strlen(filename); - int32 size = sizeof(buffer) - 1; - convert_to_utf8(B_MAC_ROMAN_CONVERSION, filename, &insize, buffer, &size, &state); - buffer[size] = 0; - return buffer; -} diff --git a/BasiliskII/src/BeOS/main_beos.cpp b/BasiliskII/src/BeOS/main_beos.cpp deleted file mode 100644 index 507e3bde..00000000 --- a/BasiliskII/src/BeOS/main_beos.cpp +++ /dev/null @@ -1,826 +0,0 @@ -/* - * main_beos.cpp - Startup code for BeOS - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "xpram.h" -#include "timer.h" -#include "video.h" -#include "rom_patches.h" -#include "prefs.h" -#include "prefs_editor.h" -#include "sys.h" -#include "user_strings.h" -#include "version.h" -#include "main.h" - -#include "sheep_driver.h" - -#define DEBUG 0 -#include "debug.h" - - -// Constants -const char APP_SIGNATURE[] = "application/x-vnd.cebix-BasiliskII"; -const char ROM_FILE_NAME[] = "ROM"; -const char RAM_AREA_NAME[] = "Macintosh RAM"; -const char ROM_AREA_NAME[] = "Macintosh ROM"; -const uint32 MSG_START = 'strt'; // Emulator start message -const uint32 ROM_AREA_SIZE = 0x500000; // Enough to hold PowerMac ROM (for powerrom_cpu) - -// Prototypes -#if __POWERPC__ -static void sigsegv_handler(vregs *r); -#endif - - -// Application object -class BasiliskII : public BApplication { -public: - BasiliskII() : BApplication(APP_SIGNATURE) - { - // Find application directory and cwd to it - app_info the_info; - GetAppInfo(&the_info); - BEntry the_file(&the_info.ref); - BEntry the_dir; - the_file.GetParent(&the_dir); - BPath the_path; - the_dir.GetPath(&the_path); - chdir(the_path.Path()); - - // Initialize other variables - rom_area = ram_area = -1; - xpram_thread = tick_thread = -1; - xpram_thread_active = true; - tick_thread_active = true; - AllowQuitting = true; - } - virtual void ReadyToRun(void); - virtual void MessageReceived(BMessage *msg); - void StartEmulator(void); - virtual bool QuitRequested(void); - virtual void Quit(void); - - thread_id xpram_thread; // XPRAM watchdog - thread_id tick_thread; // 60Hz thread - - volatile bool xpram_thread_active; // Flag for quitting the XPRAM thread - volatile bool tick_thread_active; // Flag for quitting the 60Hz thread - - bool AllowQuitting; // Flag: Alt-Q quitting allowed - -private: - static status_t emul_func(void *arg); - static status_t tick_func(void *arg); - static status_t xpram_func(void *arg); - static void sigsegv_invoc(int sig, void *arg, vregs *r); - - void init_rom(void); - void load_rom(void); - - area_id rom_area; // ROM area ID - area_id ram_area; // RAM area ID - - struct sigaction sigsegv_action; // Data access exception signal (of emulator thread) - - // Exceptions - class area_error {}; - class file_open_error {}; - class file_read_error {}; - class rom_size_error {}; - - char* vmdir; -}; - -static BasiliskII *the_app; - - -// CPU and FPU type, addressing mode -int CPUType; -bool CPUIs68060; -int FPUType; -bool TwentyFourBitAddressing; - - -// Global variables for PowerROM CPU -thread_id emul_thread = -1; // Emulator thread - -#if __POWERPC__ -int sheep_fd = -1; // fd of sheep driver -#endif - - -/* - * Create application object and start it - */ - -int main(int argc, char **argv) -{ - the_app = new BasiliskII(); - the_app->Run(); - delete the_app; - return 0; -} - - -/* - * Run application - */ - -void BasiliskII::ReadyToRun(void) -{ - // Initialize variables - RAMBaseHost = NULL; - ROMBaseHost = NULL; - srand(real_time_clock()); - tzset(); - - // Print some info - printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - printf(" %s\n", GetString(STR_ABOUT_TEXT2)); - - // Delete old areas - area_id old_ram_area = find_area(RAM_AREA_NAME); - if (old_ram_area > 0) - delete_area(old_ram_area); - area_id old_rom_area = find_area(ROM_AREA_NAME); - if (old_rom_area > 0) - delete_area(old_rom_area); - - // Read preferences - int argc = 0; - char **argv = NULL; - PrefsInit(vmdir, argc, argv); - - // Init system routines - SysInit(); - - // Show preferences editor (or start emulator directly) - if (!PrefsFindBool("nogui")) - PrefsEditor(); - else - PostMessage(MSG_START); -} - - -/* - * Message received - */ - -void BasiliskII::MessageReceived(BMessage *msg) -{ - switch (msg->what) { - case MSG_START: - StartEmulator(); - break; - default: - BApplication::MessageReceived(msg); - } -} - - -/* - * Start emulator - */ - -void BasiliskII::StartEmulator(void) -{ - char str[256]; - -#if REAL_ADDRESSING - // Open sheep driver and remap low memory - sheep_fd = open("/dev/sheep", 0); - if (sheep_fd < 0) { - sprintf(str, GetString(STR_NO_SHEEP_DRIVER_ERR), strerror(sheep_fd), sheep_fd); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } - status_t res = ioctl(sheep_fd, SHEEP_UP); - if (res < 0) { - sprintf(str, GetString(STR_SHEEP_UP_ERR), strerror(res), res); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } -#endif - - // Create area for Mac RAM - RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary - if (RAMSize < 1024*1024) { - WarningAlert(GetString(STR_SMALL_RAM_WARN)); - RAMSize = 1024*1024; - } - - RAMBaseHost = (uint8 *)0x10000000; - ram_area = create_area(RAM_AREA_NAME, (void **)&RAMBaseHost, B_BASE_ADDRESS, RAMSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (ram_area < 0) { - ErrorAlert(STR_NO_RAM_AREA_ERR); - PostMessage(B_QUIT_REQUESTED); - return; - } - D(bug("RAM area %ld at %p\n", ram_area, RAMBaseHost)); - - // Create area and load Mac ROM - try { - init_rom(); - } catch (area_error) { - ErrorAlert(STR_NO_ROM_AREA_ERR); - PostMessage(B_QUIT_REQUESTED); - return; - } catch (file_open_error) { - ErrorAlert(STR_NO_ROM_FILE_ERR); - PostMessage(B_QUIT_REQUESTED); - return; - } catch (file_read_error) { - ErrorAlert(STR_ROM_FILE_READ_ERR); - PostMessage(B_QUIT_REQUESTED); - return; - } catch (rom_size_error) { - ErrorAlert(STR_ROM_SIZE_ERR); - PostMessage(B_QUIT_REQUESTED); - return; - } - - // Initialize everything - if (!InitAll(NULL)) { - PostMessage(B_QUIT_REQUESTED); - return; - } - - // Write protect ROM - set_area_protection(rom_area, B_READ_AREA); - - // Disallow quitting with Alt-Q from now on - AllowQuitting = false; - - // Start XPRAM watchdog thread - xpram_thread = spawn_thread(xpram_func, "XPRAM Watchdog", B_LOW_PRIORITY, this); - resume_thread(xpram_thread); - - // Start 60Hz interrupt - tick_thread = spawn_thread(tick_func, "60Hz", B_REAL_TIME_PRIORITY, this); - resume_thread(tick_thread); - - // Start emulator thread - emul_thread = spawn_thread(emul_func, "MacOS", B_NORMAL_PRIORITY, this); - resume_thread(emul_thread); -} - - -/* - * Quit emulator - */ - -void QuitEmulator(void) -{ - the_app->AllowQuitting = true; - be_app->PostMessage(B_QUIT_REQUESTED); - exit_thread(0); -} - -bool BasiliskII::QuitRequested(void) -{ - if (AllowQuitting) - return BApplication::QuitRequested(); - else - return false; -} - -void BasiliskII::Quit(void) -{ - status_t l; - - // Stop 60Hz interrupt - if (tick_thread > 0) { - tick_thread_active = false; - wait_for_thread(tick_thread, &l); - } - - // Wait for emulator thread to finish - if (emul_thread > 0) - wait_for_thread(emul_thread, &l); - - // Exit 680x0 emulation - Exit680x0(); - - // Stop XPRAM watchdog thread - if (xpram_thread > 0) { - xpram_thread_active = false; - suspend_thread(xpram_thread); // Wake thread up from snooze() - snooze(1000); - resume_thread(xpram_thread); - wait_for_thread(xpram_thread, &l); - } - - // Deinitialize everything - ExitAll(); - - // Delete ROM area - if (rom_area >= 0) - delete_area(rom_area); - - // Delete RAM area - if (ram_area >= 0) - delete_area(ram_area); - -#if REAL_ADDRESSING - // Unmap low memory and close memory mess driver - if (sheep_fd >= 0) { - ioctl(sheep_fd, SHEEP_DOWN); - close(sheep_fd); - } -#endif - - // Exit system routines - SysExit(); - - // Exit preferences - PrefsExit(); - - BApplication::Quit(); -} - - -/* - * Create area for ROM (sets rom_area) and load ROM file - * - * area_error : Cannot create area - * file_open_error: Cannot open ROM file - * file_read_error: Cannot read ROM file - */ - -void BasiliskII::init_rom(void) -{ - // Create area for ROM - ROMBaseHost = (uint8 *)0x40800000; - rom_area = create_area(ROM_AREA_NAME, (void **)&ROMBaseHost, B_BASE_ADDRESS, ROM_AREA_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (rom_area < 0) - throw area_error(); - D(bug("ROM area %ld at %p\n", rom_area, ROMBaseHost)); - - // Load ROM - load_rom(); -} - - -/* - * Load ROM file - * - * file_open_error: Cannot open ROM file - * file_read_error: Cannot read ROM file - */ - -void BasiliskII::load_rom(void) -{ - // Get rom file path from preferences - const char *rom_path = PrefsFindString("rom"); - - // Try to open ROM file - BFile file(rom_path ? rom_path : ROM_FILE_NAME, B_READ_ONLY); - if (file.InitCheck() != B_NO_ERROR) - throw file_open_error(); - - printf(GetString(STR_READING_ROM_FILE)); - - // Is the ROM size correct? - off_t rom_size = 0; - file.GetSize(&rom_size); - if (rom_size != 64*1024 && rom_size != 128*1024 && rom_size != 256*1024 && rom_size != 512*1024 && rom_size != 1024*1024) - throw rom_size_error(); - - uint8 *rom = new uint8[rom_size]; // Reading directly into the area doesn't work - ssize_t actual = file.Read((void *)rom, rom_size); - if (actual == rom_size) - memcpy(ROMBaseHost, rom, rom_size); - delete[] rom; - if (actual != rom_size) - throw file_read_error(); - ROMSize = rom_size; -} - - -/* - * Emulator thread function - */ - -status_t BasiliskII::emul_func(void *arg) -{ - BasiliskII *obj = (BasiliskII *)arg; - -#if __POWERPC__ - // Install data access signal handler - sigemptyset(&obj->sigsegv_action.sa_mask); - obj->sigsegv_action.sa_handler = (__signal_func_ptr)(obj->sigsegv_invoc); - obj->sigsegv_action.sa_flags = 0; - obj->sigsegv_action.sa_userdata = arg; - sigaction(SIGSEGV, &obj->sigsegv_action, NULL); -#endif - - // Exceptions will send signals - disable_debugger(true); - - // Start 68k and jump to ROM boot routine - Start680x0(); - - // Quit program - obj->AllowQuitting = true; - be_app->PostMessage(B_QUIT_REQUESTED); - return 0; -} - - -/* - * Code was patched, flush caches if neccessary (i.e. when using a real 680x0 - * or a dynamically recompiling emulator) - */ - -void FlushCodeCache(void *start, uint32 size) -{ -} - - -/* - * Mutexes - */ - -struct B2_mutex { - int dummy; //!! -}; - -B2_mutex *B2_create_mutex(void) -{ - return new B2_mutex; -} - -void B2_lock_mutex(B2_mutex *mutex) -{ -} - -void B2_unlock_mutex(B2_mutex *mutex) -{ -} - -void B2_delete_mutex(B2_mutex *mutex) -{ - delete mutex; -} - - -/* - * Interrupt flags (must be handled atomically!) - */ - -uint32 InterruptFlags = 0; - -void SetInterruptFlag(uint32 flag) -{ - atomic_or((int32 *)&InterruptFlags, flag); -} - -void ClearInterruptFlag(uint32 flag) -{ - atomic_and((int32 *)&InterruptFlags, ~flag); -} - - -/* - * 60Hz thread (really 60.15Hz) - */ - -status_t BasiliskII::tick_func(void *arg) -{ - BasiliskII *obj = (BasiliskII *)arg; - int tick_counter = 0; - bigtime_t current = system_time(); - - while (obj->tick_thread_active) { - - // Wait - current += 16625; - snooze_until(current, B_SYSTEM_TIMEBASE); - - // Pseudo Mac 1Hz interrupt, update local time - if (++tick_counter > 60) { - tick_counter = 0; - WriteMacInt32(0x20c, TimerDateTime()); - SetInterruptFlag(INTFLAG_1HZ); - TriggerInterrupt(); - } - - // Trigger 60Hz interrupt - SetInterruptFlag(INTFLAG_60HZ); - TriggerInterrupt(); - } - return 0; -} - - -/* - * XPRAM watchdog thread (saves XPRAM every minute) - */ - -status_t BasiliskII::xpram_func(void *arg) -{ - uint8 last_xpram[XPRAM_SIZE]; - memcpy(last_xpram, XPRAM, XPRAM_SIZE); - - while (((BasiliskII *)arg)->xpram_thread_active) { - snooze(60*1000000); - if (memcmp(last_xpram, XPRAM, XPRAM_SIZE)) { - memcpy(last_xpram, XPRAM, XPRAM_SIZE); - SaveXPRAM(); - } - } - return 0; -} - - -/* - * Display error alert - */ - -void ErrorAlert(const char *text) -{ - if (PrefsFindBool("nogui")) { - printf(GetString(STR_SHELL_ERROR_PREFIX), text); - return; - } - VideoQuitFullScreen(); - char str[256]; - sprintf(str, GetString(STR_GUI_ERROR_PREFIX), text); - BAlert *alert = new BAlert(GetString(STR_ERROR_ALERT_TITLE), str, GetString(STR_QUIT_BUTTON), NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT); - alert->Go(); -} - - -/* - * Display warning alert - */ - -void WarningAlert(const char *text) -{ - if (PrefsFindBool("nogui")) { - printf(GetString(STR_SHELL_WARNING_PREFIX), text); - return; - } - char str[256]; - sprintf(str, GetString(STR_GUI_WARNING_PREFIX), text); - BAlert *alert = new BAlert(GetString(STR_WARNING_ALERT_TITLE), str, GetString(STR_OK_BUTTON), NULL, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT); - alert->Go(); -} - - -/* - * Display choice alert - */ - -bool ChoiceAlert(const char *text, const char *pos, const char *neg) -{ - char str[256]; - sprintf(str, GetString(STR_GUI_WARNING_PREFIX), text); - BAlert *alert = new BAlert(GetString(STR_WARNING_ALERT_TITLE), str, pos, neg, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT); - return alert->Go() == 0; -} - - -/* - * SEGV handler - */ - -#if __POWERPC__ -static uint32 segv_r[32]; - -asm void BasiliskII::sigsegv_invoc(register int sig, register void *arg, register vregs *r) -{ - mflr r0 - stw r0,8(r1) - stwu r1,-56(r1) - - lwz r3,segv_r(r2) - stmw r13,13*4(r3) - - mr r3,r5 - bl sigsegv_handler - - lwz r3,segv_r(r2) - lmw r13,13*4(r3) - - lwz r0,56+8(r1) - mtlr r0 - addi r1,r1,56 - blr -} - -static void sigsegv_handler(vregs *r) -{ - // Fetch volatile registers - segv_r[0] = r->r0; - segv_r[1] = r->r1; - segv_r[2] = r->r2; - segv_r[3] = r->r3; - segv_r[4] = r->r4; - segv_r[5] = r->r5; - segv_r[6] = r->r6; - segv_r[7] = r->r7; - segv_r[8] = r->r8; - segv_r[9] = r->r9; - segv_r[10] = r->r10; - segv_r[11] = r->r11; - segv_r[12] = r->r12; - - // Get opcode and divide into fields - uint32 opcode = *(uint32 *)r->pc; - uint32 primop = opcode >> 26; - uint32 exop = (opcode >> 1) & 0x3ff; - uint32 ra = (opcode >> 16) & 0x1f; - uint32 rb = (opcode >> 11) & 0x1f; - uint32 rd = (opcode >> 21) & 0x1f; - uint32 imm = opcode & 0xffff; - - // Analyze opcode - enum { - TYPE_UNKNOWN, - TYPE_LOAD, - TYPE_STORE - } transfer_type = TYPE_UNKNOWN; - enum { - SIZE_UNKNOWN, - SIZE_BYTE, - SIZE_HALFWORD, - SIZE_WORD - } transfer_size = SIZE_UNKNOWN; - enum { - MODE_UNKNOWN, - MODE_NORM, - MODE_U, - MODE_X, - MODE_UX - } addr_mode = MODE_UNKNOWN; - switch (primop) { - case 31: - switch (exop) { - case 23: // lwzx - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; - case 55: // lwzux - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; - case 87: // lbzx - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break; - case 119: // lbzux - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break; - case 151: // stwx - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; - case 183: // stwux - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; - case 215: // stbx - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break; - case 247: // stbux - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break; - case 279: // lhzx - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break; - case 311: // lhzux - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break; - case 343: // lhax - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break; - case 375: // lhaux - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break; - case 407: // sthx - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break; - case 439: // sthux - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break; - } - break; - - case 32: // lwz - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; - case 33: // lwzu - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; - case 34: // lbz - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break; - case 35: // lbzu - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break; - case 36: // stw - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; - case 37: // stwu - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; - case 38: // stb - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break; - case 39: // stbu - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break; - case 40: // lhz - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break; - case 41: // lhzu - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break; - case 42: // lha - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break; - case 43: // lhau - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break; - case 44: // sth - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break; - case 45: // sthu - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break; - } - - // Calculate effective address - uint32 addr = 0; - switch (addr_mode) { - case MODE_X: - case MODE_UX: - if (ra == 0) - addr = segv_r[rb]; - else - addr = segv_r[ra] + segv_r[rb]; - break; - case MODE_NORM: - case MODE_U: - if (ra == 0) - addr = (int32)(int16)imm; - else - addr = segv_r[ra] + (int32)(int16)imm; - break; - } - - // Ignore ROM writes - if (transfer_type == TYPE_STORE && addr >= (uint32)ROMBaseHost && addr < (uint32)ROMBaseHost + ROMSize) { -// D(bug("WARNING: %s write access to ROM at %p, 68k pc %p\n", transfer_size == SIZE_BYTE ? "Byte" : transfer_size == SIZE_HALFWORD ? "Halfword" : "Word", addr, r->pc)); - if (addr_mode == MODE_U || addr_mode == MODE_UX) - segv_r[ra] = addr; - r->pc += 4; - goto rti; - } - - // For all other errors, jump into debugger - char str[256]; - sprintf(str, "SIGSEGV\n" - " pc %08lx lr %08lx ctr %08lx msr %08lx\n" - " xer %08lx cr %08lx fpscr %08lx\n" - " r0 %08lx r1 %08lx r2 %08lx r3 %08lx\n" - " r4 %08lx r5 %08lx r6 %08lx r7 %08lx\n" - " r8 %08lx r9 %08lx r10 %08lx r11 %08lx\n" - " r12 %08lx r13 %08lx r14 %08lx r15 %08lx\n" - " r16 %08lx r17 %08lx r18 %08lx r19 %08lx\n" - " r20 %08lx r21 %08lx r22 %08lx r23 %08lx\n" - " r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n" - " r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n", - r->pc, r->lr, r->ctr, r->msr, - r->xer, r->cr, r->fpscr, - r->r0, r->r1, r->r2, r->r3, - r->r4, r->r5, r->r6, r->r7, - r->r8, r->r9, r->r10, r->r11, - r->r12, segv_r[13], segv_r[14], segv_r[15], - segv_r[16], segv_r[17], segv_r[18], segv_r[19], - segv_r[20], segv_r[21], segv_r[22], segv_r[23], - segv_r[24], segv_r[25], segv_r[26], segv_r[27], - segv_r[28], segv_r[29], segv_r[30], segv_r[31]); - disable_debugger(false); - debugger(str); - QuitEmulator(); - return; - -rti: - // Restore volatile registers - r->r0 = segv_r[0]; - r->r1 = segv_r[1]; - r->r2 = segv_r[2]; - r->r3 = segv_r[3]; - r->r4 = segv_r[4]; - r->r5 = segv_r[5]; - r->r6 = segv_r[6]; - r->r7 = segv_r[7]; - r->r8 = segv_r[8]; - r->r9 = segv_r[9]; - r->r10 = segv_r[10]; - r->r11 = segv_r[11]; - r->r12 = segv_r[12]; -} -#endif diff --git a/BasiliskII/src/BeOS/prefs_beos.cpp b/BasiliskII/src/BeOS/prefs_beos.cpp deleted file mode 100644 index 9a74d643..00000000 --- a/BasiliskII/src/BeOS/prefs_beos.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * prefs_beos.cpp - Preferences handling, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include "sysdeps.h" -#include "prefs.h" -#include "main.h" - - -// Platform-specific preferences items -prefs_desc platform_prefs_items[] = { - {"powerrom", TYPE_STRING, false, "path of PowerMac ROM"}, - {NULL, TYPE_END, false, NULL} // End of list -}; - - -// Preferences file name and path -const char PREFS_FILE_NAME[] = "BasiliskII_prefs"; -static BPath prefs_path; - - -/* - * Load preferences from settings file - */ - -void LoadPrefs(const char* vmdir) -{ -#if 0 - if (vmdir) { - prefs_path.SetTo(vmdir); - prefs_path.Append("prefs"); - FILE *prefs = fopen(prefs_path.Path(), "r"); - if (!prefs) { - printf("No file at %s found.\n", prefs_path.Path()); - exit(1); - } - LoadPrefsFromStream(prefs); - fclose(prefs); - return; - } -#endif - - // Construct prefs path - find_directory(B_USER_SETTINGS_DIRECTORY, &prefs_path, true); - prefs_path.Append(PREFS_FILE_NAME); - - // Read preferences from settings file - FILE *f = fopen(prefs_path.Path(), "r"); - if (f != NULL) { - - // Prefs file found, load settings - LoadPrefsFromStream(f); - fclose(f); - - } else { - - // No prefs file, save defaults - SavePrefs(); - } -} - - -/* - * Save preferences to settings file - */ - -void SavePrefs(void) -{ - FILE *f; - if ((f = fopen(prefs_path.Path(), "w")) != NULL) { - SavePrefsToStream(f); - fclose(f); - } -} - - -/* - * Add defaults of platform-specific prefs items - * You may also override the defaults set in PrefsInit() - */ - -void AddPlatformPrefsDefaults(void) -{ - PrefsReplaceString("extfs", "/boot"); -} diff --git a/BasiliskII/src/BeOS/prefs_editor_beos.cpp b/BasiliskII/src/BeOS/prefs_editor_beos.cpp deleted file mode 100644 index a40e4748..00000000 --- a/BasiliskII/src/BeOS/prefs_editor_beos.cpp +++ /dev/null @@ -1,1022 +0,0 @@ -/* - * prefs_editor_beos.cpp - Preferences editor, BeOS implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "main.h" -#include "cdrom.h" -#include "xpram.h" -#include "prefs.h" -#include "about_window.h" -#include "user_strings.h" -#include "prefs_editor.h" - - -// Special colors -const rgb_color fill_color = {216, 216, 216, 0}; -const rgb_color slider_fill_color = {102, 152, 255, 0}; - -// Display types -enum { - DISPLAY_WINDOW, - DISPLAY_SCREEN -}; - -// Window messages -const uint32 MSG_OK = 'okok'; // "Start" clicked -const uint32 MSG_CANCEL = 'cncl'; // "Quit" clicked -const uint32 MSG_ZAP_PRAM = 'zprm'; - -const int NUM_PANES = 4; - -const uint32 MSG_VOLUME_SELECTED = 'volu'; // "Volumes" pane -const uint32 MSG_VOLUME_INVOKED = 'voli'; -const uint32 MSG_ADD_VOLUME = 'addv'; -const uint32 MSG_CREATE_VOLUME = 'crev'; -const uint32 MSG_REMOVE_VOLUME = 'remv'; -const uint32 MSG_ADD_VOLUME_PANEL = 'advp'; -const uint32 MSG_CREATE_VOLUME_PANEL = 'crvp'; -const uint32 MSG_DEVICE_NAME = 'devn'; -const uint32 MSG_BOOT_ANY = 'bany'; -const uint32 MSG_BOOT_CDROM = 'bcdr'; -const uint32 MSG_NOCDROM = 'nocd'; - -const uint32 MSG_REF_5HZ = ' 5Hz'; // "Graphics/Sound" pane -const uint32 MSG_REF_7_5HZ = ' 7Hz'; -const uint32 MSG_REF_10HZ = '10Hz'; -const uint32 MSG_REF_15HZ = '15Hz'; -const uint32 MSG_REF_30HZ = '30Hz'; -const uint32 MSG_VIDEO_WINDOW = 'vtyw'; -const uint32 MSG_VIDEO_SCREEN = 'vtys'; -const uint32 MSG_SCREEN_MODE = 'sm\0\0'; -const uint32 MSG_NOSOUND = 'nosn'; - -const uint32 MSG_SER_A = 'sera'; // "Serial/Network" pane -const uint32 MSG_SER_B = 'serb'; -const uint32 MSG_ETHER = 'ethr'; -const uint32 MSG_UDPTUNNEL = 'udpt'; - -const uint32 MSG_RAMSIZE = 'rmsz'; // "Memory/Misc" pane -const uint32 MSG_MODELID_5 = 'mi05'; -const uint32 MSG_MODELID_14 = 'mi14'; -const uint32 MSG_CPU_68020 = 'cpu2'; -const uint32 MSG_CPU_68020_FPU = 'cpf2'; -const uint32 MSG_CPU_68030 = 'cpu3'; -const uint32 MSG_CPU_68030_FPU = 'cpf3'; -const uint32 MSG_CPU_68040 = 'cpu4'; - - -// RAM size slider class -class RAMSlider : public BSlider { -public: - RAMSlider(BRect frame, const char *name, const char *label, BMessage *message, - int32 minValue, int32 maxValue, thumb_style thumbType = B_BLOCK_THUMB, - uint32 resizingMode = B_FOLLOW_LEFT | - B_FOLLOW_TOP, - uint32 flags = B_NAVIGABLE | B_WILL_DRAW | - B_FRAME_EVENTS) : BSlider(frame, name, label, message, minValue, maxValue, thumbType, resizingMode, flags) - { - update_text = (char *)malloc(256); - } - - virtual ~RAMSlider() - { - if (update_text) - free(update_text); - } - - virtual char *UpdateText(void) const - { - if (update_text) { - sprintf(update_text, GetString(STR_RAMSIZE_FMT), Value()); - } - return update_text; - } - -private: - char *update_text; -}; - - -// Volumes list view class -class VolumeListView : public BListView { -public: - VolumeListView(BRect frame, const char *name, list_view_type type = B_SINGLE_SELECTION_LIST, uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE) - : BListView(frame, name, type, resizeMask, flags) - {} - - // Handle dropped files and volumes - virtual void MessageReceived(BMessage *msg) - { - if (msg->what == B_SIMPLE_DATA) { - BMessage msg2(MSG_ADD_VOLUME_PANEL); - entry_ref ref; - for (int i=0; msg->FindRef("refs", i, &ref) == B_NO_ERROR; i++) - msg2.AddRef("refs", &ref); - Window()->PostMessage(&msg2); - } else - BListView::MessageReceived(msg); - } -}; - - -// Number-entry BTextControl -class NumberControl : public BTextControl { -public: - NumberControl(BRect frame, float divider, const char *name, const char *label, long value, BMessage *message) - : BTextControl(frame, name, label, NULL, message, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE) - { - SetDivider(divider); - for (int c=0; c<256; c++) - if (!isdigit(c) && c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW) - ((BTextView *)ChildAt(0))->DisallowChar(c); - SetValue(value); - } - - // Set integer value - void SetValue(long value) - { - char str[32]; - sprintf(str, "%ld", value); - SetText(str); - } - - // Get integer value - long Value(void) - { - return atol(Text()); - } -}; - - -// Path-entry BTextControl -class PathControl : public BTextControl { -public: - PathControl(bool dir_ctrl_, BRect frame, const char *name, const char *label, const char *text, BMessage *message) : BTextControl(frame, name, label, text, message), dir_ctrl(dir_ctrl_) - { - for (int c=0; c<' '; c++) - if (c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW) - ((BTextView *)ChildAt(0))->DisallowChar(c); - } - - virtual void MessageReceived(BMessage *msg) - { - if (msg->what == B_SIMPLE_DATA) { - entry_ref the_ref; - BEntry the_entry; - - // Look for dropped refs - if (msg->FindRef("refs", &the_ref) == B_NO_ERROR) { - if (the_entry.SetTo(&the_ref) == B_NO_ERROR && (dir_ctrl&& the_entry.IsDirectory() || !dir_ctrl && the_entry.IsFile())) { - BPath the_path; - the_entry.GetPath(&the_path); - SetText(the_path.Path()); - } - } else - BTextControl::MessageReceived(msg); - - MakeFocus(); - } else - BTextControl::MessageReceived(msg); - } - -private: - bool dir_ctrl; -}; - - -// Preferences window class -class PrefsWindow : public BWindow { -public: - PrefsWindow(uint32 msg); - virtual ~PrefsWindow(); - virtual void MessageReceived(BMessage *msg); - -private: - void read_volumes_prefs(void); - void hide_show_graphics_ctrls(void); - void read_graphics_prefs(void); - void hide_show_serial_ctrls(void); - void read_serial_prefs(void); - void add_serial_names(BPopUpMenu *menu, uint32 msg); - void read_memory_prefs(void); - - BView *create_volumes_pane(void); - BView *create_graphics_pane(void); - BView *create_serial_pane(void); - BView *create_memory_pane(void); - - uint32 ok_message; - bool send_quit_on_close; - - system_info sys_info; - BMessenger this_messenger; - BView *top; - BRect top_frame; - BTabView *pane_tabs; - BView *panes[NUM_PANES]; - int current_pane; - - VolumeListView *volume_list; - BCheckBox *nocdrom_checkbox; - BMenuField *frameskip_menu; - NumberControl *display_x_ctrl; - NumberControl *display_y_ctrl; - BMenuField *scr_mode_menu; - BCheckBox *nosound_checkbox; - BCheckBox *ether_checkbox; - BCheckBox *udptunnel_checkbox; - NumberControl *udpport_ctrl; - RAMSlider *ramsize_slider; - PathControl *extfs_control; - PathControl *rom_control; - BCheckBox *fpu_checkbox; - - BFilePanel *add_volume_panel; - BFilePanel *create_volume_panel; - - uint32 max_ramsize; // In MB - int display_type; - int scr_mode_bit; -}; - - -/* - * Show preferences editor (asynchronously) - * Under BeOS, the return value is ignored. Instead, a message is sent to the - * application when the user clicks on "Start" or "Quit" - */ - -bool PrefsEditor(void) -{ - new PrefsWindow('strt'); - return true; -} - - -/* - * Preferences window constructor - */ - -PrefsWindow::PrefsWindow(uint32 msg) : BWindow(BRect(0, 0, 400, 289), GetString(STR_PREFS_TITLE), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS), this_messenger(this) -{ - int i; - ok_message = msg; - send_quit_on_close = true; - get_system_info(&sys_info); - - // Move window to right position - Lock(); - MoveTo(80, 80); - - // Set up menus - BMenuBar *bar = new BMenuBar(Bounds(), "menu"); - BMenu *menu = new BMenu(GetString(STR_PREFS_MENU)); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ABOUT), new BMessage(B_ABOUT_REQUESTED))); - menu->AddItem(new BSeparatorItem); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_START), new BMessage(MSG_OK))); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ZAP_PRAM), new BMessage(MSG_ZAP_PRAM))); - menu->AddItem(new BSeparatorItem); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_QUIT), new BMessage(MSG_CANCEL), 'Q')); - bar->AddItem(menu); - AddChild(bar); - SetKeyMenuBar(bar); - int mbar_height = int(bar->Bounds().bottom) + 1; - - // Resize window to fit menu bar - ResizeBy(0, mbar_height); - - // Light gray background - BRect b = Bounds(); - top = new BView(BRect(0, mbar_height, b.right, b.bottom), "top", B_FOLLOW_NONE, B_WILL_DRAW); - AddChild(top); - top->SetViewColor(fill_color); - top_frame = top->Bounds(); - - // Create panes - panes[0] = create_volumes_pane(); - panes[1] = create_graphics_pane(); - panes[2] = create_serial_pane(); - panes[3] = create_memory_pane(); - - // Prefs item tab view - pane_tabs = new BTabView(BRect(10, 10, top_frame.right-10, top_frame.bottom-50), "items", B_WIDTH_FROM_LABEL); - for (i=0; iAddTab(panes[i]); - top->AddChild(pane_tabs); - - volume_list->Select(0); - - // Create volume file panels - add_volume_panel = new BFilePanel(B_OPEN_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_ADD_VOLUME_PANEL)); - add_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_ADD_VOLUME_PANEL_BUTTON)); - add_volume_panel->Window()->SetTitle(GetString(STR_ADD_VOLUME_TITLE)); - create_volume_panel = new BFilePanel(B_SAVE_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_CREATE_VOLUME_PANEL)); - create_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_CREATE_VOLUME_PANEL_BUTTON)); - create_volume_panel->Window()->SetTitle(GetString(STR_CREATE_VOLUME_TITLE)); - - create_volume_panel->Window()->Lock(); - BView *background = create_volume_panel->Window()->ChildAt(0); - background->FindView("PoseView")->ResizeBy(0, -30); - background->FindView("VScrollBar")->ResizeBy(0, -30); - background->FindView("CountVw")->MoveBy(0, -30); - BView *v = background->FindView("HScrollBar"); - if (v) - v->MoveBy(0, -30); - else { - i = 0; - while ((v = background->ChildAt(i++)) != NULL) { - if (v->Name() == NULL || v->Name()[0] == 0) { - v->MoveBy(0, -30); // unnamed horizontal scroll bar - break; - } - } - } - BView *filename = background->FindView("text view"); - BRect fnr(filename->Frame()); - fnr.OffsetBy(0, -30); - NumberControl *nc = new NumberControl(fnr, 80, "hardfile_size", GetString(STR_HARDFILE_SIZE_CTRL), 40, NULL); - background->AddChild(nc); - create_volume_panel->Window()->Unlock(); - - // "Start" button - BButton *button = new BButton(BRect(20, top_frame.bottom-35, 90, top_frame.bottom-10), "start", GetString(STR_START_BUTTON), new BMessage(MSG_OK)); - top->AddChild(button); - SetDefaultButton(button); - - // "Quit" button - top->AddChild(new BButton(BRect(top_frame.right-90, top_frame.bottom-35, top_frame.right-20, top_frame.bottom-10), "cancel", GetString(STR_QUIT_BUTTON), new BMessage(MSG_CANCEL))); - - Unlock(); - Show(); -} - - -/* - * Preferences window destructor - */ - -PrefsWindow::~PrefsWindow() -{ - delete add_volume_panel; - delete create_volume_panel; - if (send_quit_on_close) - be_app->PostMessage(B_QUIT_REQUESTED); -} - - -/* - * Create "Volumes" pane - */ - -void PrefsWindow::read_volumes_prefs(void) -{ - PrefsReplaceString("extfs", extfs_control->Text()); -} - -BView *PrefsWindow::create_volumes_pane(void) -{ - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_VOLUMES_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - const char *str; - int32 index = 0; - volume_list = new VolumeListView(BRect(15, 10, pane->Bounds().right-30, 113), "volumes"); - while ((str = PrefsFindString("disk", index++)) != NULL) - volume_list->AddItem(new BStringItem(str)); - volume_list->SetSelectionMessage(new BMessage(MSG_VOLUME_SELECTED)); - volume_list->SetInvocationMessage(new BMessage(MSG_VOLUME_INVOKED)); - pane->AddChild(new BScrollView("volumes_border", volume_list, B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true)); - - pane->AddChild(new BButton(BRect(10, 118, pane->Bounds().right/3, 138), "add_volume", GetString(STR_ADD_VOLUME_BUTTON), new BMessage(MSG_ADD_VOLUME))); - pane->AddChild(new BButton(BRect(pane->Bounds().right/3, 118, pane->Bounds().right*2/3, 138), "create_volume", GetString(STR_CREATE_VOLUME_BUTTON), new BMessage(MSG_CREATE_VOLUME))); - pane->AddChild(new BButton(BRect(pane->Bounds().right*2/3, 118, pane->Bounds().right-11, 138), "remove_volume", GetString(STR_REMOVE_VOLUME_BUTTON), new BMessage(MSG_REMOVE_VOLUME))); - - extfs_control = new PathControl(true, BRect(10, 145, right, 160), "extfs", GetString(STR_EXTFS_CTRL), PrefsFindString("extfs"), NULL); - extfs_control->SetDivider(90); - pane->AddChild(extfs_control); - - BMenuField *menu_field; - BPopUpMenu *menu = new BPopUpMenu(""); - menu_field = new BMenuField(BRect(10, 165, right, 180), "bootdriver", GetString(STR_BOOTDRIVER_CTRL), menu); - menu_field->SetDivider(90); - menu->AddItem(new BMenuItem(GetString(STR_BOOT_ANY_LAB), new BMessage(MSG_BOOT_ANY))); - menu->AddItem(new BMenuItem(GetString(STR_BOOT_CDROM_LAB), new BMessage(MSG_BOOT_CDROM))); - pane->AddChild(menu_field); - int32 i32 = PrefsFindInt32("bootdriver"); - BMenuItem *item; - if (i32 == 0) { - if ((item = menu->FindItem(GetString(STR_BOOT_ANY_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == CDROMRefNum) { - if ((item = menu->FindItem(GetString(STR_BOOT_CDROM_LAB))) != NULL) - item->SetMarked(true); - } - - nocdrom_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nocdrom", GetString(STR_NOCDROM_CTRL), new BMessage(MSG_NOCDROM)); - pane->AddChild(nocdrom_checkbox); - nocdrom_checkbox->SetValue(PrefsFindBool("nocdrom") ? B_CONTROL_ON : B_CONTROL_OFF); - - return pane; -} - - -/* - * Create "Graphics/Sound" pane - */ - -// Screen mode list -struct scr_mode_desc { - int mode_mask; - int str; -}; - -static const scr_mode_desc scr_mode[] = { - {B_8_BIT_640x480, STR_8_BIT_640x480_LAB}, - {B_8_BIT_800x600, STR_8_BIT_800x600_LAB}, - {B_8_BIT_1024x768, STR_8_BIT_1024x768_LAB}, - {B_8_BIT_1152x900, STR_8_BIT_1152x900_LAB}, - {B_8_BIT_1280x1024, STR_8_BIT_1280x1024_LAB}, - {B_8_BIT_1600x1200, STR_8_BIT_1600x1200_LAB}, - {B_15_BIT_640x480, STR_15_BIT_640x480_LAB}, - {B_15_BIT_800x600, STR_15_BIT_800x600_LAB}, - {B_15_BIT_1024x768, STR_15_BIT_1024x768_LAB}, - {B_15_BIT_1152x900, STR_15_BIT_1152x900_LAB}, - {B_15_BIT_1280x1024, STR_15_BIT_1280x1024_LAB}, - {B_15_BIT_1600x1200, STR_15_BIT_1600x1200_LAB}, - {B_32_BIT_640x480, STR_24_BIT_640x480_LAB}, - {B_32_BIT_800x600, STR_24_BIT_800x600_LAB}, - {B_32_BIT_1024x768, STR_24_BIT_1024x768_LAB}, - {B_32_BIT_1152x900, STR_24_BIT_1152x900_LAB}, - {B_32_BIT_1280x1024, STR_24_BIT_1280x1024_LAB}, - {B_32_BIT_1600x1200, STR_24_BIT_1600x1200_LAB}, - {0, 0} // End marker -}; - -void PrefsWindow::hide_show_graphics_ctrls(void) -{ - if (display_type == DISPLAY_WINDOW) { - if (!scr_mode_menu->IsHidden()) - scr_mode_menu->Hide(); - if (frameskip_menu->IsHidden()) - frameskip_menu->Show(); - if (display_x_ctrl->IsHidden()) - display_x_ctrl->Show(); - if (display_y_ctrl->IsHidden()) - display_y_ctrl->Show(); - } else { - if (!frameskip_menu->IsHidden()) - frameskip_menu->Hide(); - if (!display_x_ctrl->IsHidden()) - display_x_ctrl->Hide(); - if (!display_y_ctrl->IsHidden()) - display_y_ctrl->Hide(); - if (scr_mode_menu->IsHidden()) - scr_mode_menu->Show(); - } -} - -void PrefsWindow::read_graphics_prefs(void) -{ - char str[64]; - if (display_type == DISPLAY_WINDOW) { - sprintf(str, "win/%d/%d", display_x_ctrl->Value(), display_y_ctrl->Value()); - } else { - sprintf(str, "scr/%d", scr_mode_bit); - } - PrefsReplaceString("screen", str); -} - -BView *PrefsWindow::create_graphics_pane(void) -{ - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_GRAPHICS_SOUND_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - const char *mode_str = PrefsFindString("screen"); - int width = 512, height = 384; - scr_mode_bit = 0; - display_type = DISPLAY_WINDOW; - if (mode_str) { - if (sscanf(mode_str, "win/%d/%d", &width, &height) == 2) - display_type = DISPLAY_WINDOW; - else if (sscanf(mode_str, "scr/%d", &scr_mode_bit) == 1) - display_type = DISPLAY_SCREEN; - } - - BMenuField *menu_field; - BMenuItem *item; - BPopUpMenu *menu; - - menu = new BPopUpMenu(""); - menu_field = new BMenuField(BRect(10, 5, right, 20), "videotype", GetString(STR_VIDEO_TYPE_CTRL), menu); - menu_field->SetDivider(120); - menu->AddItem(item = new BMenuItem(GetString(STR_WINDOW_LAB), new BMessage(MSG_VIDEO_WINDOW))); - if (display_type == DISPLAY_WINDOW) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_FULLSCREEN_LAB), new BMessage(MSG_VIDEO_SCREEN))); - if (display_type == DISPLAY_SCREEN) - item->SetMarked(true); - pane->AddChild(menu_field); - - menu = new BPopUpMenu(""); - frameskip_menu = new BMenuField(BRect(10, 26, right, 41), "frameskip", GetString(STR_FRAMESKIP_CTRL), menu); - frameskip_menu->SetDivider(120); - menu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ))); - pane->AddChild(frameskip_menu); - int32 i32 = PrefsFindInt32("frameskip"); - if (i32 == 12) { - if ((item = menu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 8) { - if ((item = menu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 6) { - if ((item = menu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 4) { - if ((item = menu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 2) { - if ((item = menu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL) - item->SetMarked(true); - } - - display_x_ctrl = new NumberControl(BRect(10, 48, right / 2, 66), 118, "width", GetString(STR_DISPLAY_X_CTRL), width, NULL); - pane->AddChild(display_x_ctrl); - display_y_ctrl = new NumberControl(BRect(10, 69, right / 2, 87), 118, "height", GetString(STR_DISPLAY_Y_CTRL), height, NULL); - pane->AddChild(display_y_ctrl); - - menu = new BPopUpMenu(""); - scr_mode_menu = new BMenuField(BRect(10, 26, right, 41), "screenmode", GetString(STR_SCREEN_MODE_CTRL), menu); - scr_mode_menu->SetDivider(120); - for (int i=0; scr_mode[i].mode_mask; i++) { - menu->AddItem(item = new BMenuItem(GetString(scr_mode[i].str), new BMessage(MSG_SCREEN_MODE + i))); - if (scr_mode[i].mode_mask & (1 << scr_mode_bit)) - item->SetMarked(true); - } - pane->AddChild(scr_mode_menu); - - nosound_checkbox = new BCheckBox(BRect(10, 90, right, 105), "nosound", GetString(STR_NOSOUND_CTRL), new BMessage(MSG_NOSOUND)); - pane->AddChild(nosound_checkbox); - nosound_checkbox->SetValue(PrefsFindBool("nosound") ? B_CONTROL_ON : B_CONTROL_OFF); - - hide_show_graphics_ctrls(); - return pane; -} - - -/* - * Create "Serial/Network" pane - */ - -void PrefsWindow::hide_show_serial_ctrls(void) -{ - if (udptunnel_checkbox->Value() == B_CONTROL_ON) { - ether_checkbox->SetEnabled(false); - udpport_ctrl->SetEnabled(true); - } else { - ether_checkbox->SetEnabled(true); - udpport_ctrl->SetEnabled(false); - } -} - -void PrefsWindow::read_serial_prefs(void) -{ - PrefsReplaceInt32("udpport", udpport_ctrl->Value()); -} - -void PrefsWindow::add_serial_names(BPopUpMenu *menu, uint32 msg) -{ - BSerialPort *port = new BSerialPort; - char name[B_PATH_NAME_LENGTH]; - for (int i=0; iCountDevices(); i++) { - port->GetDeviceName(i, name); - menu->AddItem(new BMenuItem(name, new BMessage(msg))); - } - BDirectory dir; - BEntry entry; - dir.SetTo("/dev/parallel"); - if (dir.InitCheck() == B_NO_ERROR) { - dir.Rewind(); - while (dir.GetNextEntry(&entry) >= 0) { - if (!entry.IsDirectory()) { - entry.GetName(name); - menu->AddItem(new BMenuItem(name, new BMessage(msg))); - } - } - } - delete port; -} - -static void set_serial_label(BPopUpMenu *menu, const char *prefs_name) -{ - const char *str; - BMenuItem *item; - if ((str = PrefsFindString(prefs_name)) != NULL) - if ((item = menu->FindItem(str)) != NULL) - item->SetMarked(true); -} - -BView *PrefsWindow::create_serial_pane(void) -{ - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_SERIAL_NETWORK_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - BMenuField *menu_field; - BPopUpMenu *menu_a = new BPopUpMenu(""); - add_serial_names(menu_a, MSG_SER_A); - menu_field = new BMenuField(BRect(10, 5, right, 20), "seriala", GetString(STR_SERIALA_CTRL), menu_a); - menu_field->SetDivider(90); - pane->AddChild(menu_field); - set_serial_label(menu_a, "seriala"); - - BPopUpMenu *menu_b = new BPopUpMenu(""); - add_serial_names(menu_b, MSG_SER_B); - menu_field = new BMenuField(BRect(10, 26, right, 41), "serialb", GetString(STR_SERIALB_CTRL), menu_b); - menu_field->SetDivider(90); - pane->AddChild(menu_field); - set_serial_label(menu_b, "serialb"); - - ether_checkbox = new BCheckBox(BRect(10, 47, right, 62), "ether", GetString(STR_ETHER_ENABLE_CTRL), new BMessage(MSG_ETHER)); - pane->AddChild(ether_checkbox); - ether_checkbox->SetValue(PrefsFindString("ether") ? B_CONTROL_ON : B_CONTROL_OFF); - - udptunnel_checkbox = new BCheckBox(BRect(10, 67, right, 72), "udptunnel", GetString(STR_UDPTUNNEL_CTRL), new BMessage(MSG_UDPTUNNEL)); - pane->AddChild(udptunnel_checkbox); - udptunnel_checkbox->SetValue(PrefsFindBool("udptunnel") ? B_CONTROL_ON : B_CONTROL_OFF); - - udpport_ctrl = new NumberControl(BRect(10, 87, right / 2, 105), 118, "udpport", GetString(STR_UDPPORT_CTRL), PrefsFindInt32("udpport"), NULL); - pane->AddChild(udpport_ctrl); - - hide_show_serial_ctrls(); - return pane; -} - - -/* - * Create "Memory" pane - */ - -void PrefsWindow::read_memory_prefs(void) -{ - const char *str = rom_control->Text(); - if (strlen(str)) - PrefsReplaceString("rom", str); - else - PrefsRemoveItem("rom"); -} - -BView *PrefsWindow::create_memory_pane(void) -{ - char str[256], str2[256]; - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_MEMORY_MISC_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - BEntry entry("/boot/var/swap"); - off_t swap_space; - if (entry.GetSize(&swap_space) == B_NO_ERROR) - max_ramsize = swap_space / (1024 * 1024) - 8; - else - max_ramsize = sys_info.max_pages * B_PAGE_SIZE / (1024 * 1024) - 8; - - int32 value = PrefsFindInt32("ramsize") / (1024 * 1024); - - ramsize_slider = new RAMSlider(BRect(10, 5, right, 55), "ramsize", GetString(STR_RAMSIZE_SLIDER), new BMessage(MSG_RAMSIZE), 1, max_ramsize, B_TRIANGLE_THUMB); - ramsize_slider->SetValue(value); - ramsize_slider->UseFillColor(true, &slider_fill_color); - sprintf(str, GetString(STR_RAMSIZE_FMT), 1); - sprintf(str2, GetString(STR_RAMSIZE_FMT), max_ramsize); - ramsize_slider->SetLimitLabels(str, str2); - pane->AddChild(ramsize_slider); - - BMenuField *menu_field; - BMenuItem *item; - BPopUpMenu *menu; - - int id = PrefsFindInt32("modelid"); - menu = new BPopUpMenu(""); - menu_field = new BMenuField(BRect(10, 60, right, 75), "modelid", GetString(STR_MODELID_CTRL), menu); - menu_field->SetDivider(120); - menu->AddItem(item = new BMenuItem(GetString(STR_MODELID_5_LAB), new BMessage(MSG_MODELID_5))); - if (id == 5) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_MODELID_14_LAB), new BMessage(MSG_MODELID_14))); - if (id == 14) - item->SetMarked(true); - pane->AddChild(menu_field); - - int cpu = PrefsFindInt32("cpu"); - bool fpu = PrefsFindBool("fpu"); - menu = new BPopUpMenu(""); - menu_field = new BMenuField(BRect(10, 82, right, 97), "cpu", GetString(STR_CPU_CTRL), menu); - menu_field->SetDivider(120); - menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68020_LAB), new BMessage(MSG_CPU_68020))); - if (cpu == 2 && !fpu) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68020_FPU_LAB), new BMessage(MSG_CPU_68020_FPU))); - if (cpu == 2 && fpu) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68030_LAB), new BMessage(MSG_CPU_68030))); - if (cpu == 3 && !fpu) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68030_FPU_LAB), new BMessage(MSG_CPU_68030_FPU))); - if (cpu == 3 && fpu) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68040_LAB), new BMessage(MSG_CPU_68040))); - if (cpu == 4) - item->SetMarked(true); - pane->AddChild(menu_field); - - rom_control = new PathControl(false, BRect(10, 104, right, 119), "rom", GetString(STR_ROM_FILE_CTRL), PrefsFindString("rom"), NULL); - rom_control->SetDivider(117); - pane->AddChild(rom_control); - - return pane; -} - - -/* - * Message from controls/menus received - */ - -void PrefsWindow::MessageReceived(BMessage *msg) -{ - switch (msg->what) { - case MSG_OK: { // "Start" button clicked - read_volumes_prefs(); - read_memory_prefs(); - read_graphics_prefs(); - SavePrefs(); - send_quit_on_close = false; - PostMessage(B_QUIT_REQUESTED); - be_app->PostMessage(ok_message); - break; - } - - case MSG_CANCEL: // "Quit" button clicked - send_quit_on_close = false; - PostMessage(B_QUIT_REQUESTED); - be_app->PostMessage(B_QUIT_REQUESTED); - break; - - case B_ABOUT_REQUESTED: { // "About" menu item selected - ShowAboutWindow(); - break; - } - - case MSG_ZAP_PRAM: // "Zap PRAM File" menu item selected - ZapPRAM(); - break; - - case MSG_VOLUME_INVOKED: { // Double-clicked on volume name, toggle read-only flag - int selected = volume_list->CurrentSelection(); - if (selected >= 0) { - const char *str = PrefsFindString("disk", selected); - BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected); - delete item; - char newstr[256]; - if (str[0] == '*') - strcpy(newstr, str+1); - else { - strcpy(newstr, "*"); - strcat(newstr, str); - } - PrefsReplaceString("disk", newstr, selected); - volume_list->AddItem(new BStringItem(newstr), selected); - volume_list->Select(selected); - } - break; - } - - case MSG_ADD_VOLUME: - add_volume_panel->Show(); - break; - - case MSG_CREATE_VOLUME: - create_volume_panel->Show(); - break; - - case MSG_ADD_VOLUME_PANEL: { - entry_ref ref; - if (msg->FindRef("refs", &ref) == B_NO_ERROR) { - BEntry entry(&ref, true); - BPath path; - entry.GetPath(&path); - if (entry.IsFile()) { - PrefsAddString("disk", path.Path()); - volume_list->AddItem(new BStringItem(path.Path())); - } else if (entry.IsDirectory()) { - BVolume volume; - if (path.Path()[0] == '/' && strchr(path.Path()+1, '/') == NULL && entry.GetVolume(&volume) == B_NO_ERROR) { - int32 i = 0; - dev_t d; - fs_info info; - while ((d = next_dev(&i)) >= 0) { - fs_stat_dev(d, &info); - if (volume.Device() == info.dev) { - PrefsAddString("disk", info.device_name); - volume_list->AddItem(new BStringItem(info.device_name)); - } - } - } - } - } - break; - } - - case MSG_CREATE_VOLUME_PANEL: { - entry_ref dir; - if (msg->FindRef("directory", &dir) == B_NO_ERROR) { - BEntry entry(&dir, true); - BPath path; - entry.GetPath(&path); - path.Append(msg->FindString("name")); - - create_volume_panel->Window()->Lock(); - BView *background = create_volume_panel->Window()->ChildAt(0); - NumberControl *v = (NumberControl *)background->FindView("hardfile_size"); - int size = v->Value(); - - char cmd[1024]; - sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", path.Path(), size); - int ret = system(cmd); - if (ret == 0) { - PrefsAddString("disk", path.Path()); - volume_list->AddItem(new BStringItem(path.Path())); - } else { - sprintf(cmd, GetString(STR_CREATE_VOLUME_WARN), strerror(ret)); - WarningAlert(cmd); - } - } - break; - } - - case MSG_REMOVE_VOLUME: { - int selected = volume_list->CurrentSelection(); - if (selected >= 0) { - PrefsRemoveItem("disk", selected); - BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected); - delete item; - volume_list->Select(selected); - } - break; - } - - case MSG_BOOT_ANY: - PrefsReplaceInt32("bootdriver", 0); - break; - - case MSG_BOOT_CDROM: - PrefsReplaceInt32("bootdriver", CDROMRefNum); - break; - - case MSG_NOCDROM: - PrefsReplaceBool("nocdrom", nocdrom_checkbox->Value() == B_CONTROL_ON); - break; - - case MSG_VIDEO_WINDOW: - display_type = DISPLAY_WINDOW; - hide_show_graphics_ctrls(); - break; - - case MSG_VIDEO_SCREEN: - display_type = DISPLAY_SCREEN; - hide_show_graphics_ctrls(); - break; - - case MSG_REF_5HZ: - PrefsReplaceInt32("frameskip", 12); - break; - - case MSG_REF_7_5HZ: - PrefsReplaceInt32("frameskip", 8); - break; - - case MSG_REF_10HZ: - PrefsReplaceInt32("frameskip", 6); - break; - - case MSG_REF_15HZ: - PrefsReplaceInt32("frameskip", 4); - break; - - case MSG_REF_30HZ: - PrefsReplaceInt32("frameskip", 2); - break; - - case MSG_NOSOUND: - PrefsReplaceBool("nosound", nosound_checkbox->Value() == B_CONTROL_ON); - break; - - case MSG_SER_A: { - BMenuItem *source = NULL; - msg->FindPointer("source", (void **)&source); - if (source) - PrefsReplaceString("seriala", source->Label()); - break; - } - - case MSG_SER_B: { - BMenuItem *source = NULL; - msg->FindPointer("source", (void **)&source); - if (source) - PrefsReplaceString("serialb", source->Label()); - break; - } - - case MSG_ETHER: - if (ether_checkbox->Value() == B_CONTROL_ON) - PrefsReplaceString("ether", "yes"); - else - PrefsRemoveItem("ether"); - break; - - case MSG_UDPTUNNEL: - PrefsReplaceBool("udptunnel", udptunnel_checkbox->Value() == B_CONTROL_ON); - hide_show_serial_ctrls(); - break; - - case MSG_RAMSIZE: - PrefsReplaceInt32("ramsize", ramsize_slider->Value() * 1024 * 1024); - break; - - case MSG_MODELID_5: - PrefsReplaceInt32("modelid", 5); - break; - - case MSG_MODELID_14: - PrefsReplaceInt32("modelid", 14); - break; - - case MSG_CPU_68020: - PrefsReplaceInt32("cpu", 2); - PrefsReplaceBool("fpu", false); - break; - - case MSG_CPU_68020_FPU: - PrefsReplaceInt32("cpu", 2); - PrefsReplaceBool("fpu", true); - break; - - case MSG_CPU_68030: - PrefsReplaceInt32("cpu", 3); - PrefsReplaceBool("fpu", false); - break; - - case MSG_CPU_68030_FPU: - PrefsReplaceInt32("cpu", 3); - PrefsReplaceBool("fpu", true); - break; - - case MSG_CPU_68040: - PrefsReplaceInt32("cpu", 4); - PrefsReplaceBool("fpu", true); - break; - - default: { - // Screen mode messages - if ((msg->what & 0xffff0000) == MSG_SCREEN_MODE) { - int m = msg->what & 0xffff; - uint32 mask = scr_mode[m].mode_mask; - for (int i=0; i<32; i++) - if (mask & (1 << i)) - scr_mode_bit = i; - } else - BWindow::MessageReceived(msg); - } - } -} diff --git a/BasiliskII/src/BeOS/scsi_beos.cpp b/BasiliskII/src/BeOS/scsi_beos.cpp deleted file mode 100644 index 75d1e29a..00000000 --- a/BasiliskII/src/BeOS/scsi_beos.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * scsi_beos.cpp - SCSI Manager, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#ifdef __HAIKU__ -#include -#else -#include -#endif - -#include "sysdeps.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "scsi.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static raw_device_command rdc; - -static int fds[8*8]; // fd's for 8 units and 8 LUNs each -static int fd; // Active fd (selected target) - -static uint32 buffer_size; // Size of data buffer -static uint8 *buffer = NULL; // Pointer to data buffer - -static uint8 sense_data[256]; // Buffer for autosense data - - -/* - * Initialization - */ - -void SCSIInit(void) -{ - int id, lun; - - // Allocate buffer - buffer = (uint8 *)malloc(buffer_size = 0x10000); - - // Open scsi_raw driver for all 8 units (and all 8 LUNs) - char dev_name[256]; - for (id=0; id<8; id++) { - for (lun=0; lun<8; lun++) - fds[id*8+lun] = -1; - char prefs_name[16]; - sprintf(prefs_name, "scsi%d", id); - const char *str = PrefsFindString(prefs_name); - if (str) { - int bus, unit; - if (sscanf(str, "%d/%d", &bus, &unit) == 2) { - for (lun=0; lun<8; lun++) { - sprintf(dev_name, "/dev/bus/scsi/%d/%d/%d/raw", bus, unit, lun); - D(bug("SCSI %d: Opening %s\n", id, dev_name)); - fds[id*8+lun] = open(dev_name, O_RDWR); - } - } - } - } - - // Reset SCSI bus - SCSIReset(); - - // Init rdc - memset(&rdc, 0, sizeof(rdc)); - rdc.data = buffer; - rdc.sense_data = sense_data; -} - - -/* - * Deinitialization - */ - -void SCSIExit(void) -{ - // Close all devices - for (int i=0; i<8; i++) - for (int j=0; j<8; j++) { - int fd = fds[i*8+j]; - if (fd > 0) - close(fd); - } - - // Free buffer - if (buffer) { - free(buffer); - buffer = NULL; - } -} - - -/* - * Check if requested data size fits into buffer, allocate new buffer if needed - */ - -static bool try_buffer(int size) -{ - if (size <= buffer_size) - return true; - - uint8 *new_buffer = (uint8 *)malloc(size); - if (new_buffer == NULL) - return false; - free(buffer); - buffer = new_buffer; - buffer_size = size; - return true; -} - - -/* - * Set SCSI command to be sent by scsi_send_cmd() - */ - -void scsi_set_cmd(int cmd_length, uint8 *cmd) -{ - rdc.command_length = cmd_length; - memcpy(rdc.command, cmd, cmd_length); -} - - -/* - * Check for presence of SCSI target - */ - -bool scsi_is_target_present(int id) -{ - return fds[id * 8] > 0; -} - - -/* - * Set SCSI target (returns false on error) - */ - -bool scsi_set_target(int id, int lun) -{ - int new_fd = fds[id * 8 + lun]; - if (new_fd < 0) - return false; - if (new_fd != fd) - rdc.cam_status &= ~CAM_AUTOSNS_VALID; // Clear sense data when selecting new target - fd = new_fd; - return true; -} - - -/* - * Send SCSI command to active target (scsi_set_command() must have been called), - * read/write data according to S/G table (returns false on error); timeout is in 1/60 sec - */ - -bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr, uint32 *sg_len, uint16 *stat, uint32 timeout) -{ - // Check if buffer is large enough, allocate new buffer if needed - if (!try_buffer(data_length)) { - char str[256]; - sprintf(str, GetString(STR_SCSI_BUFFER_ERR), data_length); - ErrorAlert(str); - return false; - } - - // Process S/G table when writing - if (!reading) { - D(bug(" writing to buffer\n")); - uint8 *buffer_ptr = buffer; - for (int i=0; i -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "serial.h" -#include "serial_defs.h" - -#define DEBUG 0 -#include "debug.h" - -#define MONITOR 0 - - -// Buffer size for kernel-space transfers -const int TMP_BUF_SIZE = 2048; - -// These packets are sent to the input/output threads -const uint32 CMD_READ = 'read'; -const uint32 CMD_WRITE = 'writ'; -const uint32 CMD_QUIT = 'quit'; - -struct ThreadPacket { - uint32 pb; -}; - - -// Driver private variables -class BeSERDPort : public SERDPort { -public: - BeSERDPort(const char *dev) - { - device_name = dev; - if (strstr(dev, "parallel")) { - is_parallel = true; - fd = -1; - device = NULL; - } else { - is_parallel = false; - device = new BSerialPort; - } - device_sem = create_sem(1, "serial port"); - input_thread = output_thread = 0; - } - - virtual ~BeSERDPort() - { - status_t l; - if (input_thread > 0) { - send_data(input_thread, CMD_QUIT, NULL, 0); - suspend_thread(input_thread); // Unblock thread - snooze(1000); - resume_thread(input_thread); - while (wait_for_thread(input_thread, &l) == B_INTERRUPTED) ; - } - if (output_thread > 0) { - send_data(output_thread, CMD_QUIT, NULL, 0); - suspend_thread(output_thread); // Unblock thread - snooze(1000); - resume_thread(output_thread); - while (wait_for_thread(output_thread, &l) == B_INTERRUPTED) ; - } - acquire_sem(device_sem); - delete_sem(device_sem); - delete device; - } - - virtual int16 open(uint16 config); - virtual int16 prime_in(uint32 pb, uint32 dce); - virtual int16 prime_out(uint32 pb, uint32 dce); - virtual int16 control(uint32 pb, uint32 dce, uint16 code); - virtual int16 status(uint32 pb, uint32 dce, uint16 code); - virtual int16 close(void); - -private: - bool configure(uint16 config); - void set_handshake(uint32 s, bool with_dtr); - static status_t input_func(void *arg); - static status_t output_func(void *arg); - - const char *device_name; // Name of BeOS port - BSerialPort *device; // BeOS port object - bool is_parallel; // Flag: Port is parallel, use fd - int fd; // FD for parallel ports - sem_id device_sem; // BSerialPort arbitration - - thread_id input_thread; // Data input thread - thread_id output_thread; // Data output thread - - bool io_killed; // Flag: KillIO called, I/O threads must not call deferred tasks - bool drop_dtr_on_close; // Flag: Negate DTR when driver is closed - - uint8 tmp_in_buf[TMP_BUF_SIZE]; // Buffers for copying from/to kernel space - uint8 tmp_out_buf[TMP_BUF_SIZE]; -}; - - -#if DEBUG -static const int baud_rates[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 31250 -}; -#endif - - -/* - * Initialization - */ - -void SerialInit(void) -{ - // Read serial preferences and create structs for both ports - the_serd_port[0] = new BeSERDPort(PrefsFindString("seriala")); - the_serd_port[1] = new BeSERDPort(PrefsFindString("serialb")); -} - - -/* - * Deinitialization - */ - -void SerialExit(void) -{ - delete (BeSERDPort *)the_serd_port[0]; - delete (BeSERDPort *)the_serd_port[1]; -} - - -/* - * Open serial port - */ - -int16 BeSERDPort::open(uint16 config) -{ - // Don't open NULL name devices - if (device_name == NULL) - return openErr; - - // Init variables - io_killed = false; - drop_dtr_on_close = true; - - // Open port - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - if (is_parallel) { - char name[256]; - sprintf(name, "/dev/parallel/%s", device_name); - fd = ::open(name, O_WRONLY); - if (fd < 0) { - release_sem(device_sem); - return openErr; - } - } else { - device->SetFlowControl(B_HARDWARE_CONTROL); // Must be set before port is opened - if (device->Open(device_name) > 0) { - device->SetBlocking(true); - device->SetTimeout(10000000); - device->SetDTR(true); - device->SetRTS(true); - } else { - release_sem(device_sem); - return openErr; - } - } - - // Start input/output threads - release_sem(device_sem); - configure(config); - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - while ((input_thread = spawn_thread(input_func, "Serial Input", B_NORMAL_PRIORITY, this)) == B_INTERRUPTED) ; - resume_thread(input_thread); - while ((output_thread = spawn_thread(output_func, "Serial Output", B_NORMAL_PRIORITY, this)) == B_INTERRUPTED) ; - resume_thread(output_thread); - release_sem(device_sem); - return noErr; -} - - -/* - * Read data from port - */ - -int16 BeSERDPort::prime_in(uint32 pb, uint32 dce) -{ - // Send input command to input_thread - read_done = false; - read_pending = true; - ThreadPacket p; - p.pb = pb; - WriteMacInt32(input_dt + serdtDCE, dce); - while (send_data(input_thread, CMD_READ, &p, sizeof(ThreadPacket)) == B_INTERRUPTED) ; - return 1; // Command in progress -} - - -/* - * Write data to port - */ - -int16 BeSERDPort::prime_out(uint32 pb, uint32 dce) -{ - // Send output command to output_thread - write_done = false; - write_pending = true; - ThreadPacket p; - p.pb = pb; - WriteMacInt32(output_dt + serdtDCE, dce); - while (send_data(output_thread, CMD_WRITE, &p, sizeof(ThreadPacket)) == B_INTERRUPTED) ; - return 1; // Command in progress -} - - -/* - * Control calls - */ - -int16 BeSERDPort::control(uint32 pb, uint32 dce, uint16 code) -{ - switch (code) { - case 1: // KillIO - io_killed = true; - suspend_thread(input_thread); // Unblock threads - suspend_thread(output_thread); - snooze(1000); - resume_thread(input_thread); - resume_thread(output_thread); - while (read_pending || write_pending) - snooze(10000); - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->ClearInput(); - device->ClearOutput(); - release_sem(device_sem); - } - io_killed = false; - return noErr; - - case kSERDConfiguration: - if (configure(ReadMacInt16(pb + csParam))) - return noErr; - else - return paramErr; - - case kSERDInputBuffer: - return noErr; // Not supported under BeOS - - case kSERDSerHShake: - set_handshake(pb + csParam, false); - return noErr; - - case kSERDClearBreak: - case kSERDSetBreak: - return noErr; // Not supported under BeOS - - case kSERDBaudRate: - if (!is_parallel) { - uint16 rate = ReadMacInt16(pb + csParam); - data_rate baud_rate; - if (rate <= 50) { - rate = 50; baud_rate = B_50_BPS; - } else if (rate <= 75) { - rate = 75; baud_rate = B_75_BPS; - } else if (rate <= 110) { - rate = 110; baud_rate = B_110_BPS; - } else if (rate <= 134) { - rate = 134; baud_rate = B_134_BPS; - } else if (rate <= 150) { - rate = 150; baud_rate = B_150_BPS; - } else if (rate <= 200) { - rate = 200; baud_rate = B_200_BPS; - } else if (rate <= 300) { - rate = 300; baud_rate = B_300_BPS; - } else if (rate <= 600) { - rate = 600; baud_rate = B_600_BPS; - } else if (rate <= 1200) { - rate = 1200; baud_rate = B_1200_BPS; - } else if (rate <= 1800) { - rate = 1800; baud_rate = B_1800_BPS; - } else if (rate <= 2400) { - rate = 2400; baud_rate = B_2400_BPS; - } else if (rate <= 4800) { - rate = 4800; baud_rate = B_4800_BPS; - } else if (rate <= 9600) { - rate = 9600; baud_rate = B_9600_BPS; - } else if (rate <= 19200) { - rate = 19200; baud_rate = B_19200_BPS; - } else if (rate <= 31250) { - rate = 31250; baud_rate = B_31250_BPS; - } else if (rate <= 38400) { - rate = 38400; baud_rate = B_38400_BPS; - } else if (rate <= 57600) { - rate = 57600; baud_rate = B_57600_BPS; - } - WriteMacInt16(pb + csParam, rate); - acquire_sem(device_sem); - if (device->SetDataRate(baud_rate) == B_OK) { - release_sem(device_sem); - return noErr; - } else { - release_sem(device_sem); - return paramErr; - } - } else - return noErr; - - case kSERDHandshake: - case kSERDHandshakeRS232: - set_handshake(pb + csParam, true); - return noErr; - - case kSERDClockMIDI: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->SetParityMode(B_NO_PARITY); - device->SetDataBits(B_DATA_BITS_8); - device->SetStopBits(B_STOP_BITS_1); - if (device->SetDataRate(B_31250_BPS) == B_OK) { - release_sem(device_sem); - return noErr; - } else { - release_sem(device_sem); - return paramErr; - } - } else - return noErr; - - case kSERDMiscOptions: - drop_dtr_on_close = !(ReadMacInt8(pb + csParam) & kOptionPreserveDTR); - return noErr; - - case kSERDAssertDTR: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->SetDTR(true); - release_sem(device_sem); - } - return noErr; - - case kSERDNegateDTR: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->SetDTR(false); - release_sem(device_sem); - } - return noErr; - - case kSERDSetPEChar: - case kSERDSetPEAltChar: - return noErr; // Not supported under BeOS - - case kSERDResetChannel: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->ClearInput(); - device->ClearOutput(); - release_sem(device_sem); - } - return noErr; - - case kSERDAssertRTS: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->SetRTS(true); - release_sem(device_sem); - } - return noErr; - - case kSERDNegateRTS: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->SetRTS(false); - release_sem(device_sem); - } - return noErr; - - case kSERD115KBaud: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - if (device->DataRate() != B_115200_BPS) - if (device->SetDataRate(B_115200_BPS) != B_OK) { - release_sem(device_sem); - return paramErr; - } - release_sem(device_sem); - } - return noErr; - - case kSERD230KBaud: - case kSERDSetHighSpeed: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - if (device->DataRate() != B_230400_BPS) - if (device->SetDataRate(B_230400_BPS) != B_OK) { - release_sem(device_sem); - return paramErr; - } - release_sem(device_sem); - } - return noErr; - - default: - printf("WARNING: SerialControl(): unimplemented control code %d\n", code); - return controlErr; - } -} - - -/* - * Status calls - */ - -int16 BeSERDPort::status(uint32 pb, uint32 dce, uint16 code) -{ - switch (code) { - case kSERDInputCount: - WriteMacInt32(pb + csParam, 0); - if (!is_parallel) { - int32 num = 0; - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->NumCharsAvailable(&num); - release_sem(device_sem); - D(bug(" %d bytes in buffer\n", num)); - WriteMacInt32(pb + csParam, num); - } - return noErr; - - case kSERDStatus: { - uint32 p = pb + csParam; - WriteMacInt8(p + staCumErrs, cum_errors); - cum_errors = 0; - WriteMacInt8(p + staXOffSent, 0); - WriteMacInt8(p + staXOffHold, 0); - WriteMacInt8(p + staRdPend, read_pending); - WriteMacInt8(p + staWrPend, write_pending); - if (is_parallel) { - WriteMacInt8(p + staCtsHold, 0); - WriteMacInt8(p + staDsrHold, 0); - WriteMacInt8(p + staModemStatus, dsrEvent | dcdEvent | ctsEvent); - } else { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - WriteMacInt8(p + staCtsHold, !device->IsCTS()); - WriteMacInt8(p + staDsrHold, !device->IsDSR()); - WriteMacInt8(p + staModemStatus, - (device->IsDSR() ? dsrEvent : 0) - | (device->IsRI() ? riEvent : 0) - | (device->IsDCD() ? dcdEvent : 0) - | (device->IsCTS() ? ctsEvent : 0)); - release_sem(device_sem); - } - return noErr; - } - - default: - printf("WARNING: SerialStatus(): unimplemented status code %d\n", code); - return statusErr; - } -} - - -/* - * Close serial port - */ - -int16 BeSERDPort::close() -{ - // Kill threads - status_t l; - io_killed = true; - if (input_thread > 0) { - while (send_data(input_thread, CMD_QUIT, NULL, 0) == B_INTERRUPTED) ; - if (read_pending) { - suspend_thread(input_thread); // Unblock thread - snooze(1000); - resume_thread(input_thread); - } - while (wait_for_thread(input_thread, &l) == B_INTERRUPTED) ; - } - if (output_thread > 0) { - while (send_data(output_thread, CMD_QUIT, NULL, 0) == B_INTERRUPTED) ; - if (write_pending) { - suspend_thread(output_thread); // Unblock thread - snooze(1000); - resume_thread(output_thread); - } - while (wait_for_thread(output_thread, &l) == B_INTERRUPTED) ; - } - input_thread = output_thread = 0; - - // Close port - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - if (is_parallel) { - ::close(fd); - fd = -1; - } else { - if (drop_dtr_on_close) - device->SetDTR(false); - device->Close(); - } - release_sem(device_sem); - return noErr; -} - - -/* - * Configure serial port with MacOS config word - */ - -bool BeSERDPort::configure(uint16 config) -{ - D(bug(" configure %04x\n", config)); - if (is_parallel) - return true; - - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - - // Set number of stop bits - switch (config & 0xc000) { - case stop10: - if (device->StopBits() != B_STOP_BITS_1) - device->SetStopBits(B_STOP_BITS_1); - break; - case stop20: - if (device->StopBits() != B_STOP_BITS_2) - device->SetStopBits(B_STOP_BITS_2); - break; - default: - release_sem(device_sem); - return false; - } - - // Set parity mode - switch (config & 0x3000) { - case noParity: - if (device->ParityMode() != B_NO_PARITY) - device->SetParityMode(B_NO_PARITY); - break; - case oddParity: - if (device->ParityMode() != B_ODD_PARITY) - device->SetParityMode(B_ODD_PARITY); - break; - case evenParity: - if (device->ParityMode() != B_EVEN_PARITY) - device->SetParityMode(B_EVEN_PARITY); - break; - default: - release_sem(device_sem); - return false; - } - - // Set number of data bits - switch (config & 0x0c00) { - case data7: - if (device->DataBits() != B_DATA_BITS_7) - device->SetDataBits(B_DATA_BITS_7); - break; - case data8: - if (device->DataBits() != B_DATA_BITS_8) - device->SetDataBits(B_DATA_BITS_8); - break; - default: - release_sem(device_sem); - return false; - } - - // Set baud rate - data_rate baud_rate; - switch (config & 0x03ff) { - case baud150: baud_rate = B_150_BPS; break; - case baud300: baud_rate = B_300_BPS; break; - case baud600: baud_rate = B_600_BPS; break; - case baud1200: baud_rate = B_1200_BPS; break; - case baud1800: baud_rate = B_1800_BPS; break; - case baud2400: baud_rate = B_2400_BPS; break; - case baud4800: baud_rate = B_4800_BPS; break; - case baud9600: baud_rate = B_9600_BPS; break; - case baud19200: baud_rate = B_19200_BPS; break; - case baud38400: baud_rate = B_38400_BPS; break; - case baud57600: baud_rate = B_57600_BPS; break; - default: - release_sem(device_sem); - return false; - } - - D(bug(" baud rate %d, %d stop bits, %s parity, %d data bits\n", baud_rates[baud_rate], device->StopBits() == B_STOP_BITS_1 ? 1 : 2, device->ParityMode() == B_NO_PARITY ? "no" : device->ParityMode() == B_ODD_PARITY ? "odd" : "even", device->DataBits() == B_DATA_BITS_7 ? 7 : 8)); - if (device->DataRate() != baud_rate) { - bool res = device->SetDataRate(baud_rate) == B_OK; - release_sem(device_sem); - return res; - } else { - release_sem(device_sem); - return true; - } -} - - -/* - * Set serial handshaking - */ - -void BeSERDPort::set_handshake(uint32 s, bool with_dtr) -{ - D(bug(" set_handshake %02x %02x %02x %02x %02x %02x %02x %02x\n", - ReadMacInt8(s + 0), ReadMacInt8(s + 1), ReadMacInt8(s + 2), ReadMacInt8(s + 3), - ReadMacInt8(s + 4), ReadMacInt8(s + 5), ReadMacInt8(s + 6), ReadMacInt8(s + 7))); - if (is_parallel) - return; - - uint32 flow; - if (with_dtr) { - if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR)) - flow = B_HARDWARE_CONTROL; - else - flow = B_SOFTWARE_CONTROL; - } else { - if (ReadMacInt8(s + shkFCTS)) - flow = B_HARDWARE_CONTROL; - else - flow = B_SOFTWARE_CONTROL; - } - - D(bug(" %sware flow control\n", flow == B_HARDWARE_CONTROL ? "hard" : "soft")); - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - if (device->FlowControl() != flow) { - device->Close(); - device->SetFlowControl(flow); - device->Open(device_name); - } - release_sem(device_sem); -} - - -/* - * Data input thread - */ - -status_t BeSERDPort::input_func(void *arg) -{ - BeSERDPort *s = (BeSERDPort *)arg; - for (;;) { - - // Wait for commands - thread_id sender; - ThreadPacket p; - uint32 code = receive_data(&sender, &p, sizeof(ThreadPacket)); - if (code == CMD_QUIT) - break; - if (code != CMD_READ) - continue; - - // Execute command - void *buf = Mac2HostAddr(ReadMacInt32(p.pb + ioBuffer)); - uint32 length = ReadMacInt32(p.pb + ioReqCount); - D(bug("input_func waiting for %ld bytes of data...\n", length)); - int32 actual; - - // Buffer in kernel space? - if ((uint32)buf < 0x80000000) { - - // Yes, transfer via buffer - actual = 0; - while (length) { - uint32 transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - int32 transferred; - acquire_sem(s->device_sem); - if (s->is_parallel) { - if ((transferred = read(s->fd, s->tmp_in_buf, transfer_size)) < 0 || s->io_killed) { - // Error - actual = transferred; - release_sem(s->device_sem); - break; - } - } else { - if ((transferred = s->device->Read(s->tmp_in_buf, transfer_size)) < 0 || s->io_killed) { - // Error - actual = transferred; - release_sem(s->device_sem); - break; - } - } - release_sem(s->device_sem); - memcpy(buf, s->tmp_in_buf, transferred); - buf = (void *)((uint8 *)buf + transferred); - length -= transferred; - actual += transferred; - } - - } else { - - // No, transfer directly - acquire_sem(s->device_sem); - if (s->is_parallel) - actual = read(s->fd, buf, length); - else - actual = s->device->Read(buf, length); - release_sem(s->device_sem); - } - - D(bug(" %ld bytes received\n", actual)); - -#if MONITOR - bug("Receiving serial data:\n"); - uint8 *adr = Mac2HostAddr(ReadMacInt32(p.pb + ioBuffer)); - for (int i=0; iio_killed) { - - WriteMacInt16(p.pb + ioResult, abortErr); - WriteMacInt32(p.pb + ioActCount, 0); - s->read_pending = s->read_done = false; - - } else { - - // Set error code - if (actual >= 0) { - WriteMacInt32(p.pb + ioActCount, actual); - WriteMacInt32(s->input_dt + serdtResult, noErr); - } else { - WriteMacInt32(p.pb + ioActCount, 0); - WriteMacInt32(s->input_dt + serdtResult, readErr); - } - - // Trigger serial interrupt - D(bug(" triggering serial interrupt\n")); - s->read_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } - } - return 0; -} - - -/* - * Data output thread - */ - -status_t BeSERDPort::output_func(void *arg) -{ - BeSERDPort *s = (BeSERDPort *)arg; - for (;;) { - - // Wait for commands - thread_id sender; - ThreadPacket p; - uint32 code = receive_data(&sender, &p, sizeof(ThreadPacket)); - if (code == CMD_QUIT) - break; - if (code != CMD_WRITE) - continue; - - // Execute command - void *buf = Mac2HostAddr(ReadMacInt32(p.pb + ioBuffer)); - uint32 length = ReadMacInt32(p.pb + ioReqCount); - D(bug("output_func transmitting %ld bytes of data...\n", length)); - int32 actual; - -#if MONITOR - bug("Sending serial data:\n"); - uint8 *adr = (uint8 *)buf; - for (int i=0; i TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - memcpy(s->tmp_out_buf, buf, transfer_size); - int32 transferred; - acquire_sem(s->device_sem); - if (s->is_parallel) { - if ((transferred = write(s->fd, s->tmp_out_buf, transfer_size)) < transfer_size || s->io_killed) { - if (transferred < 0) // Error - actual = transferred; - else - actual += transferred; - release_sem(s->device_sem); - break; - } - } else { - if ((transferred = s->device->Write(s->tmp_out_buf, transfer_size)) < transfer_size || s->io_killed) { - if (transferred < 0) // Error - actual = transferred; - else - actual += transferred; - release_sem(s->device_sem); - break; - } - } - release_sem(s->device_sem); - if (transferred > transfer_size) // R3 parallel port driver bug - transferred = transfer_size; - buf = (void *)((uint8 *)buf + transferred); - length -= transferred; - actual += transferred; - } - - } else { - - // No, transfer directly - acquire_sem(s->device_sem); - if (s->is_parallel) - actual = write(s->fd, buf, length); - else - actual = s->device->Write(buf, length); - release_sem(s->device_sem); - if (actual > length) // R3 parallel port driver bug - actual = length; - } - - D(bug(" %ld bytes transmitted\n", actual)); - - // KillIO called? Then simply return - if (s->io_killed) { - - WriteMacInt16(p.pb + ioResult, abortErr); - WriteMacInt32(p.pb + ioActCount, 0); - s->write_pending = s->write_done = false; - - } else { - - // Set error code - if (actual >= 0) { - WriteMacInt32(p.pb + ioActCount, actual); - WriteMacInt32(s->output_dt + serdtResult, noErr); - } else { - WriteMacInt32(p.pb + ioActCount, 0); - WriteMacInt32(s->output_dt + serdtResult, writErr); - } - - // Trigger serial interrupt - D(bug(" triggering serial interrupt\n")); - s->write_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } - } - return 0; -} diff --git a/BasiliskII/src/BeOS/sys_beos.cpp b/BasiliskII/src/BeOS/sys_beos.cpp deleted file mode 100644 index ff6fcb83..00000000 --- a/BasiliskII/src/BeOS/sys_beos.cpp +++ /dev/null @@ -1,841 +0,0 @@ -/* - * sys_beos.cpp - System dependent routines, BeOS implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "sys.h" - -#define DEBUG 0 -#include "debug.h" - -#ifdef __HAIKU__ -#include -#define unmount(x) fs_unmount_volume(x, 0) -#endif - - -// File handles are pointers to these structures -struct file_handle { - file_handle *next; // Pointer to next file handle (must be first in struct!) - const char *name; // File/device name (copied, for mount menu) - int fd; // fd of file/device - bool is_file; // Flag: plain file or /dev/something? - bool read_only; // Copy of Sys_open() flag - loff_t start_byte; // Size of file header (if any) - loff_t file_size; // Size of file data (only valid if is_file is true) -}; - -// Linked list of file handles -static file_handle *first_file_handle; - -// Temporary buffer for transfers from/to kernel space -const int TMP_BUF_SIZE = 0x10000; -static uint8 *tmp_buf; - -// For B_SCSI_PREVENT_ALLOW -static const int32 PREVENT = 1; -static const int32 ALLOW = 0; - - -/* - * Check if device is a mounted HFS volume, get mount name - */ - -static bool is_drive_mounted(const char *dev_name, char *mount_name) -{ - int32 i = 0; - dev_t d; - fs_info info; - while ((d = next_dev(&i)) >= 0) { - fs_stat_dev(d, &info); - if (strcmp(dev_name, info.device_name) == 0) { - status_t err = -1; - BPath mount; - BDirectory dir; - BEntry entry; - node_ref node; - node.device = info.dev; - node.node = info.root; - err = dir.SetTo(&node); - if (!err) - err = dir.GetEntry(&entry); - if (!err) - err = entry.GetPath(&mount); - if (!err) { - strcpy(mount_name, mount.Path()); - return true; - } - } - } - return false; -} - - -/* - * Initialization - */ - -void SysInit(void) -{ - first_file_handle = NULL; - - // Allocate temporary buffer - tmp_buf = new uint8[TMP_BUF_SIZE]; -} - - -/* - * Deinitialization - */ - -void SysExit(void) -{ - delete[] tmp_buf; -} - - -/* - * Create menu of used volumes (for "mount" menu) - */ - -void SysCreateVolumeMenu(BMenu *menu, uint32 msg) -{ - for (file_handle *fh=first_file_handle; fh; fh=fh->next) - if (!SysIsFixedDisk(fh)) - menu->AddItem(new BMenuItem(fh->name, new BMessage(msg))); -} - - -/* - * Mount volume given name from mount menu - */ - -void SysMountVolume(const char *name) -{ - file_handle *fh; - for (fh=first_file_handle; fh && strcmp(fh->name, name); fh=fh->next) ; - if (fh) - MountVolume(fh); -} - - -/* - * This gets called when no "floppy" prefs items are found - * It scans for available floppy drives and adds appropriate prefs items - */ - -void SysAddFloppyPrefs(void) -{ - // Only one floppy drive under BeOS - PrefsAddString("floppy", "/dev/disk/floppy/raw"); -} - - -/* - * This gets called when no "disk" prefs items are found - * It scans for available HFS volumes and adds appropriate prefs items - */ - -void SysAddDiskPrefs(void) -{ - // Let BeOS scan for HFS drives - D(bug("Looking for Mac volumes...\n")); - system("mountvolume -allhfs"); - - // Add all HFS volumes - int32 i = 0; - dev_t d; - fs_info info; - while ((d = next_dev(&i)) >= 0) { - fs_stat_dev(d, &info); - status_t err = -1; - BPath mount; - if (!strcmp(info.fsh_name, "hfs")) { - BDirectory dir; - BEntry entry; - node_ref node; - node.device = info.dev; - node.node = info.root; - err = dir.SetTo(&node); - if (!err) - err = dir.GetEntry(&entry); - if (!err) - err = entry.GetPath(&mount); - } - if (!err) - err = unmount(mount.Path()); - if (!err) { - char dev_name[B_FILE_NAME_LENGTH]; - if (info.flags & B_FS_IS_READONLY) { - dev_name[0] = '*'; - dev_name[1] = 0; - } else - dev_name[0] = 0; - strcat(dev_name, info.device_name); - PrefsAddString("disk", dev_name); - } - } -} - - -/* - * This gets called when no "cdrom" prefs items are found - * It scans for available CD-ROM drives and adds appropriate prefs items - */ - -// Scan directory for CD-ROM drives, add them to prefs -static void scan_for_cdrom_drives(const char *directory) -{ - // Set directory - BDirectory dir; - dir.SetTo(directory); - if (dir.InitCheck() != B_NO_ERROR) - return; - dir.Rewind(); - - // Scan each entry - BEntry entry; - while (dir.GetNextEntry(&entry) >= 0) { - - // Get path and ref for entry - BPath path; - if (entry.GetPath(&path) != B_NO_ERROR) - continue; - const char *name = path.Path(); - entry_ref e; - if (entry.GetRef(&e) != B_NO_ERROR) - continue; - - // Recursively enter subdirectories (except for floppy) - if (entry.IsDirectory()) { - if (!strcmp(e.name, "floppy")) - continue; - scan_for_cdrom_drives(name); - } else { - - D(bug(" checking '%s'\n", name)); - - // Ignore partitions - if (strcmp(e.name, "raw")) - continue; - - // Open device - int fd = open(name, O_RDONLY); - if (fd < 0) - continue; - - // Get geometry and device type - device_geometry g; - if (ioctl(fd, B_GET_GEOMETRY, &g, sizeof(g)) < 0) { - close(fd); - continue; - } - - // Insert to list if it is a CD drive - if (g.device_type == B_CD) - PrefsAddString("cdrom", name); - close(fd); - } - } -} - -void SysAddCDROMPrefs(void) -{ - // Don't scan for drives if nocdrom option given - if (PrefsFindBool("nocdrom")) - return; - - // Look for CD-ROM drives and add prefs items - D(bug("Looking for CD-ROM drives...\n")); - scan_for_cdrom_drives("/dev/disk"); -} - - -/* - * Add default serial prefs (must be added, even if no ports present) - */ - -void SysAddSerialPrefs(void) -{ -#ifdef __HAIKU__ - PrefsAddString("seriala", "serial1"); - PrefsAddString("serialb", "serial2"); -#else - system_info info; - get_system_info(&info); - switch (info.platform_type) { - case B_BEBOX_PLATFORM: - case B_AT_CLONE_PLATFORM: - PrefsAddString("seriala", "serial1"); - PrefsAddString("serialb", "serial2"); - break; - case B_MAC_PLATFORM: - PrefsAddString("seriala", "modem"); - PrefsAddString("serialb", "printer"); - break; - default: - PrefsAddString("seriala", "none"); - PrefsAddString("serialb", "none"); - break; - } -#endif -} - - -/* - * Open file/device, create new file handle (returns NULL on error) - */ - -void *Sys_open(const char *name, bool read_only) -{ - static bool published_all = false; - bool is_file = (strstr(name, "/dev/") != name); - - D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write")); - - // Print warning message and eventually unmount drive when this is an HFS volume mounted under BeOS (double mounting will corrupt the volume) - char mount_name[B_FILE_NAME_LENGTH]; - if (!is_file && !read_only && is_drive_mounted(name, mount_name)) { - char str[256 + B_FILE_NAME_LENGTH]; - sprintf(str, GetString(STR_VOLUME_IS_MOUNTED_WARN), mount_name); - WarningAlert(str); - if (unmount(mount_name) != 0) { - sprintf(str, GetString(STR_CANNOT_UNMOUNT_WARN), mount_name); - WarningAlert(str); - return NULL; - } - } - - int fd = open(name, read_only ? O_RDONLY : O_RDWR); - if (fd < 0 && !published_all) { - // Open failed, create all device nodes and try again, but only the first time - system("mountvolume -publishall"); - published_all = true; - fd = open(name, read_only ? O_RDONLY : O_RDWR); - } - if (fd >= 0) { - file_handle *fh = new file_handle; - fh->name = strdup(name); - fh->fd = fd; - fh->is_file = is_file; - fh->read_only = read_only; - fh->start_byte = 0; - if (fh->is_file) { - // Detect disk image file layout - loff_t size = lseek(fd, 0, SEEK_END); - uint8 data[256]; - lseek(fd, 0, SEEK_SET); - read(fd, data, 256); - FileDiskLayout(size, data, fh->start_byte, fh->file_size); - } - - // Enqueue file handle - fh->next = NULL; - file_handle *q = first_file_handle; - if (q) { - while (q->next) - q = q->next; - q->next = fh; - } else - first_file_handle = fh; - return fh; - } else - return NULL; -} - - -/* - * Close file/device, delete file handle - */ - -void Sys_close(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - // Free device name and close file/device - free((void *)fh->name); - close(fh->fd); - - // Dequeue file handle - file_handle *q = first_file_handle; - if (q == fh) { - first_file_handle = NULL; - delete fh; - return; - } - while (q) { - if (q->next == fh) { - q->next = fh->next; - delete fh; - return; - } - q = q->next; - } -} - - -/* - * Read "length" bytes from file/device, starting at "offset", to "buffer", - * returns number of bytes read (or 0) - */ - -static inline ssize_t sread(int fd, void *buf, size_t count) -{ - ssize_t res; - while ((res = read(fd, buf, count)) == B_INTERRUPTED) ; - return res; -} - -size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return 0; - -// D(bug("Sys_read(%08lx, %08lx, %Ld, %d)\n", fh, buffer, offset, length)); - - // Seek to position - if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0) - return 0; - - // Buffer in kernel space? - size_t actual = 0; - if ((uint32)buffer < 0x80000000) { - - // Yes, transfer via buffer - while (length) { - size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - if (sread(fh->fd, tmp_buf, transfer_size) != transfer_size) - return actual; - memcpy(buffer, tmp_buf, transfer_size); - buffer = (void *)((uint8 *)buffer + transfer_size); - length -= transfer_size; - actual += transfer_size; - } - - } else { - - // No, transfer directly - actual = sread(fh->fd, buffer, length); - if (actual < 0) - actual = 0; - } - return actual; -} - - -/* - * Write "length" bytes from "buffer" to file/device, starting at "offset", - * returns number of bytes written (or 0) - */ - -static inline ssize_t swrite(int fd, void *buf, size_t count) -{ - ssize_t res; - while ((res = write(fd, buf, count)) == B_INTERRUPTED) ; - return res; -} - -size_t Sys_write(void *arg, void *buffer, loff_t offset, size_t length) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return 0; - -// D(bug("Sys_write(%08lx, %08lx, %Ld, %d)\n", fh, buffer, offset, length)); - - // Seek to position - if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0) - return 0; - - // Buffer in kernel space? - size_t actual = 0; - if ((uint32)buffer < 0x80000000) { - - // Yes, transfer via buffer - while (length) { - size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - memcpy(tmp_buf, buffer, transfer_size); - if (swrite(fh->fd, tmp_buf, transfer_size) != transfer_size) - return actual; - buffer = (void *)((uint8 *)buffer + transfer_size); - length -= transfer_size; - actual += transfer_size; - } - - } else { - - // No, transfer directly - actual = swrite(fh->fd, buffer, length); - if (actual < 0) - actual = 0; - } - return actual; -} - - -/* - * Return size of file/device (minus header) - */ - -loff_t SysGetFileSize(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (fh->is_file) - return fh->file_size; - else { - device_geometry g; - if (ioctl(fh->fd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0) - return (loff_t)g.bytes_per_sector * g.sectors_per_track * g.cylinder_count * g.head_count; - else - return 0; - } -} - - -/* - * Eject volume (if applicable) - */ - -void SysEject(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) - ioctl(fh->fd, B_EJECT_DEVICE); -} - - -/* - * Format volume (if applicable) - */ - -bool SysFormat(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) - return ioctl(fh->fd, B_FORMAT_DEVICE) >= 0; - else - return false; -} - - -/* - * Check if file/device is read-only (this includes the read-only flag on Sys_open()) - */ - -bool SysIsReadOnly(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (fh->is_file) { - - // File, return flag given to Sys_open - return fh->read_only; - - } else { - - // Device, check write protection - device_geometry g; - if (ioctl(fh->fd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0) - return g.read_only | fh->read_only; - else - return fh->read_only; // Removable but not inserted - } -} - - -/* - * Check if the given file handle refers to a fixed or a removable disk - */ - -bool SysIsFixedDisk(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (fh->is_file) - return true; - else { - device_geometry g; - if (ioctl(fh->fd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0) - return !g.removable; - else - return false; // Removable but not inserted - } -} - - -/* - * Check if a disk is inserted in the drive (always true for files) - */ - -bool SysIsDiskInserted(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return true; - else { - status_t l; - if (ioctl(fh->fd, B_GET_MEDIA_STATUS, &l, sizeof(l)) >= 0 && l == B_NO_ERROR) - return true; - else - return false; - } -} - - -/* - * Prevent medium removal (if applicable) - */ - -void SysPreventRemoval(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) - ioctl(fh->fd, B_SCSI_PREVENT_ALLOW, &PREVENT, sizeof(PREVENT)); -} - - -/* - * Allow medium removal (if applicable) - */ - -void SysAllowRemoval(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) - ioctl(fh->fd, B_SCSI_PREVENT_ALLOW, &ALLOW, sizeof(ALLOW)); -} - - -/* - * Read CD-ROM TOC (binary MSF format, 804 bytes max.) - */ - -bool SysCDReadTOC(void *arg, uint8 *toc) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) { - memset(tmp_buf, 0, 804); - if (ioctl(fh->fd, B_SCSI_GET_TOC, tmp_buf, 804) < 0) - return false; - memcpy(toc, tmp_buf, 804); - return true; - } else - return false; -} - - -/* - * Read CD-ROM position data (Sub-Q Channel, 16 bytes, see SCSI standard) - */ - -bool SysCDGetPosition(void *arg, uint8 *pos) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) { - if (ioctl(fh->fd, B_SCSI_GET_POSITION, tmp_buf, 16) < 0) - return false; - memcpy(pos, tmp_buf, 16); - return true; - } else - return false; -} - - -/* - * Play CD audio - */ - -bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end_m, uint8 end_s, uint8 end_f) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) { - scsi_play_position *p = (scsi_play_position *)tmp_buf; - p->start_m = start_m; - p->start_s = start_s; - p->start_f = start_f; - p->end_m = end_m; - p->end_s = end_s; - p->end_f = end_f; - return ioctl(fh->fd, B_SCSI_PLAY_POSITION, p, sizeof(scsi_play_position)) == 0; - } else - return false; -} - - -/* - * Pause CD audio - */ - -bool SysCDPause(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (!fh->is_file) - return ioctl(fh->fd, B_SCSI_PAUSE_AUDIO) == 0; - else - return false; -} - - -/* - * Resume paused CD audio - */ - -bool SysCDResume(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) - return ioctl(fh->fd, B_SCSI_RESUME_AUDIO) == 0; - else - return false; -} - - -/* - * Stop CD audio - */ - -bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) - return ioctl(fh->fd, B_SCSI_STOP_AUDIO) == 0; - else - return false; -} - - -/* - * Perform CD audio fast-forward/fast-reverse operation starting from specified address - */ - -bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) { - scsi_scan *p = (scsi_scan *)tmp_buf; - p->speed = 0; - p->direction = reverse ? -1 : 1; - return ioctl(fh->fd, B_SCSI_SCAN, p, sizeof(scsi_scan)) == 0; - } else - return false; -} - - -/* - * Set CD audio volume (0..255 each channel) - */ - -void SysCDSetVolume(void *arg, uint8 left, uint8 right) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - scsi_volume *p = (scsi_volume *)tmp_buf; - p->flags = B_SCSI_PORT0_VOLUME | B_SCSI_PORT1_VOLUME; - p->port0_volume = left; - p->port1_volume = right; - ioctl(fh->fd, B_SCSI_SET_VOLUME, p, sizeof(scsi_volume)); - } -} - - -/* - * Get CD audio volume (0..255 each channel) - */ - -void SysCDGetVolume(void *arg, uint8 &left, uint8 &right) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - left = right = 0; - if (!fh->is_file) { - scsi_volume *p = (scsi_volume *)tmp_buf; - p->flags = B_SCSI_PORT0_VOLUME | B_SCSI_PORT1_VOLUME; - if (ioctl(fh->fd, B_SCSI_GET_VOLUME, p, sizeof(scsi_volume)) == 0) { - left = p->port0_volume; - right = p->port1_volume; - } - } -} diff --git a/BasiliskII/src/BeOS/sysdeps.h b/BasiliskII/src/BeOS/sysdeps.h deleted file mode 100644 index ed3ba9c3..00000000 --- a/BasiliskII/src/BeOS/sysdeps.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * sysdeps.h - System dependent definitions for BeOS - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SYSDEPS_H -#define SYSDEPS_H - -#ifdef __POWERPC__ -#define NO_STD_NAMESPACE -#endif - -#include -#include -#include - -#include "user_strings_beos.h" - -// Are the Mac and the host address space the same? -#ifdef __i386__ -#define REAL_ADDRESSING 0 -#undef WORDS_BIGENDIAN -#else -#define REAL_ADDRESSING 1 -#define WORDS_BIGENDIAN 1 -#endif - -// Using 68k emulator -#define EMULATED_68K 1 - -// Mac ROM is write protected -#define ROM_IS_WRITE_PROTECTED 1 - -// ExtFS is supported -#define SUPPORTS_EXTFS 1 - -// BSD socket API is supported -#define SUPPORTS_UDP_TUNNEL 1 - -// mon is not supported -#undef ENABLE_MON - -// Time data type for Time Manager emulation -typedef bigtime_t tm_time_t; - -// 64 bit file offsets -typedef off_t loff_t; - -// Networking types -#define PF_INET AF_INET -#ifndef __HAIKU__ -typedef int socklen_t; -#endif - -// UAE CPU data types -#define uae_s8 int8 -#define uae_u8 uint8 -#define uae_s16 int16 -#define uae_u16 uint16 -#define uae_s32 int32 -#define uae_u32 uint32 -#define uae_s64 int64 -#define uae_u64 uint64 -typedef uae_u32 uaecptr; -#define VAL64(a) (a ## LL) -#define UVAL64(a) (a ## uLL) -typedef uint32 uintptr; -typedef int32 intptr; - -/* Timing functions */ -extern void Delay_usec(uint32 usec); - -// UAE CPU defines -#ifdef __i386__ - -// Intel x86 assembler optimizations -#define X86_PPRO_OPT -static inline uae_u32 do_get_mem_long(uae_u32 *a) {uint32 retval; __asm__ ("bswap %0" : "=r" (retval) : "0" (*a) : "cc"); return retval;} -#ifdef X86_PPRO_OPT -static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint32 retval; __asm__ ("movzwl %w1,%k0\n\tshll $16,%k0\n\tbswap %k0\n" : "=&r" (retval) : "m" (*a) : "cc"); return retval;} -#else -static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint32 retval; __asm__ ("xorl %k0,%k0\n\tmovw %w1,%w0\n\trolw $8,%w0" : "=&r" (retval) : "m" (*a) : "cc"); return retval;} -#endif -#define HAVE_GET_WORD_UNSWAPPED -#define do_get_mem_word_unswapped(a) ((uae_u32)*((uae_u16 *)(a))) -static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {__asm__ ("bswap %0" : "=r" (v) : "0" (v) : "cc"); *a = v;} -#ifdef X86_PPRO_OPT -static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {__asm__ ("bswap %0" : "=&r" (v) : "0" (v << 16) : "cc"); *a = v;} -#else -static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {__asm__ ("rolw $8,%0" : "=r" (v) : "0" (v) : "cc"); *a = v;} -#endif - -#define X86_ASSEMBLY -#define UNALIGNED_PROFITABLE -#define OPTIMIZED_FLAGS -#define ASM_SYM(a) __asm__(a) -#define REGPARAM __attribute__((regparm(3))) - -#else - -// PowerPC (memory.cpp not used, so no optimization neccessary) -static inline uae_u32 do_get_mem_long(uae_u32 *a) {return *a;} -static inline uae_u32 do_get_mem_word(uae_u16 *a) {return *a;} -static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {*a = v;} -static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {*a = v;} - -#undef X86_ASSEMBLY -#define UNALIGNED_PROFITABLE -#undef OPTIMIZED_FLAGS -#define ASM_SYM(a) -#define REGPARAM -#endif - -#define do_get_mem_byte(a) ((uae_u32)*((uae_u8 *)(a))) -#define do_put_mem_byte(a, v) (*(uae_u8 *)(a) = (v)) - -#define call_mem_get_func(func, addr) ((*func)(addr)) -#define call_mem_put_func(func, addr, v) ((*func)(addr, v)) -#define __inline__ inline -#define CPU_EMU_SIZE 0 -#undef NO_INLINE_MEMORY_ACCESS -#undef MD_HAVE_MEM_1_FUNCS -#undef USE_COMPILER -#define REGPARAM2 -#define ENUMDECL typedef enum -#define ENUMNAME(name) name -#define write_log printf - -#endif diff --git a/BasiliskII/src/BeOS/timer_beos.cpp b/BasiliskII/src/BeOS/timer_beos.cpp deleted file mode 100644 index f6e71b50..00000000 --- a/BasiliskII/src/BeOS/timer_beos.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * timer_beos.cpp - Time Manager emulation, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include "sysdeps.h" -#include "macos_util.h" -#include "timer.h" - -#define DEBUG 0 -#include "debug.h" - - -// From main_beos.cpp -extern thread_id emul_thread; - - -/* - * Return microseconds since boot (64 bit) - */ - -void Microseconds(uint32 &hi, uint32 &lo) -{ - D(bug("Microseconds\n")); - bigtime_t time = system_time(); - hi = time >> 32; - lo = time; -} - - -/* - * Return local date/time in Mac format (seconds since 1.1.1904) - */ - -uint32 TimerDateTime(void) -{ - return TimeToMacTime(time(NULL)); -} - - -/* - * Get current time - */ - -void timer_current_time(tm_time_t &t) -{ - t = system_time(); -} - - -/* - * Add times - */ - -void timer_add_time(tm_time_t &res, tm_time_t a, tm_time_t b) -{ - res = a + b; -} - - -/* - * Subtract times - */ - -void timer_sub_time(tm_time_t &res, tm_time_t a, tm_time_t b) -{ - res = a - b; -} - - -/* - * Compare times (<0: a < b, =0: a = b, >0: a > b) - */ - -int timer_cmp_time(tm_time_t a, tm_time_t b) -{ - tm_time_t r = a - b; - return r < 0 ? -1 : (r > 0 ? 1 : 0); -} - - -/* - * Convert Mac time value (>0: microseconds, <0: microseconds) to tm_time_t - */ - -void timer_mac2host_time(tm_time_t &res, int32 mactime) -{ - if (mactime > 0) - res = mactime * 1000; // Time in milliseconds - else - res = -mactime; // Time in negative microseconds -} - - -/* - * Convert positive tm_time_t to Mac time value (>0: microseconds, <0: microseconds) - * A negative input value for hosttime results in a zero return value - * As long as the microseconds value fits in 32 bit, it must not be converted to milliseconds! - */ - -int32 timer_host2mac_time(tm_time_t hosttime) -{ - if (hosttime < 0) - return 0; - else if (hosttime > 0x7fffffff) - return hosttime / 1000; // Time in milliseconds - else - return -hosttime; // Time in negative microseconds -} - - -/* - * Delay by specified number of microseconds (<1 second) - */ - -void Delay_usec(uint32 usec) -{ - snooze(usec); -} - - -/* - * Suspend emulator thread, virtual CPU in idle mode - */ - -void idle_wait(void) -{ -#if 0 - /* - FIXME: add a semaphore (counter) to avoid a B_BAD_THREAD_STATE - return if we call idle_resume() when thread is not suspended? - - Sorry, I can't test -- gb. - */ - suspend_thread(emul_thread); -#endif -} - - -/* - * Resume execution of emulator thread, events just arrived - */ - -void idle_resume(void) -{ -#if 0 - resume_thread(emul_thread); -#endif -} diff --git a/BasiliskII/src/BeOS/user_strings_beos.cpp b/BasiliskII/src/BeOS/user_strings_beos.cpp deleted file mode 100644 index c3694578..00000000 --- a/BasiliskII/src/BeOS/user_strings_beos.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * user_strings_beos.cpp - BeOS-specific localizable strings - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "user_strings.h" - - -// Platform-specific string definitions -user_string_def platform_strings[] = { - // Common strings that have a platform-specific variant - {STR_VOLUME_IS_MOUNTED_WARN, "The volume '%s' is mounted under BeOS. Basilisk II will try to unmount it."}, - {STR_EXTFS_CTRL, "BeOS Root"}, - {STR_EXTFS_NAME, "BeOS Directory Tree"}, - {STR_EXTFS_VOLUME_NAME, "BeOS"}, - - // Purely platform-specific strings - {STR_NO_SHEEP_DRIVER_ERR, "Cannot open /dev/sheep: %s (%08x). Basilisk II is not properly installed."}, - {STR_SHEEP_UP_ERR, "Cannot allocate Low Memory Globals: %s (%08x)."}, - {STR_NO_KERNEL_DATA_ERR, "Cannot create Kernel Data area: %s (%08x)."}, - {STR_NO_NET_ADDON_WARN, "The SheepShaver net server add-on cannot be found. Ethernet will not be available."}, - {STR_NET_CONFIG_MODIFY_WARN, "To enable Ethernet networking for Basilisk II, your network configuration has to be modified and the network restarted. Do you want this to be done now (selecting \"Cancel\" will disable Ethernet under Basilisk II)?."}, - {STR_NET_ADDON_INIT_FAILED, "SheepShaver net server add-on found\nbut there seems to be no network hardware.\nPlease check your network preferences."}, - {STR_NET_ADDON_CLONE_FAILED, "Cloning of the network transfer area failed."}, - {STR_VIDEO_FAILED, "Failed to set video mode."}, - - {-1, NULL} // End marker -}; - - -/* - * Fetch pointer to string, given the string number - */ - -const char *GetString(int num) -{ - // First search for platform-specific string - int i = 0; - while (platform_strings[i].num >= 0) { - if (platform_strings[i].num == num) - return platform_strings[i].str; - i++; - } - - // Not found, search for common string - i = 0; - while (common_strings[i].num >= 0) { - if (common_strings[i].num == num) - return common_strings[i].str; - i++; - } - return NULL; -} diff --git a/BasiliskII/src/BeOS/user_strings_beos.h b/BasiliskII/src/BeOS/user_strings_beos.h deleted file mode 100644 index 8de695e9..00000000 --- a/BasiliskII/src/BeOS/user_strings_beos.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * user_strings_beos.h - BeOS-specific localizable strings - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef USER_STRINGS_BEOS_H -#define USER_STRINGS_BEOS_H - -enum { - STR_NO_SHEEP_DRIVER_ERR = 10000, - STR_SHEEP_UP_ERR, - STR_NO_KERNEL_DATA_ERR, - STR_NO_NET_ADDON_WARN, - STR_NET_CONFIG_MODIFY_WARN, - STR_NET_ADDON_INIT_FAILED, - STR_NET_ADDON_CLONE_FAILED, - STR_VIDEO_FAILED -}; - -#endif diff --git a/BasiliskII/src/BeOS/video_beos.cpp b/BasiliskII/src/BeOS/video_beos.cpp deleted file mode 100644 index d70ad834..00000000 --- a/BasiliskII/src/BeOS/video_beos.cpp +++ /dev/null @@ -1,1086 +0,0 @@ -/* - * video_beos.cpp - Video/graphics emulation, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * Portions written by Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "adb.h" -#include "prefs.h" -#include "user_strings.h" -#include "about_window.h" -#include "video.h" - -#include "m68k.h" -#include "memory.h" -#include "readcpu.h" -#include "newcpu.h" - -#define DEBUG 0 -#include "debug.h" - -#define DEBUGGER_AVAILABLE 0 - - -// Messages -const uint32 MSG_REDRAW = 'draw'; -const uint32 MSG_ABOUT_REQUESTED = B_ABOUT_REQUESTED; -const uint32 MSG_REF_5HZ = ' 5Hz'; -const uint32 MSG_REF_7_5HZ = ' 7Hz'; -const uint32 MSG_REF_10HZ = '10Hz'; -const uint32 MSG_REF_15HZ = '15Hz'; -const uint32 MSG_REF_30HZ = '30Hz'; -const uint32 MSG_REF_60HZ = '60Hz'; -const uint32 MSG_MOUNT = 'moun'; -const uint32 MSG_DEBUGGER = 'dbug'; - -// Display types -enum { - DISPLAY_WINDOW, - DISPLAY_SCREEN -}; - -// From sys_beos.cpp -extern void SysCreateVolumeMenu(BMenu *menu, uint32 msg); -extern void SysMountVolume(const char *name); - -// Global variables -static bool classic_mode = false; // Flag: Classic Mac video mode -static int scr_mode_bit = 0; -static vector VideoModes; // Supported video modes - - /* - * monitor_desc subclass for BeOS display - */ - -class BeOS_monitor_desc : public monitor_desc { -public: - BeOS_monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) : monitor_desc(available_modes, default_depth, default_id) {} - ~BeOS_monitor_desc() {} - - virtual void switch_to_current_mode(void); - virtual void set_palette(uint8 *pal, int num); - - bool video_open(void); - void video_close(void); -}; - - -/* - * A simple view class for blitting a bitmap on the screen - */ - -class BitmapView : public BView { -public: - BitmapView(BRect frame, BBitmap *bitmap) : BView(frame, "bitmap", B_FOLLOW_NONE, B_WILL_DRAW) - { - the_bitmap = bitmap; - } - virtual void Draw(BRect update) - { - DrawBitmap(the_bitmap, update, update); - } - virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *message); - -private: - BBitmap *the_bitmap; -}; - - -/* - * Window class - */ - -class MacWindow : public BDirectWindow { -public: - MacWindow(BRect frame, const BeOS_monitor_desc& monitor); - virtual ~MacWindow(); - virtual void MessageReceived(BMessage *msg); - virtual void DirectConnected(direct_buffer_info *info); - virtual void WindowActivated(bool active); - - int32 frame_skip; - bool mouse_in_view; // Flag: Mouse pointer within bitmap view - uint8 remap_mac_be[256]; // For remapping of Mac colors to Be colors - -private: - static status_t tick_func(void *arg); - - thread_id tick_thread; - bool tick_thread_active; // Flag for quitting the tick thread - - BitmapView *main_view; // Main view for bitmap drawing - BBitmap *the_bitmap; // Mac screen bitmap - - uint32 old_scroll_lock_state; - - bool supports_direct_mode; // Flag: Direct frame buffer access supported - sem_id drawing_sem; - - void *bits; - int32 bytes_per_row; - color_space pixel_format; - bool unclipped; - - BeOS_monitor_desc monitor; -}; - - -/* - * Screen class - */ - -class MacScreen : public BWindowScreen { -public: - MacScreen(const BeOS_monitor_desc& monitor, const char *name, int mode_bit, status_t *error); - virtual ~MacScreen(); - virtual void Quit(void); - virtual void ScreenConnected(bool active); - - rgb_color palette[256]; // Color palette, 256 entries - bool palette_changed; - -private: - static status_t tick_func(void *arg); - - thread_id tick_thread; - bool tick_thread_active; // Flag for quitting the tick thread - - BView *main_view; // Main view for GetMouse() - uint8 *frame_backup; // Frame buffer backup when switching from/to different workspace - bool quitting; // Flag for ScreenConnected: We are quitting, don't pause emulator thread - bool screen_active; - bool first_time; - - BeOS_monitor_desc monitor; -}; - - -// Global variables -static int display_type = DISPLAY_WINDOW; // See enum above -static MacWindow *the_window = NULL; // Pointer to the window -static MacScreen *the_screen = NULL; // Pointer to the screen -static sem_id mac_os_lock = -1; // This is used to stop the MacOS thread when the Basilisk workspace is switched out -static uint8 MacCursor[68] = {16, 1}; // Mac cursor image - - -/* - * Initialization - */ - -// Add mode to list of supported modes -static void add_mode(uint32 width, uint32 height, uint32 resolution_id, uint32 bytes_per_row, video_depth depth) -{ - video_mode mode; - mode.x = width; - mode.y = height; - mode.resolution_id = resolution_id; - mode.bytes_per_row = bytes_per_row; - mode.depth = depth; - VideoModes.push_back(mode); -} - -// Add standard list of windowed modes for given color depth -static void add_window_modes(video_depth depth) -{ -#if 0 - add_mode(512, 384, 0x80, TrivialBytesPerRow(512, depth), depth); - add_mode(640, 480, 0x81, TrivialBytesPerRow(640, depth), depth); - add_mode(800, 600, 0x82, TrivialBytesPerRow(800, depth), depth); - add_mode(1024, 768, 0x83, TrivialBytesPerRow(1024, depth), depth); - add_mode(1152, 870, 0x84, TrivialBytesPerRow(1152, depth), depth); - add_mode(1280, 1024, 0x85, TrivialBytesPerRow(1280, depth), depth); - add_mode(1600, 1200, 0x86, TrivialBytesPerRow(1600, depth), depth); -#endif -} - - - -bool VideoInit(bool classic) -{ - classic_mode = classic; - - // Get screen mode from preferences - const char *mode_str; - if (classic_mode) - mode_str = "win/512/342"; - else - mode_str = PrefsFindString("screen"); - - // Determine type and mode - int default_width = 512, default_height = 384; - display_type = DISPLAY_WINDOW; - if (mode_str) { - if (sscanf(mode_str, "win/%d/%d", &default_width, &default_height) == 2) - display_type = DISPLAY_WINDOW; - else if (sscanf(mode_str, "scr/%d", &scr_mode_bit) == 1) - display_type = DISPLAY_SCREEN; - } -#if 0 - if (default_width <= 0) - default_width = DisplayWidth(x_display, screen); - else if (default_width > DisplayWidth(x_display, screen)) - default_width = DisplayWidth(x_display, screen); - if (default_height <= 0) - default_height = DisplayHeight(x_display, screen); - else if (default_height > DisplayHeight(x_display, screen)) - default_height = DisplayHeight(x_display, screen); -#endif - - // Mac screen depth follows BeOS depth - video_depth default_depth = VDEPTH_1BIT; - switch (BScreen().ColorSpace()) { - case B_CMAP8: - default_depth = VDEPTH_8BIT; - break; - case B_RGB15: - default_depth = VDEPTH_16BIT; - break; - case B_RGB32: - default_depth = VDEPTH_32BIT; - break; - default: - fprintf(stderr, "Unknown color space!"); - } - - // Construct list of supported modes - if (display_type == DISPLAY_WINDOW) { - if (classic) - add_mode(512, 342, 0x80, 64, VDEPTH_1BIT); - else { - add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth); -#if 0 - for (unsigned d=VDEPTH_1BIT; d<=VDEPTH_32BIT; d++) { - if (find_visual_for_depth(video_depth(d))) - add_window_modes(video_depth(d)); - } -#endif - } - } else - add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth); - if (VideoModes.empty()) { - ErrorAlert(STR_VIDEO_FAILED); - return false; - } - - // Find requested default mode with specified dimensions - uint32 default_id; - std::vector::const_iterator i, end = VideoModes.end(); - for (i = VideoModes.begin(); i != end; ++i) { - if (i->x == default_width && i->y == default_height && i->depth == default_depth) { - default_id = i->resolution_id; - break; - } - } - if (i == end) { // not found, use first available mode - default_depth = VideoModes[0].depth; - default_id = VideoModes[0].resolution_id; - } - -#if DEBUG - D(bug("Available video modes:\n")); - for (i = VideoModes.begin(); i != end; ++i) { - int bits = 1 << i->depth; - if (bits == 16) - bits = 15; - else if (bits == 32) - bits = 24; - D(bug(" %dx%d (ID %02x), %d colors\n", i->x, i->y, i->resolution_id, 1 << bits)); - } -#endif - - // Create X11_monitor_desc for this (the only) display - BeOS_monitor_desc *monitor = new BeOS_monitor_desc(VideoModes, default_depth, default_id); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); -} - -bool BeOS_monitor_desc::video_open() { - // Create semaphore - mac_os_lock = create_sem(0, "MacOS Frame Buffer Lock"); - - const video_mode &mode = get_current_mode(); - - // Open display - switch (display_type) { - case DISPLAY_WINDOW: - the_window = new MacWindow(BRect(0, 0, mode.x-1, mode.y-1), *this); - break; - case DISPLAY_SCREEN: { - status_t screen_error; - the_screen = new MacScreen(*this, GetString(STR_WINDOW_TITLE), scr_mode_bit & 0x1f, &screen_error); - if (screen_error != B_NO_ERROR) { - the_screen->PostMessage(B_QUIT_REQUESTED); - while (the_screen) - snooze(200000); - ErrorAlert(STR_OPEN_SCREEN_ERR); - return false; - } else { - the_screen->Show(); - acquire_sem(mac_os_lock); - } - break; - } - } - return true; -} - - -/* - * Deinitialization - */ - -void VideoExit(void) -{ - // Close display - switch (display_type) { - case DISPLAY_WINDOW: - if (the_window != NULL) { - the_window->PostMessage(B_QUIT_REQUESTED); - while (the_window) - snooze(200000); - } - break; - case DISPLAY_SCREEN: - if (the_screen != NULL) { - the_screen->PostMessage(B_QUIT_REQUESTED); - while (the_screen) - snooze(200000); - } - break; - } - - // Delete semaphore - delete_sem(mac_os_lock); -} - - -/* - * Set palette - */ - -void BeOS_monitor_desc::set_palette(uint8 *pal, int num) -{ - switch (display_type) { - case DISPLAY_WINDOW: { - BScreen screen(the_window); - for (int i=0; i<256; i++) - the_window->remap_mac_be[i] = screen.IndexForColor(pal[i*3], pal[i*3+1], pal[i*3+2]); - break; - } - case DISPLAY_SCREEN: - for (int i=0; i<256; i++) { - the_screen->palette[i].red = pal[i*3]; - the_screen->palette[i].green = pal[i*3+1]; - the_screen->palette[i].blue = pal[i*3+2]; - } - the_screen->palette_changed = true; - break; - } -} - - -/* - * Switch video mode - */ - -void BeOS_monitor_desc::switch_to_current_mode() -{ -} - - -/* - * Close down full-screen mode (if bringing up error alerts is unsafe while in full-screen mode) - */ - -void VideoQuitFullScreen(void) -{ - D(bug("VideoQuitFullScreen()\n")); - if (display_type == DISPLAY_SCREEN) { - if (the_screen != NULL) { - the_screen->PostMessage(B_QUIT_REQUESTED); - while (the_screen) - snooze(200000); - } - } -} - - -/* - * Video event handling (not neccessary under BeOS, handled by filter function) - */ - -void VideoInterrupt(void) -{ - release_sem(mac_os_lock); - while (acquire_sem(mac_os_lock) == B_INTERRUPTED) ; -} - - -/* - * Filter function for receiving mouse and keyboard events - */ - -#define MENU_IS_POWER 0 - -// Be -> Mac raw keycode translation table -static const uint8 keycode2mac[0x80] = { - 0xff, 0x35, 0x7a, 0x78, 0x63, 0x76, 0x60, 0x61, // inv Esc F1 F2 F3 F4 F5 F6 - 0x62, 0x64, 0x65, 0x6d, 0x67, 0x6f, 0x69, 0x6b, // F7 F8 F9 F10 F11 F12 F13 F14 - 0x71, 0x0a, 0x12, 0x13, 0x14, 0x15, 0x17, 0x16, // F15 ` 1 2 3 4 5 6 - 0x1a, 0x1c, 0x19, 0x1d, 0x1b, 0x18, 0x33, 0x72, // 7 8 9 0 - = BSP INS - 0x73, 0x74, 0x47, 0x4b, 0x43, 0x4e, 0x30, 0x0c, // HOM PUP NUM / * - TAB Q - 0x0d, 0x0e, 0x0f, 0x11, 0x10, 0x20, 0x22, 0x1f, // W E R T Y U I O - 0x23, 0x21, 0x1e, 0x2a, 0x75, 0x77, 0x79, 0x59, // P [ ] \ DEL END PDN 7 - 0x5b, 0x5c, 0x45, 0x39, 0x00, 0x01, 0x02, 0x03, // 8 9 + CAP A S D F - 0x05, 0x04, 0x26, 0x28, 0x25, 0x29, 0x27, 0x24, // G H J K L ; ' RET - 0x56, 0x57, 0x58, 0x38, 0x06, 0x07, 0x08, 0x09, // 4 5 6 SHL Z X C V - 0x0b, 0x2d, 0x2e, 0x2b, 0x2f, 0x2c, 0x38, 0x3e, // B N M , . / SHR CUP - 0x53, 0x54, 0x55, 0x4c, 0x36, 0x37, 0x31, 0x37, // 1 2 3 ENT CTL ALT SPC ALT - 0x36, 0x3b, 0x3d, 0x3c, 0x52, 0x41, 0x3a, 0x3a, // CTR CLF CDN CRT 0 . CMD CMD -#if MENU_IS_POWER - 0x7f, 0x32, 0x51, 0x7f, 0xff, 0xff, 0xff, 0xff, // MNU EUR = POW inv inv inv inv -#else - 0x32, 0x32, 0x51, 0x7f, 0xff, 0xff, 0xff, 0xff, // MNU EUR = POW inv inv inv inv -#endif - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv -}; - -static const uint8 modifier2mac[0x20] = { -#if MENU_IS_POWER - 0x38, 0x37, 0x36, 0x39, 0x6b, 0x47, 0x3a, 0x7f, // SHF CMD inv CAP F14 NUM OPT MNU -#else - 0x38, 0x37, 0x36, 0x39, 0x6b, 0x47, 0x3a, 0x32, // SHF CMD CTR CAP F14 NUM OPT MNU -#endif - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv -}; - -static filter_result filter_func(BMessage *msg, BHandler **target, BMessageFilter *filter) -{ - switch (msg->what) { - case B_KEY_DOWN: - case B_KEY_UP: { - uint32 be_code = msg->FindInt32("key") & 0xff; - uint32 mac_code = keycode2mac[be_code]; - - // Intercept Ctrl-F1 (mount floppy disk shortcut) - uint32 mods = msg->FindInt32("modifiers"); - if (be_code == 0x02 && (mods & B_CONTROL_KEY)) - SysMountVolume("/dev/disk/floppy/raw"); - - if (mac_code == 0xff) - return B_DISPATCH_MESSAGE; - if (msg->what == B_KEY_DOWN) - ADBKeyDown(mac_code); - else - ADBKeyUp(mac_code); - return B_SKIP_MESSAGE; - } - - case B_MODIFIERS_CHANGED: { - uint32 mods = msg->FindInt32("modifiers"); - uint32 old_mods = msg->FindInt32("be:old_modifiers"); - uint32 changed = mods ^ old_mods; - uint32 mask = 1; - for (int i=0; i<32; i++, mask<<=1) - if (changed & mask) { - uint32 mac_code = modifier2mac[i]; - if (mac_code == 0xff) - continue; - if (mods & mask) - ADBKeyDown(mac_code); - else - ADBKeyUp(mac_code); - } - return B_SKIP_MESSAGE; - } - - case B_MOUSE_MOVED: { - BPoint point; - msg->FindPoint("where", &point); - ADBMouseMoved(int(point.x), int(point.y)); - return B_DISPATCH_MESSAGE; // Otherwise BitmapView::MouseMoved() wouldn't be called - } - - case B_MOUSE_DOWN: { - uint32 buttons = msg->FindInt32("buttons"); - if (buttons & B_PRIMARY_MOUSE_BUTTON) - ADBMouseDown(0); - if (buttons & B_SECONDARY_MOUSE_BUTTON) - ADBMouseDown(1); - if (buttons & B_TERTIARY_MOUSE_BUTTON) - ADBMouseDown(2); - return B_SKIP_MESSAGE; - } - - case B_MOUSE_UP: // B_MOUSE_UP means "all buttons released" - ADBMouseUp(0); - ADBMouseUp(1); - ADBMouseUp(2); - return B_SKIP_MESSAGE; - - default: - return B_DISPATCH_MESSAGE; - } -} - - -/* - * Window constructor - */ - -MacWindow::MacWindow(BRect frame, const BeOS_monitor_desc& monitor) - : BDirectWindow(frame, GetString(STR_WINDOW_TITLE), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_CLOSABLE | B_NOT_ZOOMABLE) - , monitor(monitor) -{ - supports_direct_mode = SupportsWindowMode(); - - // Move window to right position - Lock(); - MoveTo(80, 60); - - // Allocate bitmap and Mac frame buffer - uint32 x = frame.IntegerWidth() + 1; - uint32 y = frame.IntegerHeight() + 1; - int fbsize = x * y; - const video_mode &mode = monitor.get_current_mode(); - switch (mode.depth) { - case VDEPTH_1BIT: - fprintf(stderr, "1BIT SCREEN CREATED"); - the_bitmap = new BBitmap(frame, B_GRAY1); - fbsize /= 8; - break; - case VDEPTH_8BIT: - fprintf(stderr, "8BIT SCREEN CREATED"); - the_bitmap = new BBitmap(frame, B_CMAP8); - break; - case VDEPTH_32BIT: - fprintf(stderr, "32BIT SCREEN CREATED"); - the_bitmap = new BBitmap(frame, B_RGB32_BIG); - fbsize *= 4; - break; - default: - fprintf(stderr, "width: %d", 1 << mode.depth); - debugger("OOPS"); - } - -#if REAL_ADDRESSING - monitor.set_mac_frame_base((uint32)the_bitmap->Bits()); -#else - monitor.set_mac_frame_base(MacFrameBaseMac); -#endif - -#if !REAL_ADDRESSING - // Set variables for UAE memory mapping - MacFrameBaseHost = (uint8*)the_bitmap->Bits(); - MacFrameSize = fbsize; - MacFrameLayout = FLAYOUT_DIRECT; -#endif - - // Create bitmap view - main_view = new BitmapView(frame, the_bitmap); - AddChild(main_view); - main_view->MakeFocus(); - - // Read frame skip prefs - frame_skip = PrefsFindInt32("frameskip"); - if (frame_skip == 0) - frame_skip = 1; - - // Set up menus - BRect bounds = Bounds(); - bounds.OffsetBy(0, bounds.IntegerHeight() + 1); - BMenuItem *item; - BMenuBar *bar = new BMenuBar(bounds, "menu"); - BMenu *menu = new BMenu(GetString(STR_WINDOW_MENU)); - menu->AddItem(new BMenuItem(GetString(STR_WINDOW_ITEM_ABOUT), new BMessage(MSG_ABOUT_REQUESTED))); - menu->AddItem(new BSeparatorItem); - BMenu *submenu = new BMenu(GetString(STR_WINDOW_ITEM_REFRESH)); - submenu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_60HZ_LAB), new BMessage(MSG_REF_60HZ))); - submenu->SetRadioMode(true); - if (frame_skip == 12) { - if ((item = submenu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 8) { - if ((item = submenu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 6) { - if ((item = submenu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 4) { - if ((item = submenu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 2) { - if ((item = submenu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 1) { - if ((item = submenu->FindItem(GetString(STR_REF_60HZ_LAB))) != NULL) - item->SetMarked(true); - } - menu->AddItem(submenu); - submenu = new BMenu(GetString(STR_WINDOW_ITEM_MOUNT)); - SysCreateVolumeMenu(submenu, MSG_MOUNT); - menu->AddItem(submenu); -#if DEBUGGER_AVAILABLE - menu->AddItem(new BMenuItem("Debugger", new BMessage(MSG_DEBUGGER))); -#endif - bar->AddItem(menu); - AddChild(bar); - SetKeyMenuBar(bar); - int mbar_height = bar->Frame().IntegerHeight() + 1; - - // Resize window to fit menu bar - ResizeBy(0, mbar_height); - - // Set absolute mouse mode and get scroll lock state - ADBSetRelMouseMode(false); - mouse_in_view = true; - old_scroll_lock_state = modifiers() & B_SCROLL_LOCK; - if (old_scroll_lock_state) - SetTitle(GetString(STR_WINDOW_TITLE_FROZEN)); - else - SetTitle(GetString(STR_WINDOW_TITLE)); - - // Keep window aligned to 8-byte frame buffer boundaries for faster blitting - SetWindowAlignment(B_BYTE_ALIGNMENT, 8); - - // Create drawing semaphore (for direct mode) - drawing_sem = create_sem(0, "direct frame buffer access"); - - // Start 60Hz interrupt - tick_thread_active = true; - tick_thread = spawn_thread(tick_func, "Window Redraw", B_DISPLAY_PRIORITY, this); - resume_thread(tick_thread); - - // Add filter for keyboard and mouse events - BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, filter_func); - main_view->AddFilter(filter); - - // Show window - Unlock(); - Show(); - Sync(); -} - - -/* - * Window destructor - */ - -MacWindow::~MacWindow() -{ - // Restore cursor - mouse_in_view = false; - be_app->SetCursor(B_HAND_CURSOR); - - // Hide window - Hide(); - Sync(); - - // Stop 60Hz interrupt - status_t l; - tick_thread_active = false; - delete_sem(drawing_sem); - wait_for_thread(tick_thread, &l); - - // Free bitmap and frame buffer - delete the_bitmap; - - // Tell emulator that we're done - the_window = NULL; -} - - -/* - * Window connected/disconnected - */ - -void MacWindow::DirectConnected(direct_buffer_info *info) -{ - switch (info->buffer_state & B_DIRECT_MODE_MASK) { - case B_DIRECT_STOP: - acquire_sem(drawing_sem); - break; - case B_DIRECT_MODIFY: - acquire_sem(drawing_sem); - case B_DIRECT_START: - bits = (void *)((uint8 *)info->bits + info->window_bounds.top * info->bytes_per_row + info->window_bounds.left * info->bits_per_pixel / 8); - bytes_per_row = info->bytes_per_row; - pixel_format = info->pixel_format; - unclipped = false; - if (info->clip_list_count == 1) - if (memcmp(&info->clip_bounds, &info->window_bounds, sizeof(clipping_rect)) == 0) - unclipped = true; - release_sem(drawing_sem); - break; - } -} - - -/* - * Handle redraw and menu messages - */ - -void MacWindow::MessageReceived(BMessage *msg) -{ - BMessage *msg2; - - switch (msg->what) { - case MSG_REDRAW: { - - // Prevent backlog of messages - MessageQueue()->Lock(); - while ((msg2 = MessageQueue()->FindMessage(MSG_REDRAW, 0)) != NULL) { - MessageQueue()->RemoveMessage(msg2); - delete msg2; - } - MessageQueue()->Unlock(); - - // Convert Mac screen buffer to BeOS palette and blit - const video_mode &mode = monitor.get_current_mode(); - BRect update_rect = BRect(0, 0, mode.x-1, mode.y-1); - main_view->DrawBitmapAsync(the_bitmap, update_rect, update_rect); - break; - } - - case MSG_ABOUT_REQUESTED: { - ShowAboutWindow(); - break; - } - - case MSG_REF_5HZ: - PrefsReplaceInt32("frameskip", frame_skip = 12); - break; - - case MSG_REF_7_5HZ: - PrefsReplaceInt32("frameskip", frame_skip = 8); - break; - - case MSG_REF_10HZ: - PrefsReplaceInt32("frameskip", frame_skip = 6); - break; - - case MSG_REF_15HZ: - PrefsReplaceInt32("frameskip", frame_skip = 4); - break; - - case MSG_REF_30HZ: - PrefsReplaceInt32("frameskip", frame_skip = 2); - break; - - case MSG_REF_60HZ: - PrefsReplaceInt32("frameskip", frame_skip = 1); - break; - - case MSG_MOUNT: { - BMenuItem *source = NULL; - msg->FindPointer("source", (void **)&source); - if (source) - SysMountVolume(source->Label()); - break; - } - -#if DEBUGGER_AVAILABLE - case MSG_DEBUGGER: - extern int debugging; - debugging = 1; - regs.spcflags |= SPCFLAG_BRK; - break; -#endif - - default: - BDirectWindow::MessageReceived(msg); - } -} - - -/* - * Window activated/deactivated - */ - -void MacWindow::WindowActivated(bool active) -{ - if (active) { - frame_skip = PrefsFindInt32("frameskip"); - if (frame_skip == 0) - frame_skip = 1; - } else - frame_skip = 12; // 5Hz in background -} - - -/* - * 60Hz interrupt routine - */ - -status_t MacWindow::tick_func(void *arg) -{ - MacWindow *obj = (MacWindow *)arg; - static int tick_counter = 0; - while (obj->tick_thread_active) { - - tick_counter++; - if (tick_counter >= obj->frame_skip) { - tick_counter = 0; - - // Window title is determined by Scroll Lock state - uint32 scroll_lock_state = modifiers() & B_SCROLL_LOCK; - if (scroll_lock_state != obj->old_scroll_lock_state) { - if (scroll_lock_state) - obj->SetTitle(GetString(STR_WINDOW_TITLE_FROZEN)); - else - obj->SetTitle(GetString(STR_WINDOW_TITLE)); - obj->old_scroll_lock_state = scroll_lock_state; - } - - // Has the Mac started? - if (HasMacStarted()) { - - // Yes, set new cursor image if it was changed - if (memcmp(MacCursor+4, Mac2HostAddr(0x844), 64)) { - Mac2Host_memcpy(MacCursor+4, 0x844, 64); // Cursor image - MacCursor[2] = ReadMacInt8(0x885); // Hotspot - MacCursor[3] = ReadMacInt8(0x887); - be_app->SetCursor(MacCursor); - } - } - - // Refresh screen unless Scroll Lock is down - if (!scroll_lock_state) { - obj->PostMessage(MSG_REDRAW); - } - } - snooze(16666); - } - return 0; -} - - -/* - * Mouse moved in window - */ - -void BitmapView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) -{ - switch (transit) { - case B_ENTERED_VIEW: - ((MacWindow *)Window())->mouse_in_view = true; - be_app->SetCursor(MacCursor); - break; - case B_EXITED_VIEW: - ((MacWindow *)Window())->mouse_in_view = false; - be_app->SetCursor(B_HAND_CURSOR); - break; - } -} - - -/* - * Screen constructor - */ - -MacScreen::MacScreen(const BeOS_monitor_desc& monitor, const char *name, int mode_bit, status_t *error) - : BWindowScreen(name, 1 << mode_bit, error), tick_thread(-1) - , monitor(monitor) -{ - // Set all variables - frame_backup = NULL; - palette_changed = false; - screen_active = false; - first_time = true; - quitting = false; - - // Set relative mouse mode - ADBSetRelMouseMode(true); - - // Create view to get mouse events - main_view = new BView(Frame(), NULL, B_FOLLOW_NONE, 0); - AddChild(main_view); - - // Start 60Hz interrupt - tick_thread_active = true; - tick_thread = spawn_thread(tick_func, "Polling sucks...", B_DISPLAY_PRIORITY, this); - resume_thread(tick_thread); - - // Add filter for keyboard and mouse events - BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, filter_func); - AddCommonFilter(filter); -} - - -/* - * Screen destructor - */ - -MacScreen::~MacScreen() -{ - // Stop 60Hz interrupt - if (tick_thread > 0) { - status_t l; - tick_thread_active = false; - wait_for_thread(tick_thread, &l); - } - - // Tell emulator that we're done - the_screen = NULL; -} - - -/* - * Screen closed - */ - -void MacScreen::Quit(void) -{ - // Tell ScreenConnected() that we are quitting - quitting = true; - BWindowScreen::Quit(); -} - - -/* - * Screen connected/disconnected - */ - -void MacScreen::ScreenConnected(bool active) -{ - graphics_card_info *info = CardInfo(); - screen_active = active; - const video_mode &mode = monitor.get_current_mode(); - - if (active == true) { - - // Set VideoMonitor -#if REAL_ADDRESSING - monitor.set_mac_frame_base((uint32)info->frame_buffer); -#else - monitor.set_mac_frame_base(MacFrameBaseMac); -#endif - -#if !REAL_ADDRESSING - // Set variables for UAE memory mapping - MacFrameBaseHost = (uint8 *)info->frame_buffer; - MacFrameSize = mode.bytes_per_row * mode.y; - switch (info->bits_per_pixel) { - case 15: - MacFrameLayout = FLAYOUT_HOST_555; - break; - case 16: - MacFrameLayout = FLAYOUT_HOST_565; - break; - case 32: - MacFrameLayout = FLAYOUT_HOST_888; - break; - default: - MacFrameLayout = FLAYOUT_DIRECT; - break; - } -#endif - - // Copy from backup store to frame buffer - if (frame_backup != NULL) { - memcpy(info->frame_buffer, frame_backup, mode.bytes_per_row * mode.y); - delete[] frame_backup; - frame_backup = NULL; - } - - // Restore palette - if (mode.depth == VDEPTH_8BIT) - SetColorList(palette); - - // Restart/signal emulator thread - release_sem(mac_os_lock); - - } else { - - if (!quitting) { - - // Stop emulator thread - acquire_sem(mac_os_lock); - - // Create backup store and save frame buffer - frame_backup = new uint8[mode.bytes_per_row * mode.y]; - memcpy(frame_backup, info->frame_buffer, mode.bytes_per_row * mode.y); - } - } -} - - -/* - * Screen 60Hz interrupt routine - */ - -status_t MacScreen::tick_func(void *arg) -{ - MacScreen *obj = (MacScreen *)arg; - while (obj->tick_thread_active) { - - // Wait - snooze(16667); - - // Workspace activated? Then poll the mouse and set the palette if needed - if (!obj->quitting && obj->LockWithTimeout(200000) == B_OK) { - if (obj->screen_active) { - BPoint pt; - uint32 button = 0; - if (obj->palette_changed) { - obj->palette_changed = false; - obj->SetColorList(obj->palette); - } - obj->main_view->GetMouse(&pt, &button); - set_mouse_position(320, 240); - ADBMouseMoved(int(pt.x) - 320, int(pt.y) - 240); - if (button & B_PRIMARY_MOUSE_BUTTON) - ADBMouseDown(0); - if (!(button & B_PRIMARY_MOUSE_BUTTON)) - ADBMouseUp(0); - if (button & B_SECONDARY_MOUSE_BUTTON) - ADBMouseDown(1); - if (!(button & B_SECONDARY_MOUSE_BUTTON)) - ADBMouseUp(1); - if (button & B_TERTIARY_MOUSE_BUTTON) - ADBMouseDown(2); - if (!(button & B_TERTIARY_MOUSE_BUTTON)) - ADBMouseUp(2); - } - obj->Unlock(); - } - } - return 0; -} diff --git a/BasiliskII/src/BeOS/xpram_beos.cpp b/BasiliskII/src/BeOS/xpram_beos.cpp deleted file mode 100644 index 8ee250a4..00000000 --- a/BasiliskII/src/BeOS/xpram_beos.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * xpram_beos.cpp - XPRAM handling, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include "sysdeps.h" -#include "xpram.h" - - -// XPRAM file name and path -#if POWERPC_ROM -const char XPRAM_FILE_NAME[] = "SheepShaver_NVRAM"; -#else -const char XPRAM_FILE_NAME[] = "BasiliskII_XPRAM"; -#endif -static BPath xpram_path; - - -/* - * Load XPRAM from settings file - */ - -void LoadXPRAM(const char *vmdir) -{ - // Construct XPRAM path - find_directory(B_USER_SETTINGS_DIRECTORY, &xpram_path, true); - xpram_path.Append(XPRAM_FILE_NAME); - - // Load XPRAM from settings file - int fd; - if ((fd = open(xpram_path.Path(), O_RDONLY)) >= 0) { - read(fd, XPRAM, XPRAM_SIZE); - close(fd); - } -} - - -/* - * Save XPRAM to settings file - */ - -void SaveXPRAM(void) -{ - if (xpram_path.InitCheck() != B_NO_ERROR) - return; - int fd; - if ((fd = open(xpram_path.Path(), O_WRONLY | O_CREAT, 0666)) >= 0) { - write(fd, XPRAM, XPRAM_SIZE); - close(fd); - } -} - - -/* - * Delete PRAM file - */ - -void ZapPRAM(void) -{ - // Construct PRAM path - find_directory(B_USER_SETTINGS_DIRECTORY, &xpram_path, true); - xpram_path.Append(XPRAM_FILE_NAME); - - // Delete file - unlink(xpram_path.Path()); -} diff --git a/BasiliskII/src/CrossPlatform/sigsegv.cpp b/BasiliskII/src/CrossPlatform/sigsegv.cpp index 570058c2..41a5d04e 100644 --- a/BasiliskII/src/CrossPlatform/sigsegv.cpp +++ b/BasiliskII/src/CrossPlatform/sigsegv.cpp @@ -53,14 +53,8 @@ using std::list; // Size of an unsigned integer large enough to hold all bits of a pointer // NOTE: this can be different than SIGSEGV_REGISTER_TYPE. In // particular, on ILP32 systems with a 64-bit kernel (HP-UX/ia64?) -#if defined(HAVE_WIN32_VM) -// Windows is either ILP32 or LLP64 -#include -typedef UINT_PTR sigsegv_uintptr_t; -#else // Other systems are sane enough to follow ILP32 or LP64 models typedef unsigned long sigsegv_uintptr_t; -#endif // Type of the system signal handler typedef RETSIGTYPE (*signal_handler)(int); @@ -96,507 +90,19 @@ enum transfer_size_t { SIZE_QUAD // 8 bytes }; -#if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__)) -// Addressing mode -enum addressing_mode_t { - MODE_UNKNOWN, - MODE_NORM, - MODE_U, - MODE_X, - MODE_UX -}; - -// Decoded instruction -struct instruction_t { - transfer_type_t transfer_type; - transfer_size_t transfer_size; - addressing_mode_t addr_mode; - unsigned int addr; - char ra, rd; -}; - -static void powerpc_decode_instruction(instruction_t *instruction, unsigned int nip, unsigned long * gpr) -{ - // Get opcode and divide into fields - unsigned int opcode = *((unsigned int *)(unsigned long)nip); - unsigned int primop = opcode >> 26; - unsigned int exop = (opcode >> 1) & 0x3ff; - unsigned int ra = (opcode >> 16) & 0x1f; - unsigned int rb = (opcode >> 11) & 0x1f; - unsigned int rd = (opcode >> 21) & 0x1f; - signed int imm = (signed short)(opcode & 0xffff); - - // Analyze opcode - transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN; - transfer_size_t transfer_size = SIZE_UNKNOWN; - addressing_mode_t addr_mode = MODE_UNKNOWN; - switch (primop) { - case 31: - switch (exop) { - case 23: // lwzx - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_X; break; - case 55: // lwzux - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break; - case 87: // lbzx - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break; - case 119: // lbzux - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break; - case 151: // stwx - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_X; break; - case 183: // stwux - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break; - case 215: // stbx - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break; - case 247: // stbux - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break; - case 279: // lhzx - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; - case 311: // lhzux - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; - case 343: // lhax - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; - case 375: // lhaux - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; - case 407: // sthx - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; - case 439: // sthux - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; - } - break; - - case 32: // lwz - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break; - case 33: // lwzu - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_U; break; - case 34: // lbz - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break; - case 35: // lbzu - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break; - case 36: // stw - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break; - case 37: // stwu - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_U; break; - case 38: // stb - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break; - case 39: // stbu - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break; - case 40: // lhz - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; - case 41: // lhzu - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; - case 42: // lha - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; - case 43: // lhau - transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; - case 44: // sth - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; - case 45: // sthu - transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; - case 58: // ld, ldu, lwa - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_QUAD; - addr_mode = ((opcode & 3) == 1) ? MODE_U : MODE_NORM; - imm &= ~3; - break; - case 62: // std, stdu, stq - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_QUAD; - addr_mode = ((opcode & 3) == 1) ? MODE_U : MODE_NORM; - imm &= ~3; - break; - } - - // Calculate effective address - unsigned int addr = 0; - switch (addr_mode) { - case MODE_X: - case MODE_UX: - if (ra == 0) - addr = gpr[rb]; - else - addr = gpr[ra] + gpr[rb]; - break; - case MODE_NORM: - case MODE_U: - if (ra == 0) - addr = (signed int)(signed short)imm; - else - addr = gpr[ra] + (signed int)(signed short)imm; - break; - default: - break; - } - - // Commit decoded instruction - instruction->addr = addr; - instruction->addr_mode = addr_mode; - instruction->transfer_type = transfer_type; - instruction->transfer_size = transfer_size; - instruction->ra = ra; - instruction->rd = rd; -} -#endif - - /* * OS-dependant SIGSEGV signals support section */ #if HAVE_SIGINFO_T // Generic extended signal handler -#if defined(__hpux) -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) FAULT_HANDLER(SIGBUS) -#else -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) -#endif + #define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *scp #define SIGSEGV_FAULT_HANDLER_ARGLIST_1 siginfo_t *sip, void *scp #define SIGSEGV_FAULT_HANDLER_ARGS sip, scp #define SIGSEGV_FAULT_ADDRESS sip->si_addr -#if (defined(sgi) || defined(__sgi)) -#include -#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) -#define SIGSEGV_FAULT_INSTRUCTION (unsigned long)SIGSEGV_CONTEXT_REGS[CTX_EPC] -#if (defined(mips) || defined(__mips)) -#define SIGSEGV_REGISTER_FILE &SIGSEGV_CONTEXT_REGS[CTX_EPC], &SIGSEGV_CONTEXT_REGS[CTX_R0] -#define SIGSEGV_SKIP_INSTRUCTION mips_skip_instruction -#endif -#endif -#if defined(__sun__) -#if (defined(sparc) || defined(__sparc__)) -#include -#include -#include -#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) -#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[REG_PC] -#define SIGSEGV_SPARC_GWINDOWS (((ucontext_t *)scp)->uc_mcontext.gwins) -#define SIGSEGV_SPARC_RWINDOW (struct rwindow *)((char *)SIGSEGV_CONTEXT_REGS[REG_SP] + STACK_BIAS) -#define SIGSEGV_REGISTER_FILE ((unsigned long *)SIGSEGV_CONTEXT_REGS), SIGSEGV_SPARC_GWINDOWS, SIGSEGV_SPARC_RWINDOW -#define SIGSEGV_SKIP_INSTRUCTION sparc_skip_instruction -#endif -#if defined(__i386__) -#include -#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) -#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[EIP] -#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS -#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#endif -#endif -#if defined(__FreeBSD__) || defined(__OpenBSD__) -#if (defined(i386) || defined(__i386__)) -#undef SIGSEGV_ALL_SIGNALS -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGBUS) -#define SIGSEGV_FAULT_INSTRUCTION (((struct sigcontext *)scp)->sc_eip) -#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&(((struct sigcontext *)scp)->sc_edi)) /* EDI is the first GPR (even below EIP) in sigcontext */ -#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#elif (defined(x86_64) || defined(__x86_64__)) -#define SIGSEGV_FAULT_INSTRUCTION (((struct sigcontext *)scp)->sc_rip) -#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&(((struct sigcontext *)scp)->sc_rdi)) -#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#endif -#endif -#if defined(__NetBSD__) -#if (defined(i386) || defined(__i386__)) -#include -#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.__gregs) -#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[_REG_EIP] -#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS -#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#endif -#if (defined(powerpc) || defined(__powerpc__)) -#include -#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.__gregs) -#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[_REG_PC] -#define SIGSEGV_REGISTER_FILE (unsigned long *)&SIGSEGV_CONTEXT_REGS[_REG_PC], (unsigned long *)&SIGSEGV_CONTEXT_REGS[_REG_R0] -#define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction -#endif -#endif -#if defined(__linux__) -#if HAVE_ASM_UCONTEXT -#include /* use kernel structure, glibc may not be in sync */ -#else -#include -#endif -#if (defined(hppa) || defined(__hppa__)) -#undef SIGSEGV_FAULT_ADDRESS -#define SIGSEGV_FAULT_ADDRESS sip->si_ptr -#endif -#if (defined(i386) || defined(__i386__)) -#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) -#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[14] /* should use REG_EIP instead */ -#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS -#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#elif (defined(x86_64) || defined(__x86_64__)) -#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) -#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[16] /* should use REG_RIP instead */ -#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS -#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#elif (defined(ia64) || defined(__ia64__)) -#define SIGSEGV_CONTEXT_REGS ((struct sigcontext *)scp) -#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS->sc_ip & ~0x3ULL) /* slot number is in bits 0 and 1 */ -#define SIGSEGV_REGISTER_FILE SIGSEGV_CONTEXT_REGS -#define SIGSEGV_SKIP_INSTRUCTION ia64_skip_instruction -#elif (defined(powerpc) || defined(__powerpc__)) -#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.regs) -#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS->nip) -#define SIGSEGV_REGISTER_FILE (unsigned long *)&SIGSEGV_CONTEXT_REGS->nip, (unsigned long *)(SIGSEGV_CONTEXT_REGS->gpr) -#define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction -#elif (defined(arm) || defined(__arm__)) -#define SIGSEGV_CONTEXT_REGS (((struct ucontext *)scp)->uc_mcontext) -#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS.arm_pc) -#define SIGSEGV_REGISTER_FILE (&SIGSEGV_CONTEXT_REGS.arm_r0) -#define SIGSEGV_SKIP_INSTRUCTION arm_skip_instruction -#elif (defined(mips) || defined(__mips__)) -#define SIGSEGV_CONTEXT_REGS (((struct ucontext *)scp)->uc_mcontext) -#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS.pc) -#define SIGSEGV_REGISTER_FILE &SIGSEGV_CONTEXT_REGS.pc, &SIGSEGV_CONTEXT_REGS.gregs[0] -#define SIGSEGV_SKIP_INSTRUCTION mips_skip_instruction -#endif -#endif // defined(__linux__) -#if (defined(__hpux) || defined(__hpux__)) -#if (defined(__hppa) || defined(__hppa__)) -#define SIGSEGV_CONTEXT_REGS (&((ucontext_t *)scp)->uc_mcontext) -#define SIGSEGV_FAULT_INSTRUCTION_32 (SIGSEGV_CONTEXT_REGS->ss_narrow.ss_pcoq_head & ~3ul) -#define SIGSEGV_FAULT_INSTRUCTION_64 (SIGSEGV_CONTEXT_REGS->ss_wide.ss_64.ss_pcoq_head & ~3ull) -#if defined(__LP64__) -#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_FAULT_INSTRUCTION_64 -#else -#define SIGSEGV_FAULT_INSTRUCTION ((SIGSEGV_CONTEXT_REGS->ss_flags & SS_WIDEREGS) ? \ - (uint32_t)SIGSEGV_FAULT_INSTRUCTION_64 : \ - SIGSEGV_FAULT_INSTRUCTION_32) -#endif -#endif -#if (defined(__ia64) || defined(__ia64__)) -#include -#define SIGSEGV_CONTEXT_REGS ((ucontext_t *)scp) -#define SIGSEGV_FAULT_INSTRUCTION get_fault_instruction(SIGSEGV_CONTEXT_REGS) -#define SIGSEGV_REGISTER_FILE SIGSEGV_CONTEXT_REGS -#define SIGSEGV_SKIP_INSTRUCTION ia64_skip_instruction - -#include -static inline sigsegv_address_t get_fault_instruction(const ucontext_t *ucp) -{ - uint64_t ip; - if (__uc_get_ip(ucp, &ip) != 0) - return SIGSEGV_INVALID_ADDRESS; - return (sigsegv_address_t)(ip & ~3ULL); -} -#endif -#endif -#endif - -#if HAVE_SIGCONTEXT_SUBTERFUGE -// Linux kernels prior to 2.4 ? -#if defined(__linux__) -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) -#if (defined(i386) || defined(__i386__)) -#include -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, struct sigcontext scs -#define SIGSEGV_FAULT_HANDLER_ARGLIST_1 struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS &scs -#define SIGSEGV_FAULT_ADDRESS scp->cr2 -#define SIGSEGV_FAULT_INSTRUCTION scp->eip -#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)scp -#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#endif -#if (defined(sparc) || defined(__sparc__)) -#include -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp, char *addr -#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp, addr -#define SIGSEGV_FAULT_ADDRESS addr -#endif -#if (defined(powerpc) || defined(__powerpc__)) -#include -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS sig, scp -#define SIGSEGV_FAULT_ADDRESS scp->regs->dar -#define SIGSEGV_FAULT_INSTRUCTION scp->regs->nip -#define SIGSEGV_REGISTER_FILE (unsigned long *)&scp->regs->nip, (unsigned long *)(scp->regs->gpr) -#define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction -#endif -#if (defined(alpha) || defined(__alpha__)) -#include -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp -#define SIGSEGV_FAULT_ADDRESS get_fault_address(scp) -#define SIGSEGV_FAULT_INSTRUCTION scp->sc_pc -#endif -#if (defined(arm) || defined(__arm__)) -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int r1, int r2, int r3, struct sigcontext sc -#define SIGSEGV_FAULT_HANDLER_ARGLIST_1 struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS &sc -#define SIGSEGV_FAULT_ADDRESS scp->fault_address -#define SIGSEGV_FAULT_INSTRUCTION scp->arm_pc -#define SIGSEGV_REGISTER_FILE &scp->arm_r0 -#define SIGSEGV_SKIP_INSTRUCTION arm_skip_instruction -#endif -#endif - -// Irix 5 or 6 on MIPS -#if (defined(sgi) || defined(__sgi)) && (defined(SYSTYPE_SVR4) || defined(_SYSTYPE_SVR4)) -#include -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp -#define SIGSEGV_FAULT_ADDRESS (unsigned long)scp->sc_badvaddr -#define SIGSEGV_FAULT_INSTRUCTION (unsigned long)scp->sc_pc -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) -#endif - -// HP-UX -#if (defined(hpux) || defined(__hpux__)) -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp -#define SIGSEGV_FAULT_ADDRESS scp->sc_sl.sl_ss.ss_narrow.ss_cr21 -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) FAULT_HANDLER(SIGBUS) -#endif - -// OSF/1 on Alpha -#if defined(__osf__) -#include -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp -#define SIGSEGV_FAULT_ADDRESS scp->sc_traparg_a0 -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) -#endif - -// AIX -#if defined(_AIX) -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp -#define SIGSEGV_FAULT_ADDRESS scp->sc_jmpbuf.jmp_context.o_vaddr -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) -#endif - -// NetBSD -#if defined(__NetBSD__) -#if (defined(m68k) || defined(__m68k__)) -#include -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp -#define SIGSEGV_FAULT_ADDRESS get_fault_address(scp) -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) - -// Use decoding scheme from BasiliskII/m68k native -static sigsegv_address_t get_fault_address(struct sigcontext *scp) -{ - struct sigstate { - int ss_flags; - struct frame ss_frame; - }; - struct sigstate *state = (struct sigstate *)scp->sc_ap; - char *fault_addr; - switch (state->ss_frame.f_format) { - case 7: /* 68040 access error */ - /* "code" is sometimes unreliable (i.e. contains NULL or a bogus address), reason unknown */ - fault_addr = state->ss_frame.f_fmt7.f_fa; - break; - default: - fault_addr = (char *)code; - break; - } - return (sigsegv_address_t)fault_addr; -} -#endif -#if (defined(alpha) || defined(__alpha__)) -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp -#define SIGSEGV_FAULT_ADDRESS get_fault_address(scp) -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGBUS) -#endif -#if (defined(i386) || defined(__i386__)) -#error "FIXME: need to decode instruction and compute EA" -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) -#endif -#endif -#if defined(__FreeBSD__) -#if (defined(i386) || defined(__i386__)) -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGBUS) -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp, char *addr -#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp, addr -#define SIGSEGV_FAULT_ADDRESS addr -#define SIGSEGV_FAULT_INSTRUCTION scp->sc_eip -#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&scp->sc_edi) -#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#endif -#if (defined(alpha) || defined(__alpha__)) -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, char *addr, struct sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS sig, addr, scp -#define SIGSEGV_FAULT_ADDRESS addr -#define SIGSEGV_FAULT_INSTRUCTION scp->sc_pc -#endif -#endif - -// Extract fault address out of a sigcontext -#if (defined(alpha) || defined(__alpha__)) -// From Boehm's GC 6.0alpha8 -static sigsegv_address_t get_fault_address(struct sigcontext *scp) -{ - unsigned int instruction = *((unsigned int *)(scp->sc_pc)); - unsigned long fault_address = scp->sc_regs[(instruction >> 16) & 0x1f]; - fault_address += (signed long)(signed short)(instruction & 0xffff); - return (sigsegv_address_t)fault_address; -} -#endif -// MacOS X, not sure which version this works in. Under 10.1 -// vm_protect does not appear to work from a signal handler. Under -// 10.2 signal handlers get siginfo type arguments but the si_addr -// field is the address of the faulting instruction and not the -// address that caused the SIGBUS. Maybe this works in 10.0? In any -// case with Mach exception handlers there is a way to do what this -// was meant to do. -#ifndef HAVE_MACH_EXCEPTIONS -#if defined(__APPLE__) && defined(__MACH__) -#if (defined(ppc) || defined(__ppc__)) -#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct __darwin_sigcontext *scp -#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp -#define SIGSEGV_FAULT_ADDRESS get_fault_address(scp) -#define SIGSEGV_FAULT_INSTRUCTION scp->MACH_FIELD_NAME(sc_ir) -#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGBUS) -#define SIGSEGV_REGISTER_FILE (unsigned int *)&scp->sc_ir, &((unsigned int *) scp->sc_regs)[2] -#define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction - -// Use decoding scheme from SheepShaver -static sigsegv_address_t get_fault_address(struct sigcontext *scp) -{ - unsigned int nip = (unsigned int) scp->MACH_FIELD_NAME(sc_ir); - unsigned int * gpr = &((unsigned int *) scp->MACH_FIELD_NAME(sc_regs))[2]; - instruction_t instr; - - powerpc_decode_instruction(&instr, nip, (long unsigned int*)gpr); - return (sigsegv_address_t)instr.addr; -} -#endif -#endif -#endif -#endif - -#if HAVE_WIN32_EXCEPTIONS -#define WIN32_LEAN_AND_MEAN /* avoid including junk */ -#include -#include - -#define SIGSEGV_FAULT_HANDLER_ARGLIST EXCEPTION_POINTERS *ExceptionInfo -#define SIGSEGV_FAULT_HANDLER_ARGS ExceptionInfo -#define SIGSEGV_FAULT_ADDRESS ExceptionInfo->ExceptionRecord->ExceptionInformation[1] -#define SIGSEGV_CONTEXT_REGS ExceptionInfo->ContextRecord -#if defined(_M_IX86) -#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS->Eip -#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIGSEGV_CONTEXT_REGS->Edi) -#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#endif -#if defined(_M_X64) -#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS->Rip -#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIGSEGV_CONTEXT_REGS->Rax) -#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#endif -#if defined(_M_IA64) -#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS->StIIP -#endif #endif #if HAVE_MACH_EXCEPTIONS @@ -748,130 +254,11 @@ handleExceptions(void *priv) #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION // Decode and skip X86 instruction #if (defined(i386) || defined(__i386__) || defined(_M_IX86)) || (defined(__x86_64__) || defined(_M_X64)) -#if defined(__linux__) -enum { -#if (defined(i386) || defined(__i386__)) - X86_REG_EIP = 14, - X86_REG_EAX = 11, - X86_REG_ECX = 10, - X86_REG_EDX = 9, - X86_REG_EBX = 8, - X86_REG_ESP = 7, - X86_REG_EBP = 6, - X86_REG_ESI = 5, - X86_REG_EDI = 4 -#endif -#if defined(__x86_64__) - X86_REG_R8 = 0, - X86_REG_R9 = 1, - X86_REG_R10 = 2, - X86_REG_R11 = 3, - X86_REG_R12 = 4, - X86_REG_R13 = 5, - X86_REG_R14 = 6, - X86_REG_R15 = 7, - X86_REG_EDI = 8, - X86_REG_ESI = 9, - X86_REG_EBP = 10, - X86_REG_EBX = 11, - X86_REG_EDX = 12, - X86_REG_EAX = 13, - X86_REG_ECX = 14, - X86_REG_ESP = 15, - X86_REG_EIP = 16 -#endif -}; -#endif -#if defined(__NetBSD__) -enum { -#if (defined(i386) || defined(__i386__)) - X86_REG_EIP = _REG_EIP, - X86_REG_EAX = _REG_EAX, - X86_REG_ECX = _REG_ECX, - X86_REG_EDX = _REG_EDX, - X86_REG_EBX = _REG_EBX, - X86_REG_ESP = _REG_ESP, - X86_REG_EBP = _REG_EBP, - X86_REG_ESI = _REG_ESI, - X86_REG_EDI = _REG_EDI -#endif -}; -#endif -#if defined(__FreeBSD__) -enum { -#if (defined(i386) || defined(__i386__)) - X86_REG_EIP = 10, - X86_REG_EAX = 7, - X86_REG_ECX = 6, - X86_REG_EDX = 5, - X86_REG_EBX = 4, - X86_REG_ESP = 13, - X86_REG_EBP = 2, - X86_REG_ESI = 1, - X86_REG_EDI = 0 -#endif -#if (defined(x86_64) || defined(__x86_64__)) - X86_REG_EDI = 0, - X86_REG_ESI = 1, - X86_REG_EDX = 2, - X86_REG_ECX = 3, - X86_REG_R8 = 4, - X86_REG_R9 = 5, - X86_REG_EAX = 6, - X86_REG_EBX = 7, - X86_REG_EBP = 8, - X86_REG_R10 = 9, - X86_REG_R11 = 10, - X86_REG_R12 = 11, - X86_REG_R13 = 12, - X86_REG_R14 = 13, - X86_REG_R15 = 14, - X86_REG_EIP = 19, - X86_REG_ESP = 22, -#endif -}; -#endif -#if defined(__OpenBSD__) -enum { -#if defined(__i386__) - // EDI is the first register we consider -#define OREG(REG) offsetof(struct sigcontext, sc_##REG) -#define DREG(REG) ((OREG(REG) - OREG(edi)) / 4) - X86_REG_EIP = DREG(eip), // 7 - X86_REG_EAX = DREG(eax), // 6 - X86_REG_ECX = DREG(ecx), // 5 - X86_REG_EDX = DREG(edx), // 4 - X86_REG_EBX = DREG(ebx), // 3 - X86_REG_ESP = DREG(esp), // 10 - X86_REG_EBP = DREG(ebp), // 2 - X86_REG_ESI = DREG(esi), // 1 - X86_REG_EDI = DREG(edi) // 0 -#undef DREG -#undef OREG -#endif -}; -#endif -#if defined(__sun__) -// Same as for Linux, need to check for x86-64 -enum { -#if defined(__i386__) - X86_REG_EIP = EIP, - X86_REG_EAX = EAX, - X86_REG_ECX = ECX, - X86_REG_EDX = EDX, - X86_REG_EBX = EBX, - X86_REG_ESP = ESP, - X86_REG_EBP = EBP, - X86_REG_ESI = ESI, - X86_REG_EDI = EDI -#endif -}; -#endif + #if defined(__APPLE__) && defined(__MACH__) enum { #if (defined(i386) || defined(__i386__)) #ifdef i386_SAVED_STATE - // same as FreeBSD (in Open Darwin 8.0.1) X86_REG_EIP = 10, X86_REG_EAX = 7, X86_REG_ECX = 6, @@ -915,40 +302,7 @@ enum { #endif }; #endif -#if defined(_WIN32) -enum { -#if defined(_M_IX86) - X86_REG_EIP = 7, - X86_REG_EAX = 5, - X86_REG_ECX = 4, - X86_REG_EDX = 3, - X86_REG_EBX = 2, - X86_REG_ESP = 10, - X86_REG_EBP = 6, - X86_REG_ESI = 1, - X86_REG_EDI = 0 -#endif -#if defined(_M_X64) - X86_REG_EAX = 0, - X86_REG_ECX = 1, - X86_REG_EDX = 2, - X86_REG_EBX = 3, - X86_REG_ESP = 4, - X86_REG_EBP = 5, - X86_REG_ESI = 6, - X86_REG_EDI = 7, - X86_REG_R8 = 8, - X86_REG_R9 = 9, - X86_REG_R10 = 10, - X86_REG_R11 = 11, - X86_REG_R12 = 12, - X86_REG_R13 = 13, - X86_REG_R14 = 14, - X86_REG_R15 = 15, - X86_REG_EIP = 16 -#endif -}; -#endif + // FIXME: this is partly redundant with the instruction decoding phase // to discover transfer type and register number static inline int ix86_step_over_modrm(unsigned char * p) @@ -989,10 +343,6 @@ static bool ix86_skip_instruction(SIGSEGV_REGISTER_TYPE * regs) if (eip == 0) return false; -#ifdef _WIN32 - if (IsBadCodePtr((FARPROC)eip)) - return false; -#endif enum instruction_type_t { i_MOV, @@ -1242,1261 +592,6 @@ static bool ix86_skip_instruction(SIGSEGV_REGISTER_TYPE * regs) } #endif -// Decode and skip IA-64 instruction -#if defined(__ia64) || defined(__ia64__) -typedef uint64_t ia64_bundle_t[2]; -#if defined(__linux__) -// We can directly patch the slot number -#define IA64_CAN_PATCH_IP_SLOT 1 -// Helper macros to access the machine context -#define IA64_CONTEXT_TYPE struct sigcontext * -#define IA64_CONTEXT scp -#define IA64_GET_IP() (IA64_CONTEXT->sc_ip) -#define IA64_SET_IP(V) (IA64_CONTEXT->sc_ip = (V)) -#define IA64_GET_PR(P) ((IA64_CONTEXT->sc_pr >> (P)) & 1) -#define IA64_GET_NAT(I) ((IA64_CONTEXT->sc_nat >> (I)) & 1) -#define IA64_GET_GR(R) (IA64_CONTEXT->sc_gr[(R)]) -#define _IA64_SET_GR(R,V) (IA64_CONTEXT->sc_gr[(R)] = (V)) -#define _IA64_SET_NAT(I,V) (IA64_CONTEXT->sc_nat = (IA64_CONTEXT->sc_nat & ~(1ull << (I))) | (((uint64_t)!!(V)) << (I))) -#define IA64_SET_GR(R,V,N) (_IA64_SET_GR(R,V), _IA64_SET_NAT(R,N)) - -// Load bundle (in little-endian) -static inline void ia64_load_bundle(ia64_bundle_t bundle, uint64_t raw_ip) -{ - uint64_t *ip = (uint64_t *)(raw_ip & ~3ull); - bundle[0] = ip[0]; - bundle[1] = ip[1]; -} -#endif -#if defined(__hpux) || defined(__hpux__) -// We can directly patch the slot number -#define IA64_CAN_PATCH_IP_SLOT 1 -// Helper macros to access the machine context -#define IA64_CONTEXT_TYPE ucontext_t * -#define IA64_CONTEXT ucp -#define IA64_GET_IP() ia64_get_ip(IA64_CONTEXT) -#define IA64_SET_IP(V) ia64_set_ip(IA64_CONTEXT, V) -#define IA64_GET_PR(P) ia64_get_pr(IA64_CONTEXT, P) -#define IA64_GET_NAT(I) ia64_get_nat(IA64_CONTEXT, I) -#define IA64_GET_GR(R) ia64_get_gr(IA64_CONTEXT, R) -#define IA64_SET_GR(R,V,N) ia64_set_gr(IA64_CONTEXT, R, V, N) -#define UC_ACCESS(FUNC,ARGS) do { if (__uc_##FUNC ARGS != 0) abort(); } while (0) - -static inline uint64_t ia64_get_ip(IA64_CONTEXT_TYPE IA64_CONTEXT) - { uint64_t v; UC_ACCESS(get_ip,(IA64_CONTEXT, &v)); return v; } -static inline void ia64_set_ip(IA64_CONTEXT_TYPE IA64_CONTEXT, uint64_t v) - { UC_ACCESS(set_ip,(IA64_CONTEXT, v)); } -static inline unsigned int ia64_get_pr(IA64_CONTEXT_TYPE IA64_CONTEXT, int pr) - { uint64_t v; UC_ACCESS(get_prs,(IA64_CONTEXT, &v)); return (v >> pr) & 1; } -static inline unsigned int ia64_get_nat(IA64_CONTEXT_TYPE IA64_CONTEXT, int r) - { uint64_t v; unsigned int nat; UC_ACCESS(get_grs,(IA64_CONTEXT, r, 1, &v, &nat)); return (nat >> r) & 1; } -static inline uint64_t ia64_get_gr(IA64_CONTEXT_TYPE IA64_CONTEXT, int r) - { uint64_t v; unsigned int nat; UC_ACCESS(get_grs,(IA64_CONTEXT, r, 1, &v, &nat)); return v; } - -static void ia64_set_gr(IA64_CONTEXT_TYPE IA64_CONTEXT, int r, uint64_t v, unsigned int nat) -{ - if (r == 0) - return; - if (r > 0 && r < 32) - UC_ACCESS(set_grs,(IA64_CONTEXT, r, 1, &v, (!!nat) << r)); - else { - uint64_t bsp, bspstore; - UC_ACCESS(get_ar_bsp,(IA64_CONTEXT, &bsp)); - UC_ACCESS(get_ar_bspstore,(IA64_CONTEXT, &bspstore)); - abort(); /* XXX: use libunwind, this is not fun... */ - } -} - -// Byte-swapping -#if defined(__GNUC__) -#define BSWAP64(V) ({ uint64_t r; __asm__ __volatile__("mux1 %0=%1,@rev;;" : "=r" (r) : "r" (V)); r; }) -#elif defined (__HP_aCC) -#define BSWAP64(V) _Asm_mux1(_MBTYPE_REV, V) -#else -#error "Define byte-swap instruction" -#endif - -// Load bundle (in little-endian) -static inline void ia64_load_bundle(ia64_bundle_t bundle, uint64_t raw_ip) -{ - uint64_t *ip = (uint64_t *)(raw_ip & ~3ull); - bundle[0] = BSWAP64(ip[0]); - bundle[1] = BSWAP64(ip[1]); -} -#endif - -// Instruction operations -enum { - IA64_INST_UNKNOWN = 0, - IA64_INST_LD1, // ld1 op0=[op1] - IA64_INST_LD1_UPDATE, // ld1 op0=[op1],op2 - IA64_INST_LD2, // ld2 op0=[op1] - IA64_INST_LD2_UPDATE, // ld2 op0=[op1],op2 - IA64_INST_LD4, // ld4 op0=[op1] - IA64_INST_LD4_UPDATE, // ld4 op0=[op1],op2 - IA64_INST_LD8, // ld8 op0=[op1] - IA64_INST_LD8_UPDATE, // ld8 op0=[op1],op2 - IA64_INST_ST1, // st1 [op0]=op1 - IA64_INST_ST1_UPDATE, // st1 [op0]=op1,op2 - IA64_INST_ST2, // st2 [op0]=op1 - IA64_INST_ST2_UPDATE, // st2 [op0]=op1,op2 - IA64_INST_ST4, // st4 [op0]=op1 - IA64_INST_ST4_UPDATE, // st4 [op0]=op1,op2 - IA64_INST_ST8, // st8 [op0]=op1 - IA64_INST_ST8_UPDATE, // st8 [op0]=op1,op2 - IA64_INST_ADD, // add op0=op1,op2,op3 - IA64_INST_SUB, // sub op0=op1,op2,op3 - IA64_INST_SHLADD, // shladd op0=op1,op3,op2 - IA64_INST_AND, // and op0=op1,op2 - IA64_INST_ANDCM, // andcm op0=op1,op2 - IA64_INST_OR, // or op0=op1,op2 - IA64_INST_XOR, // xor op0=op1,op2 - IA64_INST_SXT1, // sxt1 op0=op1 - IA64_INST_SXT2, // sxt2 op0=op1 - IA64_INST_SXT4, // sxt4 op0=op1 - IA64_INST_ZXT1, // zxt1 op0=op1 - IA64_INST_ZXT2, // zxt2 op0=op1 - IA64_INST_ZXT4, // zxt4 op0=op1 - IA64_INST_NOP // nop op0 -}; - -const int IA64_N_OPERANDS = 4; - -// Decoded operand type -struct ia64_operand_t { - uint8_t commit; // commit result of operation to register file? - uint8_t valid; // XXX: not really used, can be removed (debug) - int8_t index; // index of GPR, or -1 if immediate value - uint8_t nat; // NaT state before operation - uint64_t value; // register contents or immediate value -}; - -// Decoded instruction type -struct ia64_instruction_t { - uint8_t mnemo; // operation to perform - uint8_t pred; // predicate register to check - uint8_t no_memory; // used to emulated main fault instruction - uint64_t inst; // the raw instruction bits (41-bit wide) - ia64_operand_t operands[IA64_N_OPERANDS]; -}; - -// Get immediate sign-bit -static inline int ia64_inst_get_sbit(uint64_t inst) -{ - return (inst >> 36) & 1; -} - -// Get 8-bit immediate value (A3, A8, I27, M30) -static inline uint64_t ia64_inst_get_imm8(uint64_t inst) -{ - uint64_t value = (inst >> 13) & 0x7full; - if (ia64_inst_get_sbit(inst)) - value |= ~0x7full; - return value; -} - -// Get 9-bit immediate value (M3) -static inline uint64_t ia64_inst_get_imm9b(uint64_t inst) -{ - uint64_t value = (((inst >> 27) & 1) << 7) | ((inst >> 13) & 0x7f); - if (ia64_inst_get_sbit(inst)) - value |= ~0xffull; - return value; -} - -// Get 9-bit immediate value (M5) -static inline uint64_t ia64_inst_get_imm9a(uint64_t inst) -{ - uint64_t value = (((inst >> 27) & 1) << 7) | ((inst >> 6) & 0x7f); - if (ia64_inst_get_sbit(inst)) - value |= ~0xffull; - return value; -} - -// Get 14-bit immediate value (A4) -static inline uint64_t ia64_inst_get_imm14(uint64_t inst) -{ - uint64_t value = (((inst >> 27) & 0x3f) << 7) | (inst & 0x7f); - if (ia64_inst_get_sbit(inst)) - value |= ~0x1ffull; - return value; -} - -// Get 22-bit immediate value (A5) -static inline uint64_t ia64_inst_get_imm22(uint64_t inst) -{ - uint64_t value = ((((inst >> 22) & 0x1f) << 16) | - (((inst >> 27) & 0x1ff) << 7) | - (inst & 0x7f)); - if (ia64_inst_get_sbit(inst)) - value |= ~0x1fffffull; - return value; -} - -// Get 21-bit immediate value (I19) -static inline uint64_t ia64_inst_get_imm21(uint64_t inst) -{ - return (((inst >> 36) & 1) << 20) | ((inst >> 6) & 0xfffff); -} - -// Get 2-bit count value (A2) -static inline int ia64_inst_get_count2(uint64_t inst) -{ - return (inst >> 27) & 0x3; -} - -// Get bundle template -static inline unsigned int ia64_get_template(uint64_t ip) -{ - ia64_bundle_t bundle; - ia64_load_bundle(bundle, ip); - return bundle[0] & 0x1f; -} - -// Get specified instruction in bundle -static uint64_t ia64_get_instruction(uint64_t ip, int slot) -{ - uint64_t inst; - ia64_bundle_t bundle; - ia64_load_bundle(bundle, ip); -#if DEBUG - printf("Bundle: %016llx%016llx\n", bundle[1], bundle[0]); -#endif - - switch (slot) { - case 0: - inst = (bundle[0] >> 5) & 0x1ffffffffffull; - break; - case 1: - inst = ((bundle[1] & 0x7fffffull) << 18) | ((bundle[0] >> 46) & 0x3ffffull); - break; - case 2: - inst = (bundle[1] >> 23) & 0x1ffffffffffull; - break; - case 3: - fprintf(stderr, "ERROR: ia64_get_instruction(), invalid slot number %d\n", slot); - abort(); - break; - } - -#if DEBUG - printf(" Instruction %d: 0x%016llx\n", slot, inst); -#endif - return inst; -} - -// Decode group 0 instructions -static bool ia64_decode_instruction_0(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) -{ - const int r1 = (inst->inst >> 6) & 0x7f; - const int r3 = (inst->inst >> 20) & 0x7f; - - const int x3 = (inst->inst >> 33) & 0x07; - const int x6 = (inst->inst >> 27) & 0x3f; - const int x2 = (inst->inst >> 31) & 0x03; - const int x4 = (inst->inst >> 27) & 0x0f; - - if (x3 == 0) { - switch (x6) { - case 0x01: // nop.i (I19) - inst->mnemo = IA64_INST_NOP; - inst->operands[0].valid = true; - inst->operands[0].index = -1; - inst->operands[0].value = ia64_inst_get_imm21(inst->inst); - return true; - case 0x14: // sxt1 (I29) - case 0x15: // sxt2 (I29) - case 0x16: // sxt4 (I29) - case 0x10: // zxt1 (I29) - case 0x11: // zxt2 (I29) - case 0x12: // zxt4 (I29) - switch (x6) { - case 0x14: inst->mnemo = IA64_INST_SXT1; break; - case 0x15: inst->mnemo = IA64_INST_SXT2; break; - case 0x16: inst->mnemo = IA64_INST_SXT4; break; - case 0x10: inst->mnemo = IA64_INST_ZXT1; break; - case 0x11: inst->mnemo = IA64_INST_ZXT2; break; - case 0x12: inst->mnemo = IA64_INST_ZXT4; break; - default: abort(); - } - inst->operands[0].valid = true; - inst->operands[0].index = r1; - inst->operands[1].valid = true; - inst->operands[1].index = r3; - inst->operands[1].value = IA64_GET_GR(r3); - inst->operands[1].nat = IA64_GET_NAT(r3); - return true; - } - } - return false; -} - -// Decode group 4 instructions (load/store instructions) -static bool ia64_decode_instruction_4(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) -{ - const int r1 = (inst->inst >> 6) & 0x7f; - const int r2 = (inst->inst >> 13) & 0x7f; - const int r3 = (inst->inst >> 20) & 0x7f; - - const int m = (inst->inst >> 36) & 1; - const int x = (inst->inst >> 27) & 1; - const int x6 = (inst->inst >> 30) & 0x3f; - - switch (x6) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - if (x == 0) { - inst->operands[0].valid = true; - inst->operands[0].index = r1; - inst->operands[1].valid = true; - inst->operands[1].index = r3; - inst->operands[1].value = IA64_GET_GR(r3); - inst->operands[1].nat = IA64_GET_NAT(r3); - if (m == 0) { - switch (x6) { - case 0x00: inst->mnemo = IA64_INST_LD1; break; - case 0x01: inst->mnemo = IA64_INST_LD2; break; - case 0x02: inst->mnemo = IA64_INST_LD4; break; - case 0x03: inst->mnemo = IA64_INST_LD8; break; - } - } - else { - inst->operands[2].valid = true; - inst->operands[2].index = r2; - inst->operands[2].value = IA64_GET_GR(r2); - inst->operands[2].nat = IA64_GET_NAT(r2); - switch (x6) { - case 0x00: inst->mnemo = IA64_INST_LD1_UPDATE; break; - case 0x01: inst->mnemo = IA64_INST_LD2_UPDATE; break; - case 0x02: inst->mnemo = IA64_INST_LD4_UPDATE; break; - case 0x03: inst->mnemo = IA64_INST_LD8_UPDATE; break; - } - } - return true; - } - break; - case 0x30: - case 0x31: - case 0x32: - case 0x33: - if (m == 0 && x == 0) { - inst->operands[0].valid = true; - inst->operands[0].index = r3; - inst->operands[0].value = IA64_GET_GR(r3); - inst->operands[0].nat = IA64_GET_NAT(r3); - inst->operands[1].valid = true; - inst->operands[1].index = r2; - inst->operands[1].value = IA64_GET_GR(r2); - inst->operands[1].nat = IA64_GET_NAT(r2); - switch (x6) { - case 0x30: inst->mnemo = IA64_INST_ST1; break; - case 0x31: inst->mnemo = IA64_INST_ST2; break; - case 0x32: inst->mnemo = IA64_INST_ST4; break; - case 0x33: inst->mnemo = IA64_INST_ST8; break; - } - return true; - } - break; - } - return false; -} - -// Decode group 5 instructions (load/store instructions) -static bool ia64_decode_instruction_5(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) -{ - const int r1 = (inst->inst >> 6) & 0x7f; - const int r2 = (inst->inst >> 13) & 0x7f; - const int r3 = (inst->inst >> 20) & 0x7f; - - const int x6 = (inst->inst >> 30) & 0x3f; - - switch (x6) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - inst->operands[0].valid = true; - inst->operands[0].index = r1; - inst->operands[1].valid = true; - inst->operands[1].index = r3; - inst->operands[1].value = IA64_GET_GR(r3); - inst->operands[1].nat = IA64_GET_NAT(r3); - inst->operands[2].valid = true; - inst->operands[2].index = -1; - inst->operands[2].value = ia64_inst_get_imm9b(inst->inst); - inst->operands[2].nat = 0; - switch (x6) { - case 0x00: inst->mnemo = IA64_INST_LD1_UPDATE; break; - case 0x01: inst->mnemo = IA64_INST_LD2_UPDATE; break; - case 0x02: inst->mnemo = IA64_INST_LD4_UPDATE; break; - case 0x03: inst->mnemo = IA64_INST_LD8_UPDATE; break; - } - return true; - case 0x30: - case 0x31: - case 0x32: - case 0x33: - inst->operands[0].valid = true; - inst->operands[0].index = r3; - inst->operands[0].value = IA64_GET_GR(r3); - inst->operands[0].nat = IA64_GET_NAT(r3); - inst->operands[1].valid = true; - inst->operands[1].index = r2; - inst->operands[1].value = IA64_GET_GR(r2); - inst->operands[1].nat = IA64_GET_NAT(r2); - inst->operands[2].valid = true; - inst->operands[2].index = -1; - inst->operands[2].value = ia64_inst_get_imm9a(inst->inst); - inst->operands[2].nat = 0; - switch (x6) { - case 0x30: inst->mnemo = IA64_INST_ST1_UPDATE; break; - case 0x31: inst->mnemo = IA64_INST_ST2_UPDATE; break; - case 0x32: inst->mnemo = IA64_INST_ST4_UPDATE; break; - case 0x33: inst->mnemo = IA64_INST_ST8_UPDATE; break; - } - return true; - } - return false; -} - -// Decode group 8 instructions (ALU integer) -static bool ia64_decode_instruction_8(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) -{ - const int r1 = (inst->inst >> 6) & 0x7f; - const int r2 = (inst->inst >> 13) & 0x7f; - const int r3 = (inst->inst >> 20) & 0x7f; - - const int x2a = (inst->inst >> 34) & 0x3; - const int x2b = (inst->inst >> 27) & 0x3; - const int x4 = (inst->inst >> 29) & 0xf; - const int ve = (inst->inst >> 33) & 0x1; - - // destination register (r1) is always valid in this group - inst->operands[0].valid = true; - inst->operands[0].index = r1; - - // source register (r3) is always valid in this group - inst->operands[2].valid = true; - inst->operands[2].index = r3; - inst->operands[2].value = IA64_GET_GR(r3); - inst->operands[2].nat = IA64_GET_NAT(r3); - - if (x2a == 0 && ve == 0) { - inst->operands[1].valid = true; - inst->operands[1].index = r2; - inst->operands[1].value = IA64_GET_GR(r2); - inst->operands[1].nat = IA64_GET_NAT(r2); - switch (x4) { - case 0x0: // add (A1) - inst->mnemo = IA64_INST_ADD; - inst->operands[3].valid = true; - inst->operands[3].index = -1; - inst->operands[3].value = x2b == 1; - return true; - case 0x1: // add (A1) - inst->mnemo = IA64_INST_SUB; - inst->operands[3].valid = true; - inst->operands[3].index = -1; - inst->operands[3].value = x2b == 0; - return true; - case 0x4: // shladd (A2) - inst->mnemo = IA64_INST_SHLADD; - inst->operands[3].valid = true; - inst->operands[3].index = -1; - inst->operands[3].value = ia64_inst_get_count2(inst->inst); - return true; - case 0x9: - if (x2b == 1) { - inst->mnemo = IA64_INST_SUB; - inst->operands[1].index = -1; - inst->operands[1].value = ia64_inst_get_imm8(inst->inst); - inst->operands[1].nat = 0; - return true; - } - break; - case 0xb: - inst->operands[1].index = -1; - inst->operands[1].value = ia64_inst_get_imm8(inst->inst); - inst->operands[1].nat = 0; - // fall-through - case 0x3: - switch (x2b) { - case 0: inst->mnemo = IA64_INST_AND; break; - case 1: inst->mnemo = IA64_INST_ANDCM; break; - case 2: inst->mnemo = IA64_INST_OR; break; - case 3: inst->mnemo = IA64_INST_XOR; break; - } - return true; - } - } - return false; -} - -// Decode instruction -static bool ia64_decode_instruction(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) -{ - const int major = (inst->inst >> 37) & 0xf; - - inst->mnemo = IA64_INST_UNKNOWN; - inst->pred = inst->inst & 0x3f; - memset(&inst->operands[0], 0, sizeof(inst->operands)); - - switch (major) { - case 0x0: return ia64_decode_instruction_0(inst, IA64_CONTEXT); - case 0x4: return ia64_decode_instruction_4(inst, IA64_CONTEXT); - case 0x5: return ia64_decode_instruction_5(inst, IA64_CONTEXT); - case 0x8: return ia64_decode_instruction_8(inst, IA64_CONTEXT); - } - return false; -} - -static bool ia64_emulate_instruction(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) -{ - // XXX: handle Register NaT Consumption fault? - // XXX: this simple emulator assumes instructions in a bundle - // don't depend on effects of other instructions in the same - // bundle. It probably would be simpler to JIT-generate code to be - // executed natively but probably more costly (inject/extract CPU state) - if (inst->mnemo == IA64_INST_UNKNOWN) - return false; - if (inst->pred && !IA64_GET_PR(inst->pred)) - return true; - - uint8_t nat, nat2; - uint64_t dst, dst2, src1, src2, src3; - - switch (inst->mnemo) { - case IA64_INST_NOP: - break; - case IA64_INST_ADD: - case IA64_INST_SUB: - case IA64_INST_SHLADD: - src3 = inst->operands[3].value; - // fall-through - case IA64_INST_AND: - case IA64_INST_ANDCM: - case IA64_INST_OR: - case IA64_INST_XOR: - src1 = inst->operands[1].value; - src2 = inst->operands[2].value; - switch (inst->mnemo) { - case IA64_INST_ADD: dst = src1 + src2 + src3; break; - case IA64_INST_SUB: dst = src1 - src2 - src3; break; - case IA64_INST_SHLADD: dst = (src1 << src3) + src2; break; - case IA64_INST_AND: dst = src1 & src2; break; - case IA64_INST_ANDCM: dst = src1 &~ src2; break; - case IA64_INST_OR: dst = src1 | src2; break; - case IA64_INST_XOR: dst = src1 ^ src2; break; - } - inst->operands[0].commit = true; - inst->operands[0].value = dst; - inst->operands[0].nat = inst->operands[1].nat | inst->operands[2].nat; - break; - case IA64_INST_SXT1: - case IA64_INST_SXT2: - case IA64_INST_SXT4: - case IA64_INST_ZXT1: - case IA64_INST_ZXT2: - case IA64_INST_ZXT4: - src1 = inst->operands[1].value; - switch (inst->mnemo) { - case IA64_INST_SXT1: dst = (int64_t)(int8_t)src1; break; - case IA64_INST_SXT2: dst = (int64_t)(int16_t)src1; break; - case IA64_INST_SXT4: dst = (int64_t)(int32_t)src1; break; - case IA64_INST_ZXT1: dst = (uint8_t)src1; break; - case IA64_INST_ZXT2: dst = (uint16_t)src1; break; - case IA64_INST_ZXT4: dst = (uint32_t)src1; break; - } - inst->operands[0].commit = true; - inst->operands[0].value = dst; - inst->operands[0].nat = inst->operands[1].nat; - break; - case IA64_INST_LD1_UPDATE: - case IA64_INST_LD2_UPDATE: - case IA64_INST_LD4_UPDATE: - case IA64_INST_LD8_UPDATE: - inst->operands[1].commit = true; - dst2 = inst->operands[1].value + inst->operands[2].value; - nat2 = inst->operands[2].nat ? inst->operands[2].nat : 0; - // fall-through - case IA64_INST_LD1: - case IA64_INST_LD2: - case IA64_INST_LD4: - case IA64_INST_LD8: - src1 = inst->operands[1].value; - if (inst->no_memory) - dst = 0; - else { - switch (inst->mnemo) { - case IA64_INST_LD1: case IA64_INST_LD1_UPDATE: dst = *((uint8_t *)src1); break; - case IA64_INST_LD2: case IA64_INST_LD2_UPDATE: dst = *((uint16_t *)src1); break; - case IA64_INST_LD4: case IA64_INST_LD4_UPDATE: dst = *((uint32_t *)src1); break; - case IA64_INST_LD8: case IA64_INST_LD8_UPDATE: dst = *((uint64_t *)src1); break; - } - } - inst->operands[0].commit = true; - inst->operands[0].value = dst; - inst->operands[0].nat = 0; - inst->operands[1].value = dst2; - inst->operands[1].nat = nat2; - break; - case IA64_INST_ST1_UPDATE: - case IA64_INST_ST2_UPDATE: - case IA64_INST_ST4_UPDATE: - case IA64_INST_ST8_UPDATE: - inst->operands[0].commit = 0; - dst2 = inst->operands[0].value + inst->operands[2].value; - nat2 = inst->operands[2].nat ? inst->operands[2].nat : 0; - // fall-through - case IA64_INST_ST1: - case IA64_INST_ST2: - case IA64_INST_ST4: - case IA64_INST_ST8: - dst = inst->operands[0].value; - src1 = inst->operands[1].value; - if (!inst->no_memory) { - switch (inst->mnemo) { - case IA64_INST_ST1: case IA64_INST_ST1_UPDATE: *((uint8_t *)dst) = src1; break; - case IA64_INST_ST2: case IA64_INST_ST2_UPDATE: *((uint16_t *)dst) = src1; break; - case IA64_INST_ST4: case IA64_INST_ST4_UPDATE: *((uint32_t *)dst) = src1; break; - case IA64_INST_ST8: case IA64_INST_ST8_UPDATE: *((uint64_t *)dst) = src1; break; - } - } - inst->operands[0].value = dst2; - inst->operands[0].nat = nat2; - break; - default: - return false; - } - - for (int i = 0; i < IA64_N_OPERANDS; i++) { - ia64_operand_t const & op = inst->operands[i]; - if (!op.commit) - continue; - if (op.index == -1) - return false; // XXX: internal error - IA64_SET_GR(op.index, op.value, op.nat); - } - return true; -} - -static bool ia64_emulate_instruction(uint64_t raw_inst, IA64_CONTEXT_TYPE IA64_CONTEXT) -{ - ia64_instruction_t inst; - memset(&inst, 0, sizeof(inst)); - inst.inst = raw_inst; - if (!ia64_decode_instruction(&inst, IA64_CONTEXT)) - return false; - return ia64_emulate_instruction(&inst, IA64_CONTEXT); -} - -static bool ia64_skip_instruction(IA64_CONTEXT_TYPE IA64_CONTEXT) -{ - uint64_t ip = IA64_GET_IP(); -#if DEBUG - printf("IP: 0x%016llx\n", ip); -#if 0 - printf(" Template 0x%02x\n", ia64_get_template(ip)); - ia64_get_instruction(ip, 0); - ia64_get_instruction(ip, 1); - ia64_get_instruction(ip, 2); -#endif -#endif - - // Select which decode switch to use - ia64_instruction_t inst; - inst.inst = ia64_get_instruction(ip, ip & 3); - if (!ia64_decode_instruction(&inst, IA64_CONTEXT)) { - fprintf(stderr, "ERROR: ia64_skip_instruction(): could not decode instruction\n"); - return false; - } - - transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN; - transfer_size_t transfer_size = SIZE_UNKNOWN; - - switch (inst.mnemo) { - case IA64_INST_LD1: - case IA64_INST_LD2: - case IA64_INST_LD4: - case IA64_INST_LD8: - case IA64_INST_LD1_UPDATE: - case IA64_INST_LD2_UPDATE: - case IA64_INST_LD4_UPDATE: - case IA64_INST_LD8_UPDATE: - transfer_type = SIGSEGV_TRANSFER_LOAD; - break; - case IA64_INST_ST1: - case IA64_INST_ST2: - case IA64_INST_ST4: - case IA64_INST_ST8: - case IA64_INST_ST1_UPDATE: - case IA64_INST_ST2_UPDATE: - case IA64_INST_ST4_UPDATE: - case IA64_INST_ST8_UPDATE: - transfer_type = SIGSEGV_TRANSFER_STORE; - break; - } - - if (transfer_type == SIGSEGV_TRANSFER_UNKNOWN) { - // Unknown machine code, let it crash. Then patch the decoder - fprintf(stderr, "ERROR: ia64_skip_instruction(): not a load/store instruction\n"); - return false; - } - - switch (inst.mnemo) { - case IA64_INST_LD1: - case IA64_INST_LD1_UPDATE: - case IA64_INST_ST1: - case IA64_INST_ST1_UPDATE: - transfer_size = SIZE_BYTE; - break; - case IA64_INST_LD2: - case IA64_INST_LD2_UPDATE: - case IA64_INST_ST2: - case IA64_INST_ST2_UPDATE: - transfer_size = SIZE_WORD; - break; - case IA64_INST_LD4: - case IA64_INST_LD4_UPDATE: - case IA64_INST_ST4: - case IA64_INST_ST4_UPDATE: - transfer_size = SIZE_LONG; - break; - case IA64_INST_LD8: - case IA64_INST_LD8_UPDATE: - case IA64_INST_ST8: - case IA64_INST_ST8_UPDATE: - transfer_size = SIZE_QUAD; - break; - } - - if (transfer_size == SIZE_UNKNOWN) { - // Unknown machine code, let it crash. Then patch the decoder - fprintf(stderr, "ERROR: ia64_skip_instruction(): unknown transfer size\n"); - return false; - } - - inst.no_memory = true; - if (!ia64_emulate_instruction(&inst, IA64_CONTEXT)) { - fprintf(stderr, "ERROR: ia64_skip_instruction(): could not emulate fault instruction\n"); - return false; - } - - int slot = ip & 3; - bool emulate_next = false; - switch (slot) { - case 0: - switch (ia64_get_template(ip)) { - case 0x2: // MI;I - case 0x3: // MI;I; - emulate_next = true; - slot = 2; - break; - case 0xa: // M;MI - case 0xb: // M;MI; - emulate_next = true; - slot = 1; - break; - } - break; - } - if (emulate_next && !IA64_CAN_PATCH_IP_SLOT) { - while (slot < 3) { - if (!ia64_emulate_instruction(ia64_get_instruction(ip, slot), IA64_CONTEXT)) { - fprintf(stderr, "ERROR: ia64_skip_instruction(): could not emulate instruction\n"); - return false; - } - ++slot; - } - } - -#if IA64_CAN_PATCH_IP_SLOT - if ((slot = ip & 3) < 2) - IA64_SET_IP((ip & ~3ull) + (slot + 1)); - else -#endif - IA64_SET_IP((ip & ~3ull) + 16); -#if DEBUG - printf("IP: 0x%016llx\n", IA64_GET_IP()); -#endif - return true; -} -#endif - -// Decode and skip PPC instruction -#if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__)) -static bool powerpc_skip_instruction(unsigned long * nip_p, unsigned long * regs) -{ - instruction_t instr; - powerpc_decode_instruction(&instr, *nip_p, regs); - - if (instr.transfer_type == SIGSEGV_TRANSFER_UNKNOWN) { - // Unknown machine code, let it crash. Then patch the decoder - return false; - } - -#if DEBUG - printf("%08x: %s %s access", *nip_p, - instr.transfer_size == SIZE_BYTE ? "byte" : - instr.transfer_size == SIZE_WORD ? "word" : - instr.transfer_size == SIZE_LONG ? "long" : "quad", - instr.transfer_type == SIGSEGV_TRANSFER_LOAD ? "read" : "write"); - - if (instr.addr_mode == MODE_U || instr.addr_mode == MODE_UX) - printf(" r%d (ra = %08x)\n", instr.ra, instr.addr); - if (instr.transfer_type == SIGSEGV_TRANSFER_LOAD) - printf(" r%d (rd = 0)\n", instr.rd); -#endif - - if (instr.addr_mode == MODE_U || instr.addr_mode == MODE_UX) - regs[instr.ra] = instr.addr; - if (instr.transfer_type == SIGSEGV_TRANSFER_LOAD) - regs[instr.rd] = 0; - - *nip_p += 4; - return true; -} -#endif - -// Decode and skip MIPS instruction -#if (defined(mips) || defined(__mips)) -static bool mips_skip_instruction(greg_t * pc_p, greg_t * regs) -{ - unsigned int * epc = (unsigned int *)(unsigned long)*pc_p; - - if (epc == 0) - return false; - -#if DEBUG - printf("IP: %p [%08x]\n", epc, epc[0]); -#endif - - transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN; - transfer_size_t transfer_size = SIZE_LONG; - int direction = 0; - - const unsigned int opcode = epc[0]; - switch (opcode >> 26) { - case 32: // Load Byte - case 36: // Load Byte Unsigned - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_BYTE; - break; - case 33: // Load Halfword - case 37: // Load Halfword Unsigned - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_WORD; - break; - case 35: // Load Word - case 39: // Load Word Unsigned - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_LONG; - break; - case 34: // Load Word Left - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_LONG; - direction = -1; - break; - case 38: // Load Word Right - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_LONG; - direction = 1; - break; - case 55: // Load Doubleword - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_QUAD; - break; - case 26: // Load Doubleword Left - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_QUAD; - direction = -1; - break; - case 27: // Load Doubleword Right - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_QUAD; - direction = 1; - break; - case 40: // Store Byte - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_BYTE; - break; - case 41: // Store Halfword - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_WORD; - break; - case 43: // Store Word - case 42: // Store Word Left - case 46: // Store Word Right - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_LONG; - break; - case 63: // Store Doubleword - case 44: // Store Doubleword Left - case 45: // Store Doubleword Right - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_QUAD; - break; - /* Misc instructions unlikely to be used within CPU emulators */ - case 48: // Load Linked Word - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_LONG; - break; - case 52: // Load Linked Doubleword - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_QUAD; - break; - case 56: // Store Conditional Word - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_LONG; - break; - case 60: // Store Conditional Doubleword - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_QUAD; - break; - } - - if (transfer_type == SIGSEGV_TRANSFER_UNKNOWN) { - // Unknown machine code, let it crash. Then patch the decoder - return false; - } - - // Zero target register in case of a load operation - const int reg = (opcode >> 16) & 0x1f; - if (transfer_type == SIGSEGV_TRANSFER_LOAD) { - if (direction == 0) - regs[reg] = 0; - else { - // FIXME: untested code - unsigned long ea = regs[(opcode >> 21) & 0x1f]; - ea += (signed long)(signed int)(signed short)(opcode & 0xffff); - const int offset = ea & (transfer_size == SIZE_LONG ? 3 : 7); - unsigned long value; - if (direction > 0) { - const unsigned long rmask = ~((1L << ((offset + 1) * 8)) - 1); - value = regs[reg] & rmask; - } - else { - const unsigned long lmask = (1L << (offset * 8)) - 1; - value = regs[reg] & lmask; - } - // restore most significant bits - if (transfer_size == SIZE_LONG) - value = (signed long)(signed int)value; - regs[reg] = value; - } - } - -#if DEBUG -#if (defined(_ABIN32) || defined(_ABI64)) - static const char * mips_gpr_names[32] = { - "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" - }; -#else - static const char * mips_gpr_names[32] = { - "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" - }; -#endif - printf("%s %s register %s\n", - transfer_size == SIZE_BYTE ? "byte" : - transfer_size == SIZE_WORD ? "word" : - transfer_size == SIZE_LONG ? "long" : - transfer_size == SIZE_QUAD ? "quad" : "unknown", - transfer_type == SIGSEGV_TRANSFER_LOAD ? "load to" : "store from", - mips_gpr_names[reg]); -#endif - - *pc_p += 4; - return true; -} -#endif - -// Decode and skip SPARC instruction -#if (defined(sparc) || defined(__sparc__)) -enum { -#if (defined(__sun__)) - SPARC_REG_G1 = REG_G1, - SPARC_REG_O0 = REG_O0, - SPARC_REG_PC = REG_PC, - SPARC_REG_nPC = REG_nPC -#endif -}; -static bool sparc_skip_instruction(unsigned long * regs, gwindows_t * gwins, struct rwindow * rwin) -{ - unsigned int * pc = (unsigned int *)regs[SPARC_REG_PC]; - - if (pc == 0) - return false; - -#if DEBUG - printf("IP: %p [%08x]\n", pc, pc[0]); -#endif - - transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN; - transfer_size_t transfer_size = SIZE_LONG; - bool register_pair = false; - - const unsigned int opcode = pc[0]; - if ((opcode >> 30) != 3) - return false; - switch ((opcode >> 19) & 0x3f) { - case 9: // Load Signed Byte - case 1: // Load Unsigned Byte - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_BYTE; - break; - case 10:// Load Signed Halfword - case 2: // Load Unsigned Word - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_WORD; - break; - case 8: // Load Word - case 0: // Load Unsigned Word - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_LONG; - break; - case 11:// Load Extended Word - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_QUAD; - break; - case 3: // Load Doubleword - transfer_type = SIGSEGV_TRANSFER_LOAD; - transfer_size = SIZE_LONG; - register_pair = true; - break; - case 5: // Store Byte - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_BYTE; - break; - case 6: // Store Halfword - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_WORD; - break; - case 4: // Store Word - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_LONG; - break; - case 14:// Store Extended Word - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_QUAD; - break; - case 7: // Store Doubleword - transfer_type = SIGSEGV_TRANSFER_STORE; - transfer_size = SIZE_LONG; - register_pair = true; - break; - } - - if (transfer_type == SIGSEGV_TRANSFER_UNKNOWN) { - // Unknown machine code, let it crash. Then patch the decoder - return false; - } - - const int reg = (opcode >> 25) & 0x1f; - -#if DEBUG - static const char * reg_names[] = { - "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7" - }; - printf("%s %s register %s\n", - transfer_size == SIZE_BYTE ? "byte" : - transfer_size == SIZE_WORD ? "word" : - transfer_size == SIZE_LONG ? "long" : - transfer_size == SIZE_QUAD ? "quad" : "unknown", - transfer_type == SIGSEGV_TRANSFER_LOAD ? "load to" : "store from", - reg_names[reg]); -#endif - - // Zero target register in case of a load operation - if (transfer_type == SIGSEGV_TRANSFER_LOAD && reg != 0) { - // FIXME: code to handle local & input registers is not tested - if (reg >= 1 && reg < 8) { - // global registers - regs[reg - 1 + SPARC_REG_G1] = 0; - } - else if (reg >= 8 && reg < 16) { - // output registers - regs[reg - 8 + SPARC_REG_O0] = 0; - } - else if (reg >= 16 && reg < 24) { - // local registers (in register windows) - if (gwins) - gwins->wbuf->rw_local[reg - 16] = 0; - else - rwin->rw_local[reg - 16] = 0; - } - else { - // input registers (in register windows) - if (gwins) - gwins->wbuf->rw_in[reg - 24] = 0; - else - rwin->rw_in[reg - 24] = 0; - } - } - - regs[SPARC_REG_PC] += 4; - regs[SPARC_REG_nPC] += 4; - return true; -} -#endif -#endif - -// Decode and skip ARM instruction -#if (defined(arm) || defined(__arm__)) -enum { -#if (defined(__linux__)) - ARM_REG_PC = 15, - ARM_REG_CPSR = 16 -#endif -}; -static bool arm_skip_instruction(unsigned long * regs) -{ - unsigned int * pc = (unsigned int *)regs[ARM_REG_PC]; - - if (pc == 0) - return false; - -#if DEBUG - printf("IP: %p [%08x]\n", pc, pc[0]); -#endif - - transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN; - transfer_size_t transfer_size = SIZE_UNKNOWN; - enum { op_sdt = 1, op_sdth = 2 }; - int op = 0; - - // Handle load/store instructions only - const unsigned int opcode = pc[0]; - switch ((opcode >> 25) & 7) { - case 0: // Halfword and Signed Data Transfer (LDRH, STRH, LDRSB, LDRSH) - op = op_sdth; - // Determine transfer size (S/H bits) - switch ((opcode >> 5) & 3) { - case 0: // SWP instruction - break; - case 1: // Unsigned halfwords - case 3: // Signed halfwords - transfer_size = SIZE_WORD; - break; - case 2: // Signed byte - transfer_size = SIZE_BYTE; - break; - } - break; - case 2: - case 3: // Single Data Transfer (LDR, STR) - op = op_sdt; - // Determine transfer size (B bit) - if (((opcode >> 22) & 1) == 1) - transfer_size = SIZE_BYTE; - else - transfer_size = SIZE_LONG; - break; - default: - // FIXME: support load/store mutliple? - return false; - } - - // Check for invalid transfer size (SWP instruction?) - if (transfer_size == SIZE_UNKNOWN) - return false; - - // Determine transfer type (L bit) - if (((opcode >> 20) & 1) == 1) - transfer_type = SIGSEGV_TRANSFER_LOAD; - else - transfer_type = SIGSEGV_TRANSFER_STORE; - - // Compute offset - int offset; - if (((opcode >> 25) & 1) == 0) { - if (op == op_sdt) - offset = opcode & 0xfff; - else if (op == op_sdth) { - int rm = opcode & 0xf; - if (((opcode >> 22) & 1) == 0) { - // register offset - offset = regs[rm]; - } - else { - // immediate offset - offset = ((opcode >> 4) & 0xf0) | (opcode & 0x0f); - } - } - } - else { - const int rm = opcode & 0xf; - const int sh = (opcode >> 7) & 0x1f; - if (((opcode >> 4) & 1) == 1) { - // we expect only legal load/store instructions - printf("FATAL: invalid shift operand\n"); - return false; - } - const unsigned int v = regs[rm]; - switch ((opcode >> 5) & 3) { - case 0: // logical shift left - offset = sh ? v << sh : v; - break; - case 1: // logical shift right - offset = sh ? v >> sh : 0; - break; - case 2: // arithmetic shift right - if (sh) - offset = ((signed int)v) >> sh; - else - offset = (v & 0x80000000) ? 0xffffffff : 0; - break; - case 3: // rotate right - if (sh) - offset = (v >> sh) | (v << (32 - sh)); - else - offset = (v >> 1) | ((regs[ARM_REG_CPSR] << 2) & 0x80000000); - break; - } - } - if (((opcode >> 23) & 1) == 0) - offset = -offset; - - int rd = (opcode >> 12) & 0xf; - int rn = (opcode >> 16) & 0xf; -#if DEBUG - static const char * reg_names[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r9", "r9", "sl", "fp", "ip", "sp", "lr", "pc" - }; - printf("%s %s register %s\n", - transfer_size == SIZE_BYTE ? "byte" : - transfer_size == SIZE_WORD ? "word" : - transfer_size == SIZE_LONG ? "long" : "unknown", - transfer_type == SIGSEGV_TRANSFER_LOAD ? "load to" : "store from", - reg_names[rd]); -#endif - - unsigned int base = regs[rn]; - if (((opcode >> 24) & 1) == 1) - base += offset; - - if (transfer_type == SIGSEGV_TRANSFER_LOAD) - regs[rd] = 0; - - if (((opcode >> 24) & 1) == 0) // post-index addressing - regs[rn] += offset; - else if (((opcode >> 21) & 1) == 1) // write-back address into base - regs[rn] = base; - - regs[ARM_REG_PC] += 4; - return true; -} #endif @@ -2528,18 +623,7 @@ static bool arm_skip_instruction(unsigned long * regs) */ #ifdef HAVE_MACH_EXCEPTIONS -#ifdef EMULATED_PPC -static void mach_get_exception_state(sigsegv_info_t *SIP) -{ - SIP->exc_state_count = SIGSEGV_EXCEPTION_STATE_COUNT; - kern_return_t krc = thread_get_state(SIP->thread, - SIGSEGV_EXCEPTION_STATE_FLAVOR, - (natural_t *)&SIP->exc_state, - &SIP->exc_state_count); - MACH_CHECK_ERROR(thread_get_state, krc); - SIP->has_exc_state = true; -} -#endif + static void mach_get_thread_state(sigsegv_info_t *SIP) { @@ -2565,28 +649,6 @@ static void mach_set_thread_state(sigsegv_info_t *SIP) // Return the address of the invalid memory reference sigsegv_address_t sigsegv_get_fault_address(sigsegv_info_t *SIP) { -#ifdef HAVE_MACH_EXCEPTIONS -#ifdef EMULATED_PPC - static int use_fast_path = -1; - if (use_fast_path != 1 && !SIP->has_exc_state) { - mach_get_exception_state(SIP); - - sigsegv_address_t addr = (sigsegv_address_t)SIGSEGV_FAULT_ADDRESS; - if (use_fast_path < 0) { - const char *machfault = getenv("SIGSEGV_MACH_FAULT"); - if (machfault) { - if (strcmp(machfault, "fast") == 0) - use_fast_path = 1; - else if (strcmp(machfault, "slow") == 0) - use_fast_path = 0; - } - if (use_fast_path < 0) - use_fast_path = addr == SIP->addr; - } - SIP->addr = addr; - } -#endif -#endif return SIP->addr; } @@ -2594,15 +656,6 @@ sigsegv_address_t sigsegv_get_fault_address(sigsegv_info_t *SIP) // SIGSEGV_INVALID_ADDRESS if we could not retrieve this information sigsegv_address_t sigsegv_get_fault_instruction_address(sigsegv_info_t *SIP) { -#ifdef HAVE_MACH_EXCEPTIONS -#ifdef EMULATED_PPC - if (!SIP->has_thr_state) { - mach_get_thread_state(SIP); - - SIP->pc = (sigsegv_address_t)SIGSEGV_FAULT_INSTRUCTION; - } -#endif -#endif return SIP->pc; } @@ -2907,10 +960,6 @@ static bool sigsegv_do_install_handler(int sig) sigemptyset(&sigsegv_sa.sa_mask); sigsegv_sa.sa_handler = (signal_handler)sigsegv_handler; sigsegv_sa.sa_flags = 0; -#if !EMULATED_68K && defined(__NetBSD__) - sigaddset(&sigsegv_sa.sa_mask, SIGALRM); - sigsegv_sa.sa_flags |= SA_ONSTACK; -#endif return (sigaction(sig, &sigsegv_sa, 0) == 0); #else return (signal(sig, (signal_handler)sigsegv_handler) != SIG_ERR); @@ -3003,95 +1052,6 @@ static bool sigsegv_do_install_handler(sigsegv_fault_handler_t handler) } #endif -#ifdef HAVE_WIN32_EXCEPTIONS -static LONG WINAPI main_exception_filter(EXCEPTION_POINTERS *ExceptionInfo) -{ - if (sigsegv_fault_handler != NULL - && ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION - && ExceptionInfo->ExceptionRecord->NumberParameters >= 2 - && handle_badaccess(ExceptionInfo)) - return EXCEPTION_CONTINUE_EXECUTION; - - return EXCEPTION_CONTINUE_SEARCH; -} - -#if defined __CYGWIN__ && defined __i386__ -/* In Cygwin programs, SetUnhandledExceptionFilter has no effect because Cygwin - installs a global exception handler. We have to dig deep in order to install - our main_exception_filter. */ - -/* Data structures for the current thread's exception handler chain. - On the x86 Windows uses register fs, offset 0 to point to the current - exception handler; Cygwin mucks with it, so we must do the same... :-/ */ - -/* Magic taken from winsup/cygwin/include/exceptions.h. */ - -struct exception_list { - struct exception_list *prev; - int (*handler) (EXCEPTION_RECORD *, void *, CONTEXT *, void *); -}; -typedef struct exception_list exception_list; - -/* Magic taken from winsup/cygwin/exceptions.cc. */ - -__asm__ (".equ __except_list,0"); - -extern exception_list *_except_list __asm__ ("%fs:__except_list"); - -/* For debugging. _except_list is not otherwise accessible from gdb. */ -static exception_list * -debug_get_except_list () -{ - return _except_list; -} - -/* Cygwin's original exception handler. */ -static int (*cygwin_exception_handler) (EXCEPTION_RECORD *, void *, CONTEXT *, void *); - -/* Our exception handler. */ -static int -libsigsegv_exception_handler (EXCEPTION_RECORD *exception, void *frame, CONTEXT *context, void *dispatch) -{ - EXCEPTION_POINTERS ExceptionInfo; - ExceptionInfo.ExceptionRecord = exception; - ExceptionInfo.ContextRecord = context; - if (main_exception_filter (&ExceptionInfo) == EXCEPTION_CONTINUE_SEARCH) - return cygwin_exception_handler (exception, frame, context, dispatch); - else - return 0; -} - -static void -do_install_main_exception_filter () -{ - /* We cannot insert any handler into the chain, because such handlers - must lie on the stack (?). Instead, we have to replace(!) Cygwin's - global exception handler. */ - cygwin_exception_handler = _except_list->handler; - _except_list->handler = libsigsegv_exception_handler; -} - -#else - -static void -do_install_main_exception_filter () -{ - SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER) &main_exception_filter); -} -#endif - -static bool sigsegv_do_install_handler(sigsegv_fault_handler_t handler) -{ - static bool main_exception_filter_installed = false; - if (!main_exception_filter_installed) { - do_install_main_exception_filter(); - main_exception_filter_installed = true; - } - sigsegv_fault_handler = handler; - return true; -} -#endif - bool sigsegv_install_handler(sigsegv_fault_handler_t handler) { #if defined(HAVE_SIGSEGV_RECOVERY) @@ -3102,7 +1062,7 @@ bool sigsegv_install_handler(sigsegv_fault_handler_t handler) if (success) sigsegv_fault_handler = handler; return success; -#elif defined(HAVE_MACH_EXCEPTIONS) || defined(HAVE_WIN32_EXCEPTIONS) +#elif defined(HAVE_MACH_EXCEPTIONS) return sigsegv_do_install_handler(handler); #else // FAIL: no siginfo_t nor sigcontext subterfuge is available @@ -3128,9 +1088,6 @@ void sigsegv_deinstall_handler(void) SIGSEGV_ALL_SIGNALS #undef FAULT_HANDLER #endif -#ifdef HAVE_WIN32_EXCEPTIONS - sigsegv_fault_handler = NULL; -#endif } diff --git a/BasiliskII/src/CrossPlatform/video_blit.cpp b/BasiliskII/src/CrossPlatform/video_blit.cpp index 19e400fd..d889291a 100644 --- a/BasiliskII/src/CrossPlatform/video_blit.cpp +++ b/BasiliskII/src/CrossPlatform/video_blit.cpp @@ -498,7 +498,7 @@ bool Screen_blitter_init(VisualFormat const & visual_format, bool native_byte_or #else const bool use_sdl_video = false; #endif -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING if (mac_depth == 1 && !use_sdl_video && !visual_format.fullscreen) { // Windowed 1-bit mode uses a 1-bit X image, so there's no need for special blitting routines diff --git a/BasiliskII/src/CrossPlatform/video_vosf.h b/BasiliskII/src/CrossPlatform/video_vosf.h index 4a5677e1..148a9e6f 100644 --- a/BasiliskII/src/CrossPlatform/video_vosf.h +++ b/BasiliskII/src/CrossPlatform/video_vosf.h @@ -26,10 +26,7 @@ #include "sigsegv.h" #include "vm_alloc.h" -#ifdef _WIN32 -#include "util_windows.h" -#endif - + // Glue for SDL and X11 support #ifdef TEST_VOSF_PERFORMANCE #define MONITOR_INIT /* nothing */ @@ -180,10 +177,6 @@ static inline unsigned find_next_page_clear(unsigned page) static pthread_mutex_t vosf_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to protect frame buffer (dirtyPages in fact) #define LOCK_VOSF pthread_mutex_lock(&vosf_lock); #define UNLOCK_VOSF pthread_mutex_unlock(&vosf_lock); -#elif defined(_WIN32) -static mutex_t vosf_lock; // Mutex to protect frame buffer (dirtyPages in fact) -#define LOCK_VOSF vosf_lock.lock(); -#define UNLOCK_VOSF vosf_lock.unlock(); #elif defined(HAVE_SPINLOCKS) static spinlock_t vosf_lock = SPIN_LOCK_UNLOCKED; // Mutex to protect frame buffer (dirtyPages in fact) #define LOCK_VOSF spin_lock(&vosf_lock) @@ -533,7 +526,7 @@ static void update_display_window_vosf(VIDEO_DRV_WIN_INIT) */ #ifndef TEST_VOSF_PERFORMANCE -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT) { VIDEO_MODE_INIT; diff --git a/BasiliskII/src/CrossPlatform/vm_alloc.cpp b/BasiliskII/src/CrossPlatform/vm_alloc.cpp index 005cb727..0dde455c 100644 --- a/BasiliskII/src/CrossPlatform/vm_alloc.cpp +++ b/BasiliskII/src/CrossPlatform/vm_alloc.cpp @@ -27,11 +27,6 @@ #include #endif -#ifdef HAVE_WIN32_VM -#define WIN32_LEAN_AND_MEAN /* avoid including junk */ -#include -#endif - #include #include #include @@ -53,13 +48,8 @@ #endif #endif -#ifdef HAVE_WIN32_VM -/* Windows is either ILP32 or LLP64 */ -typedef UINT_PTR vm_uintptr_t; -#else /* Other systems are sane as they are either ILP32 or LP64 */ typedef unsigned long vm_uintptr_t; -#endif /* We want MAP_32BIT, if available, for SheepShaver and BasiliskII because the emulated target is 32-bit and this helps to allocate @@ -71,11 +61,7 @@ typedef unsigned long vm_uintptr_t; #ifndef MAP_32BIT #define MAP_32BIT 0 #endif -#ifdef __FreeBSD__ -#define FORCE_MAP_32BIT MAP_FIXED -#else #define FORCE_MAP_32BIT MAP_32BIT -#endif #ifndef MAP_ANON #define MAP_ANON 0 #endif @@ -86,10 +72,9 @@ typedef unsigned long vm_uintptr_t; #define MAP_EXTRA_FLAGS (MAP_32BIT) #ifdef HAVE_MMAP_VM -#if (defined(__linux__) && defined(__i386__)) || defined(__FreeBSD__) || HAVE_LINKER_SCRIPT +#if HAVE_LINKER_SCRIPT /* Force a reasonnable address below 0x80000000 on x86 so that we - don't get addresses above when the program is run on AMD64. - NOTE: this is empirically determined on Linux/x86. */ + don't get addresses above when the program is run on AMD64. */ #define MAP_BASE 0x10000000 #else #define MAP_BASE 0x00000000 @@ -127,40 +112,6 @@ static int translate_map_flags(int vm_flags) } #endif -/* Align ADDR and SIZE to 64K boundaries. */ - -#ifdef HAVE_WIN32_VM -static inline LPVOID align_addr_segment(LPVOID addr) -{ - return LPVOID(vm_uintptr_t(addr) & ~vm_uintptr_t(0xFFFF)); -} - -static inline DWORD align_size_segment(LPVOID addr, DWORD size) -{ - return size + ((vm_uintptr_t)addr - (vm_uintptr_t)align_addr_segment(addr)); -} -#endif - -/* Translate generic VM prot flags to host values. */ - -#ifdef HAVE_WIN32_VM -static int translate_prot_flags(int prot_flags) -{ - int prot = PAGE_READWRITE; - if (prot_flags == (VM_PAGE_EXECUTE | VM_PAGE_READ | VM_PAGE_WRITE)) - prot = PAGE_EXECUTE_READWRITE; - else if (prot_flags == (VM_PAGE_EXECUTE | VM_PAGE_READ)) - prot = PAGE_EXECUTE_READ; - else if (prot_flags == (VM_PAGE_READ | VM_PAGE_WRITE)) - prot = PAGE_READWRITE; - else if (prot_flags == VM_PAGE_READ) - prot = PAGE_READONLY; - else if (prot_flags == 0) - prot = PAGE_NOACCESS; - return prot; -} -#endif - /* Translate Mach return codes to POSIX errno values. */ #ifdef HAVE_MACH_VM static int vm_error(kern_return_t ret_code) @@ -193,17 +144,17 @@ int vm_init(void) // On 10.4 and earlier, reset CrashReporter's task signal handler to // avoid having it show up for signals that get handled. -#if defined(__APPLE__) && defined(__MACH__) - struct utsname info; +// #if defined(__APPLE__) && defined(__MACH__) +// struct utsname info; - if (!uname(&info) && atoi(info.release) <= 8) { - task_set_exception_ports(mach_task_self(), - EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC, - MACH_PORT_NULL, - EXCEPTION_STATE_IDENTITY, - MACHINE_THREAD_STATE); - } -#endif +// if (!uname(&info) && atoi(info.release) <= 8) { +// task_set_exception_ports(mach_task_self(), +// EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC, +// MACH_PORT_NULL, +// EXCEPTION_STATE_IDENTITY, +// MACHINE_THREAD_STATE); +// } +// #endif return 0; } @@ -260,13 +211,6 @@ void * vm_acquire(size_t size, int options) return VM_MAP_FAILED; next_address = (char *)addr + size; -#elif defined(HAVE_WIN32_VM) - int alloc_type = MEM_RESERVE | MEM_COMMIT; - if (options & VM_MAP_WRITE_WATCH) - alloc_type |= MEM_WRITE_WATCH; - - if ((addr = VirtualAlloc(NULL, size, alloc_type, PAGE_EXECUTE_READWRITE)) == NULL) - return VM_MAP_FAILED; #else if ((addr = calloc(size, 1)) == 0) return VM_MAP_FAILED; @@ -312,21 +256,6 @@ int vm_acquire_fixed(void * addr, size_t size, int options) if (mmap((caddr_t)addr, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0) == (void *)MAP_FAILED) return -1; -#elif defined(HAVE_WIN32_VM) - // Windows cannot allocate Low Memory - if (addr == NULL) - return -1; - - int alloc_type = MEM_RESERVE | MEM_COMMIT; - if (options & VM_MAP_WRITE_WATCH) - alloc_type |= MEM_WRITE_WATCH; - - // Allocate a possibly offset region to align on 64K boundaries - LPVOID req_addr = align_addr_segment(addr); - DWORD req_size = align_size_segment(addr, size); - LPVOID ret_addr = VirtualAlloc(req_addr, req_size, alloc_type, PAGE_EXECUTE_READWRITE); - if (ret_addr != req_addr) - return -1; #else // Unsupported return -1; @@ -356,14 +285,9 @@ int vm_release(void * addr, size_t size) #ifdef HAVE_MMAP_VM if (munmap((caddr_t)addr, size) != 0) return -1; -#else -#ifdef HAVE_WIN32_VM - if (VirtualFree(align_addr_segment(addr), 0, MEM_RELEASE) == 0) - return -1; #else free(addr); #endif -#endif #endif return 0; @@ -381,17 +305,11 @@ int vm_protect(void * addr, size_t size, int prot) #ifdef HAVE_MMAP_VM int ret_code = mprotect((caddr_t)addr, size, prot); return ret_code == 0 ? 0 : -1; -#else -#ifdef HAVE_WIN32_VM - DWORD old_prot; - int ret_code = VirtualProtect(addr, size, translate_prot_flags(prot), &old_prot); - return ret_code != 0 ? 0 : -1; #else // Unsupported return -1; #endif #endif -#endif } /* Return the addresses of the pages that got modified in the @@ -403,20 +321,7 @@ int vm_get_write_watch(void * addr, size_t size, int options) { #ifdef HAVE_VM_WRITE_WATCH -#ifdef HAVE_WIN32_VM - DWORD flags = 0; - if (options & VM_WRITE_WATCH_RESET) - flags |= WRITE_WATCH_FLAG_RESET; - ULONG page_size; - ULONG_PTR count = *n_pages; - int ret_code = GetWriteWatch(flags, addr, size, pages, &count, &page_size); - if (ret_code != 0) - return -1; - - *n_pages = count; - return 0; -#endif #endif // Unsupported return -1; @@ -428,10 +333,7 @@ int vm_get_write_watch(void * addr, size_t size, int vm_reset_write_watch(void * addr, size_t size) { #ifdef HAVE_VM_WRITE_WATCH -#ifdef HAVE_WIN32_VM - int ret_code = ResetWriteWatch(addr, size); - return ret_code == 0 ? 0 : -1; -#endif + #endif // Unsupported return -1; @@ -441,17 +343,7 @@ int vm_reset_write_watch(void * addr, size_t size) int vm_get_page_size(void) { -#ifdef HAVE_WIN32_VM - static vm_uintptr_t page_size = 0; - if (page_size == 0) { - SYSTEM_INFO si; - GetSystemInfo(&si); - page_size = si.dwAllocationGranularity; - } - return page_size; -#else return getpagesize(); -#endif } #ifdef CONFIGURE_TEST_VM_WRITE_WATCH diff --git a/BasiliskII/src/MacOSX/AudioBackEnd.cpp b/BasiliskII/src/MacOSX/AudioBackEnd.cpp deleted file mode 100644 index 65a8cb5d..00000000 --- a/BasiliskII/src/MacOSX/AudioBackEnd.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* - * - * This is based on Apple example software AudioBackEnd.cpp - * - * Copyright © 2004 Apple Computer, Inc., All Rights Reserved - * Original Apple code modified by Daniel Sumorok - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "AudioBackEnd.h" - -#pragma mark ---Public Methods--- - -AudioBackEnd::AudioBackEnd(int bitsPerSample, int numChannels, int sampleRate): - mBitsPerSample(bitsPerSample), - mSampleRate(sampleRate), - mNumChannels(numChannels), - mCallback(NULL), - mCallbackArg(NULL), - mBufferSizeFrames(0), - mFramesProcessed(0), - mAudioBuffer(NULL), - mAudioBufferWriteIndex(0), - mAudioBufferReadIndex(0), - mBytesPerFrame(0), - mAudioBufferSize(0) { - OSStatus err = noErr; - err = Init(); - if(err) { - fprintf(stderr,"AudioBackEnd ERROR: Cannot Init AudioBackEnd"); - exit(1); - } -} - -AudioBackEnd::~AudioBackEnd() { //clean up - Stop(); - - AUGraphClose(mGraph); - DisposeAUGraph(mGraph); - - if(mAudioBuffer != NULL) { - delete mAudioBuffer; - mAudioBuffer = NULL; - mAudioBufferSize = 0; - } -} - -OSStatus AudioBackEnd::Init() { - OSStatus err = noErr; - - err = SetupGraph(); - checkErr(err); - - err = SetupBuffers(); - checkErr(err); - - err = AUGraphInitialize(mGraph); - checkErr(err); - - return err; -} - -#pragma mark --- Operation--- - -OSStatus AudioBackEnd::Start() -{ - OSStatus err = noErr; - if(!IsRunning()) { - mFramesProcessed = 0; - mAudioBufferWriteIndex = 0; - mAudioBufferReadIndex = 0; - - err = AUGraphStart(mGraph); - } - return err; -} - -OSStatus AudioBackEnd::Stop() { - OSStatus err = noErr; - - if(IsRunning()) { - err = AUGraphStop(mGraph); - } - return err; -} - -Boolean AudioBackEnd::IsRunning() { - OSStatus err = noErr; - Boolean graphRunning; - - err = AUGraphIsRunning(mGraph,&graphRunning); - - return (graphRunning); -} - -#pragma mark - -#pragma mark --Private methods--- -OSStatus AudioBackEnd::SetupGraph() { - OSStatus err = noErr; - AURenderCallbackStruct output; - UInt32 size; - ComponentDescription outDesc; - AudioDeviceID out; - - //Make a New Graph - err = NewAUGraph(&mGraph); - checkErr(err); - - //Open the Graph, AudioUnits are opened but not initialized - err = AUGraphOpen(mGraph); - checkErr(err); - - outDesc.componentType = kAudioUnitType_Output; - outDesc.componentSubType = kAudioUnitSubType_DefaultOutput; - outDesc.componentManufacturer = kAudioUnitManufacturer_Apple; - outDesc.componentFlags = 0; - outDesc.componentFlagsMask = 0; - - ////////////////////////// - ///MAKE NODES - //This creates a node in the graph that is an AudioUnit, using - //the supplied ComponentDescription to find and open that unit - err = AUGraphNewNode(mGraph, &outDesc, 0, NULL, &mOutputNode); - checkErr(err); - - //Get Audio Units from AUGraph node - err = AUGraphGetNodeInfo(mGraph, mOutputNode, NULL, NULL, NULL, &mOutputUnit); - checkErr(err); - - err = AUGraphUpdate(mGraph, NULL); - checkErr(err); - - size = sizeof(AudioDeviceID); - err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, - &size, &out); - checkErr(err); - mOutputDevice.Init(out, false); - - //Set the Current Device to the Default Output Unit. - err = AudioUnitSetProperty(mOutputUnit, - kAudioOutputUnitProperty_CurrentDevice, - kAudioUnitScope_Global, - 0, - &out, - sizeof(out)); - checkErr(err); - - output.inputProc = OutputProc; - output.inputProcRefCon = this; - - err = AudioUnitSetProperty(mOutputUnit, - kAudioUnitProperty_SetRenderCallback, - kAudioUnitScope_Input, - 0, - &output, - sizeof(output)); - checkErr(err); - return err; -} - -//Allocate Audio Buffer List(s) to hold the data from input. -OSStatus AudioBackEnd::SetupBuffers() { - OSStatus err = noErr; - UInt32 safetyOffset; - AudioStreamBasicDescription asbd; - UInt32 propertySize; - - propertySize = sizeof(mBufferSizeFrames); - err = AudioUnitGetProperty(mOutputUnit, kAudioDevicePropertyBufferFrameSize, - kAudioUnitScope_Global, 0, &mBufferSizeFrames, - &propertySize); - - propertySize = sizeof(safetyOffset); - safetyOffset = 0; - err = AudioUnitGetProperty(mOutputUnit, kAudioDevicePropertySafetyOffset, - kAudioUnitScope_Global, 0, &safetyOffset, - &propertySize); - - - asbd.mFormatID = 0x6c70636d; // 'lpcm' - asbd.mFormatFlags = (kAudioFormatFlagIsSignedInteger | - kAudioFormatFlagIsBigEndian | - kAudioFormatFlagIsPacked); - asbd.mChannelsPerFrame = mNumChannels; - asbd.mSampleRate = mSampleRate; - - if(asbd.mFormatFlags & kAudioFormatFlagIsSignedInteger) { - asbd.mBitsPerChannel = mBitsPerSample; - } else if(asbd.mFormatFlags & kAudioFormatFlagIsFloat) { - asbd.mBitsPerChannel = 32; - } else { - asbd.mBitsPerChannel = 0; - } - - asbd.mFramesPerPacket = 1; - asbd.mBytesPerFrame = (asbd.mBitsPerChannel / 8) * asbd.mChannelsPerFrame; - asbd.mBytesPerPacket = asbd.mBytesPerFrame * asbd.mFramesPerPacket; - - asbd.mReserved = 0; - - mBytesPerFrame = asbd.mBytesPerFrame; - if((mBytesPerFrame & (mBytesPerFrame - 1)) != 0) { - printf("Audio buffer size must be a power of two!\n"); - return -1; - } - - propertySize = sizeof(asbd); - err = AudioUnitSetProperty(mOutputUnit, kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Input, 0, &asbd, propertySize); - checkErr(err); - - if(mAudioBuffer != NULL) { - delete mAudioBuffer; - mAudioBufferSize = 0; - } - - mAudioBufferSize = mBytesPerFrame * mBufferSizeFrames * 2; - mAudioBuffer = new UInt8[mAudioBufferSize]; - bzero(mAudioBuffer, mAudioBufferSize); - return err; -} - -#pragma mark - -#pragma mark -- IO Procs -- -OSStatus AudioBackEnd::OutputProc(void *inRefCon, - AudioUnitRenderActionFlags *ioActionFlags, - const AudioTimeStamp *TimeStamp, - UInt32 inBusNumber, - UInt32 inNumberFrames, - AudioBufferList * ioData) { - OSStatus err = noErr; - AudioBackEnd *This = (AudioBackEnd *)inRefCon; - UInt8 *dstPtr; - UInt32 bytesToCopy; - UInt32 bytesUntilEnd; - - This->mFramesProcessed += inNumberFrames; - - dstPtr = (UInt8 *)ioData->mBuffers[0].mData; - if(This->mAudioBuffer == NULL) { - bzero(dstPtr, inNumberFrames * This->mBytesPerFrame); - return noErr; - } - - bytesToCopy = inNumberFrames * This->mBytesPerFrame; - bytesUntilEnd = This->mAudioBufferSize - This->mAudioBufferReadIndex; - if(bytesUntilEnd < bytesToCopy) { - memcpy(dstPtr, &This->mAudioBuffer[This->mAudioBufferReadIndex], - bytesUntilEnd); - memcpy(dstPtr, This->mAudioBuffer, bytesToCopy - bytesUntilEnd); - - This->mAudioBufferReadIndex = bytesToCopy - bytesUntilEnd; - } else { - memcpy(dstPtr, &This->mAudioBuffer[This->mAudioBufferReadIndex], - bytesToCopy); - This->mAudioBufferReadIndex += bytesToCopy; - } - - - while(This->mFramesProcessed >= This->mBufferSizeFrames) { - This->mFramesProcessed -= This->mBufferSizeFrames; - if(This->mCallback != NULL) { - This->mCallback(This->mCallbackArg); - } - } - - return err; -} - -void AudioBackEnd::setCallback(playthruCallback func, void *arg) { - mCallback = func; - mCallbackArg = arg; -} - -UInt32 AudioBackEnd::BufferSizeFrames() { - return mBufferSizeFrames; -} - -int AudioBackEnd::sendAudioBuffer(void *buffer, int numFrames) { - UInt8 *dstBuffer; - int totalBytes; - - mAudioBufferWriteIndex += (mAudioBufferSize / 2); - mAudioBufferWriteIndex &= (mAudioBufferSize - 1); - - dstBuffer = &mAudioBuffer[mAudioBufferWriteIndex]; - totalBytes = mBytesPerFrame * numFrames; - memcpy(dstBuffer, buffer, totalBytes); - - dstBuffer += totalBytes; - bzero(dstBuffer, (mBufferSizeFrames * mBytesPerFrame) - totalBytes); - - return numFrames; -} diff --git a/BasiliskII/src/MacOSX/AudioBackEnd.h b/BasiliskII/src/MacOSX/AudioBackEnd.h deleted file mode 100644 index 455d42ff..00000000 --- a/BasiliskII/src/MacOSX/AudioBackEnd.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * This is based on Apple example software AudioBackEnd.cpp - * - * Copyright © 2004 Apple Computer, Inc., All Rights Reserved - * Original Apple code modified by Daniel Sumorok - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __AudioBackEnd_H__ -#define __AudioBackEnd_H__ - -#define checkErr( err) \ -if(err) {\ - OSStatus error = static_cast(err);\ - fprintf(stderr, "AudioBackEnd Error: %ld -> %s: %d\n", error,\ - __FILE__, \ - __LINE__\ - );\ - fflush(stdout);\ -} - -#include -#include -#include -#include -#include "AudioDevice.h" - -typedef void (*playthruCallback)(void *arg); - -class AudioBackEnd { - public: - AudioBackEnd(int bitsPerSample, int numChannels, int sampleRate); - ~AudioBackEnd(); - OSStatus Init(); - OSStatus Start(); - OSStatus Stop(); - Boolean IsRunning(); - void setCallback(playthruCallback func, void *arg); - UInt32 BufferSizeFrames(); - int sendAudioBuffer(void *buffer, int numFrames); - private: - OSStatus SetupGraph(); - OSStatus CallbackSetup(); - OSStatus SetupBuffers(); - - static OSStatus OutputProc(void *inRefCon, - AudioUnitRenderActionFlags *ioActionFlags, - const AudioTimeStamp *inTimeStamp, - UInt32 inBusNumber, - UInt32 inNumberFrames, - AudioBufferList * ioData); - - AudioDevice mOutputDevice; - - AUGraph mGraph; - AUNode mOutputNode; - AudioUnit mOutputUnit; - int mBitsPerSample; - int mSampleRate; - int mNumChannels; - playthruCallback mCallback; - void *mCallbackArg; - UInt32 mBufferSizeFrames; - UInt32 mFramesProcessed; - UInt8 *mAudioBuffer; - UInt32 mAudioBufferWriteIndex; - UInt32 mAudioBufferReadIndex; - UInt32 mBytesPerFrame; - UInt32 mAudioBufferSize; -}; - -#endif //__AudioBackEnd_H__ diff --git a/BasiliskII/src/MacOSX/AudioDevice.cpp b/BasiliskII/src/MacOSX/AudioDevice.cpp deleted file mode 100644 index 9fe065f6..00000000 --- a/BasiliskII/src/MacOSX/AudioDevice.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright: © Copyright 2004 Apple Computer, Inc. All rights reserved. - - Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. - ("Apple") in consideration of your agreement to the following terms, and your - use, installation, modification or redistribution of this Apple software - constitutes acceptance of these terms. If you do not agree with these terms, - please do not use, install, modify or redistribute this Apple software. - - In consideration of your agreement to abide by the following terms, and subject - to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs - copyrights in this original Apple software (the "Apple Software"), to use, - reproduce, modify and redistribute the Apple Software, with or without - modifications, in source and/or binary forms; provided that if you redistribute - the Apple Software in its entirety and without modifications, you must retain - this notice and the following text and disclaimers in all such redistributions of - the Apple Software. Neither the name, trademarks, service marks or logos of - Apple Computer, Inc. may be used to endorse or promote products derived from the - Apple Software without specific prior written permission from Apple. Except as - expressly stated in this notice, no other rights or licenses, express or implied, - are granted by Apple herein, including but not limited to any patent rights that - may be infringed by your derivative works or by other works in which the Apple - Software may be incorporated. - - The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO - WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED - WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN - COMBINATION WITH YOUR PRODUCTS. - - IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION - OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT - (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -/*============================================================================= - AudioDevice.cpp - -=============================================================================*/ - -#include "AudioDevice.h" - -void AudioDevice::Init(AudioDeviceID devid, bool isInput) -{ - mID = devid; - mIsInput = isInput; - if (mID == kAudioDeviceUnknown) return; - - UInt32 propsize; - - propsize = sizeof(UInt32); - verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertySafetyOffset, &propsize, &mSafetyOffset)); - - propsize = sizeof(UInt32); - verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames)); - - propsize = sizeof(AudioStreamBasicDescription); - verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyStreamFormat, &propsize, &mFormat)); - -} - -void AudioDevice::SetBufferSize(UInt32 size) -{ - UInt32 propsize = sizeof(UInt32); - verify_noerr(AudioDeviceSetProperty(mID, NULL, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, propsize, &size)); - - propsize = sizeof(UInt32); - verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames)); -} - -int AudioDevice::CountChannels() -{ - OSStatus err; - UInt32 propSize; - int result = 0; - - err = AudioDeviceGetPropertyInfo(mID, 0, mIsInput, kAudioDevicePropertyStreamConfiguration, &propSize, NULL); - if (err) return 0; - - AudioBufferList *buflist = (AudioBufferList *)malloc(propSize); - err = AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyStreamConfiguration, &propSize, buflist); - if (!err) { - for (UInt32 i = 0; i < buflist->mNumberBuffers; ++i) { - result += buflist->mBuffers[i].mNumberChannels; - } - } - free(buflist); - return result; -} - -char * AudioDevice::GetName(char *buf, UInt32 maxlen) -{ - verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyDeviceName, &maxlen, buf)); - return buf; -} diff --git a/BasiliskII/src/MacOSX/AudioDevice.h b/BasiliskII/src/MacOSX/AudioDevice.h deleted file mode 100644 index d32be287..00000000 --- a/BasiliskII/src/MacOSX/AudioDevice.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright: © Copyright 2004 Apple Computer, Inc. All rights reserved. - - Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. - ("Apple") in consideration of your agreement to the following terms, and your - use, installation, modification or redistribution of this Apple software - constitutes acceptance of these terms. If you do not agree with these terms, - please do not use, install, modify or redistribute this Apple software. - - In consideration of your agreement to abide by the following terms, and subject - to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs - copyrights in this original Apple software (the "Apple Software"), to use, - reproduce, modify and redistribute the Apple Software, with or without - modifications, in source and/or binary forms; provided that if you redistribute - the Apple Software in its entirety and without modifications, you must retain - this notice and the following text and disclaimers in all such redistributions of - the Apple Software. Neither the name, trademarks, service marks or logos of - Apple Computer, Inc. may be used to endorse or promote products derived from the - Apple Software without specific prior written permission from Apple. Except as - expressly stated in this notice, no other rights or licenses, express or implied, - are granted by Apple herein, including but not limited to any patent rights that - may be infringed by your derivative works or by other works in which the Apple - Software may be incorporated. - - The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO - WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED - WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN - COMBINATION WITH YOUR PRODUCTS. - - IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION - OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT - (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -/*============================================================================= - AudioDevice.h - -=============================================================================*/ - -#ifndef __AudioDevice_h__ -#define __AudioDevice_h__ - -#include -#include - -class AudioDevice { -public: - AudioDevice() : mID(kAudioDeviceUnknown) { } - AudioDevice(AudioDeviceID devid, bool isInput) { Init(devid, isInput); } - - void Init(AudioDeviceID devid, bool isInput); - - bool Valid() { return mID != kAudioDeviceUnknown; } - - void SetBufferSize(UInt32 size); - - int CountChannels(); - char * GetName(char *buf, UInt32 maxlen); - -public: - AudioDeviceID mID; - bool mIsInput; - UInt32 mSafetyOffset; - UInt32 mBufferSizeFrames; - AudioStreamBasicDescription mFormat; -}; - - -#endif // __AudioDevice_h__ diff --git a/BasiliskII/src/MacOSX/BasiliskII.icns b/BasiliskII/src/MacOSX/BasiliskII.icns deleted file mode 100644 index b26870dd..00000000 Binary files a/BasiliskII/src/MacOSX/BasiliskII.icns and /dev/null differ diff --git a/BasiliskII/src/MacOSX/Controller.h b/BasiliskII/src/MacOSX/Controller.h deleted file mode 100644 index 867497e2..00000000 --- a/BasiliskII/src/MacOSX/Controller.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Controller.h - Simple application window management. - * - * $Id$ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import -#import "PrefsEditor.h" - -// If the application supports multiple windows, -// ENABLE_MULTIPLE can be defined in config.h - -@interface Controller : NSApplication -{ -#ifdef ENABLE_MULTIPLE - NSMutableArray *emulators; // Array of created Emulators -#endif - IBOutlet Emulator *theEmulator; - IBOutlet PrefsEditor *thePrefsEditor; -} - -- (void) dispatchKeyEvent: (NSEvent *)event - type: (NSEventType)type; -- (void) dispatchEvent: (NSEvent *)event - type: (NSEventType)type; - - -- (IBAction) HelpHowTo: (id)sender; -- (IBAction) HelpToDo: (id)sender; -- (IBAction) HelpVersions: (id)sender; - -#ifdef ENABLE_MULTIPLE -- (IBAction) NewEmulator: (id)sender; -- (IBAction) PauseAll: (id)sender; -- (IBAction) RunAll: (id)sender; -- (IBAction) TerminateAll: (id)sender; -#endif - -- (BOOL) isAnyEmulatorDisplayingSheets; -- (BOOL) isAnyEmulatorRunning; -- (short) emulatorCreatedCount; // If any emulator environments have been setup, count how many - -@end diff --git a/BasiliskII/src/MacOSX/Controller.mm b/BasiliskII/src/MacOSX/Controller.mm deleted file mode 100644 index af4a96e6..00000000 --- a/BasiliskII/src/MacOSX/Controller.mm +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Controller.m - Simple application window management. - * - * $Id$ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import "Controller.h" -#import "Emulator.h" - -#import "sysdeps.h" // Types used in Basilisk C++ code - -#import -#import - -#define DEBUG 0 -#import - -#import "misc_macosx.h" -#import "video_macosx.h" - -@implementation Controller - -// -// Standard NSApplication methods that we override -// - -- (id) init -{ -#ifdef ENABLE_MULTIPLE - emulators = [NSMutableArray new]; -#endif - return [super init]; -} - -- (void) dealloc -{ -#ifdef ENABLE_MULTIPLE - [emulators dealloc]; -#endif - [super dealloc]; -} - -- (void) awakeFromNib -{ -#ifdef ENABLE_MULTIPLE - [self NewEmulator: self]; // So the user gets something on screen -#endif - [[NSApplication sharedApplication] - setDelegate: self]; // Enable applicationShouldTerminate -} - -- (void) sendEvent: (NSEvent *)event; -{ - // We can either process the event ourselves, - // or pass it to our superclass for the other UI objects to process - bool passToSuper = false; - - if ( [self isAnyEmulatorDisplayingSheets] || - [[thePrefsEditor window] isVisible] || ! [self isAnyEmulatorRunning] ) - passToSuper = true; - - if ( [[theEmulator screen] isFullScreen] ) - passToSuper = false; - - if ( passToSuper ) - [super sendEvent: event]; // NSApplication default - else - { - NSEventType type = [event type]; - - if ( type == NSKeyUp || type == NSKeyDown || type == NSFlagsChanged ) - [self dispatchKeyEvent: event - type: type]; - else - [self dispatchEvent: event - type: type]; - } -} - -// NSApplication methods which are invoked through delegation - -- (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication *)app -{ return YES; } - -- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *)app -{ - short count; - const char *stillRunningMessage; - - if ( [thePrefsEditor hasEdited] ) - if ( ChoiceAlert("Preferences have been edited", - "Save changes", "Quit") ) - SavePrefs(); - -// if ( edited ) -// { -// NSString *title = [NSString stringWithCString: getString(STR_WARNING_ALERT_TITLE)], -// *msg = @"Preferences have been edited", -// *def = @"Save changes", -// *alt = @"Quit Application", -// *other = @"Continue"; -// -// switch ( NSRunAlertPanel(title, msg, def, alt, other, nil) ) -// { -// case NSAlertDefault: savePrefs(); -// case NSAlertAlternate: return NSTerminateNow; -// case NSAlertOther: return NSTerminateCancel; -// } -// } - - - if ( [[thePrefsEditor window] isVisible] ) - [[thePrefsEditor window] performClose: self]; - - - count = [self emulatorCreatedCount]; - - if ( count > 0 ) - { - if ( count > 1 ) - stillRunningMessage = "Emulators are still running\nExiting Basilisk may lose data"; - else - stillRunningMessage = "Emulator is still running\nExiting Basilisk may lose data"; - if ( ! ChoiceAlert(stillRunningMessage, "Exit", "Continue") ) - return NSTerminateCancel; // NSTerminateLater? - } - - return NSTerminateNow; -} - - -// Event dispatching, called by sendEvent - -- (void) dispatchKeyEvent: (NSEvent *)event - type: (NSEventType)type -{ - EmulatorView *view; - -#ifdef ENABLE_MULTIPLE - // We need to work out what window's Emulator should receive these messages - - - int tmp; - - for ( tmp = 0; tmp < [emulators count], ++tmp ) - { - theEmulator = [emulators objectAtIndex: tmp]; - view = [theEmulator screen]; - - if ( [ theEmulator isRunning ] && - ( [[theEmulator window] isKeyWindow] || [view isFullScreen] ) ) - break; - } - - if ( tmp < [emulators count] ) // i.e. if we exited the for loop -#else - view = [theEmulator screen]; - - if ( [theEmulator isRunning] && - ( [[theEmulator window] isKeyWindow] || [view isFullScreen] ) ) -#endif - { - D(NSLog(@"Got a key event - %d\n", [event keyCode])); - switch ( type ) - { - case NSKeyUp: - [view keyUp: event]; - break; - case NSKeyDown: - D(NSLog(@"%s - NSKeyDown - %@", __PRETTY_FUNCTION__, event)); - [view keyDown: event]; - break; - case NSFlagsChanged: - [view flagsChanged: event]; - break; - default: - NSLog(@"%s - Sent a non-key event (logic error)", - __PRETTY_FUNCTION__); - [super sendEvent: event]; - } - } - else // No Basilisk window is key (maybe a panel or pane). - [super sendEvent: event]; // Call NSApplication default - -} - -- (void) dispatchEvent: (NSEvent *)event - type: (NSEventType)type -{ - EmulatorView *view; - BOOL fullScreen; - -#ifdef ENABLE_MULTIPLE - // We need to work out what window's Emulator should receive these messages - - - int tmp; - - for ( tmp = 0; tmp < [emulators count], ++tmp ) - { - theEmulator = [emulators objectAtIndex: tmp]; - view = [theEmulator screen]; - fullScreen = [view isFullScreen]; - - if ( [theEmulator isRunning] && - ( fullScreen || [[theEmulator window] isMainWindow] ) ) - break; - } - - if ( tmp < [emulators count] ) // i.e. if we exited the for loop -#else - view = [theEmulator screen]; - fullScreen = [view isFullScreen]; - - if ( [theEmulator isRunning] && - ( fullScreen || [[theEmulator window] isMainWindow] ) ) -#endif - { - if ( fullScreen || [view mouseInView: event] ) - { - switch ( type ) - { - case NSLeftMouseDown: - [view mouseDown: event]; - break; - case NSLeftMouseUp: - [view mouseUp: event]; - break; - case NSLeftMouseDragged: - case NSMouseMoved: - if ( fullScreen ) - [view fullscreenMouseMove]; - else - [view processMouseMove: event]; - break; - default: - [super sendEvent: event]; // NSApplication default - } - return; - } - } - - // Either the pointer is not in the Emulator's screen, no Basilisk window is running, - // or no Basilisk window is main (e.g. there might be a panel or pane up). - // - // We should just be calling NSApp's default sendEvent, but then for some reason - // mouseMoved events are still passed to our EmulatorView, so we filter them out. - - if ( type != NSMouseMoved ) - [super sendEvent: event]; -} - - -// Methods to display documentation: - -- (IBAction) HelpHowTo: (id)sender -{ - NSString *path = [[NSBundle mainBundle] pathForResource: @"HowTo" - ofType: @"html"]; - - if ( ! path ) - InfoSheet(@"Cannot find HowTo.html", [theEmulator window]); - else - if ( ! [[NSWorkspace sharedWorkspace] openFile: path] ) - InfoSheet(@"Cannot open HowTo.html with default app", [theEmulator window]); -} - -- (IBAction) HelpToDo: (id)sender -{ - NSString *path = [[NSBundle mainBundle] pathForResource: @"ToDo" - ofType: @"html"]; - - if ( ! path ) - InfoSheet(@"Cannot find ToDo.html", [theEmulator window]); - else - if ( ! [[NSWorkspace sharedWorkspace] openFile: path - withApplication: @"TextEdit"] ) - InfoSheet(@"Cannot open ToDo.html with TextEdit", [theEmulator window]); -} - -- (IBAction) HelpVersions: (id)sender -{ - NSString *path = [[NSBundle mainBundle] pathForResource: @"Versions" - ofType: @"html"]; - - if ( ! path ) - InfoSheet(@"Cannot find Versions.html", [theEmulator window]); - else - if ( ! [[NSWorkspace sharedWorkspace] openFile: path - withApplication: @"TextEdit"] ) - InfoSheet(@"Cannot open Versions.html with TextEdit", - [theEmulator window]); -} - - -// Menu items which for managing more than one window - -#ifdef ENABLE_MULTIPLE - -- (IBAction) NewEmulator: (id)sender -{ - NSString *title; - - if ( ! [NSBundle loadNibNamed:@"Win512x342" owner:self] ) - { - NSLog(@"%s - LoadNibNamed@Win512x342 failed", __PRETTY_FUNCTION__); - return; - } - - if ( theEmulator == nil) - { - NSLog(@"%s - Newly created emulator's NIB stuff not fully linked?", __PRETTY_FUNCTION__); - return; - } - - [emulators addObject: theEmulator]; - title = [NSString localizedStringWithFormat:@"BasiliskII Emulator %d", [emulators count]]; - [theEmulator -> win setTitle: title]; -} - -- (IBAction) PauseAll: (id)sender -{ - [emulators makeObjectsPerformSelector:@selector(Suspend:) - withObject:self]; -} - -- (IBAction) RunAll: (id)sender -{ - [emulators makeObjectsPerformSelector:@selector(Resume:) - withObject:self]; -} - -- (IBAction) TerminateAll: (id)sender -{ - [emulators makeObjectsPerformSelector:@selector(Terminate:) - withObject:self]; -} - -#endif - -- (BOOL) isAnyEmulatorDisplayingSheets -{ -#ifdef ENABLE_MULTIPLE - int tmp; - - for ( tmp = 0; tmp < [emulators count], ++tmp ) - if ( [[[emulators objectAtIndex: tmp] window] attachedSheet] ) - break; - - if ( tmp < [emulators count] ) // i.e. if we exited the for loop -#else - if ( [[theEmulator window] attachedSheet] ) -#endif - return TRUE; - - return FALSE; -} - -- (BOOL) isAnyEmulatorRunning -{ -#ifdef ENABLE_MULTIPLE - int tmp; - - for ( tmp = 0; tmp < [emulators count], ++tmp ) - if ( [[emulators objectAtIndex: tmp] isRunning] ) - break; - - if ( tmp < [emulators count] ) // i.e. if we exited the for loop -#else - if ( [theEmulator isRunning] ) -#endif - return TRUE; - - return FALSE; -} - -- (short) emulatorCreatedCount -{ - short count = 0; -#ifdef ENABLE_MULTIPLE - int tmp; - - for ( tmp = 0; tmp < [emulators count], ++tmp ) - if ( [[emulators objectAtIndex: tmp] uaeCreated] ) - ++count; -#else - if ( [theEmulator uaeCreated] ) - ++count; -#endif - - return count; -} - -@end diff --git a/BasiliskII/src/MacOSX/Credits.html b/BasiliskII/src/MacOSX/Credits.html deleted file mode 100644 index 29ee57a9..00000000 --- a/BasiliskII/src/MacOSX/Credits.html +++ /dev/null @@ -1,11 +0,0 @@ -Basilisk II is an open source, 68k Mac. emulator. -
-It enables you to run 68k MacOS software on your computer, even if you are using a different operating system (however, you do need a copy of the MacOS and a Macintosh ROM image to use it). -
-The Official Basilisk II Home Page -
- -MacOS X (native windowing) port -
-by Nigel Pearson <nigel@ind.tansu.com.au> -
diff --git a/BasiliskII/src/MacOSX/Emulator.h b/BasiliskII/src/MacOSX/Emulator.h deleted file mode 100644 index 761ce55e..00000000 --- a/BasiliskII/src/MacOSX/Emulator.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Emulator.h - Class whose actions are attached GUI widgets in a window, - * used to control a single Basilisk II emulated Macintosh. - * - * $Id$ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import -#import -#import "EmulatorView.h" -#import "NNThread.h" - -@interface Emulator : NSObject -{ - NNThread *emul; // Run emulThread - NNTimer *RTC, // Invoke RTCinterrupt - *redraw, // Invoke redrawScreen - *tick, // Invoke tickInterrupt - *xPRAM; // Invoke xPRAMbackup - - BOOL uaeCreated, // Has thread created the emulator environment? - running; // Is the emulator currently grinding away? - float redrawDelay; // Seconds until next screen update - - // UI elements that this class changes the state of - - IBOutlet NSProgressIndicator *barberPole; - IBOutlet NSButton *runOrPause; - IBOutlet EmulatorView *screen; - IBOutlet NSSlider *speed; - IBOutlet NSWindow *win; -} - -// The following allow the Controller and PrefsEditor classes to access our internal data - -- (BOOL) isRunning; -- (BOOL) uaeCreated; -- (EmulatorView *) screen; -- (NSSlider *) speed; -- (NSWindow *) window; - -- (void) runUpdate; // Update some UI elements - -- (IBAction) Benchmark: (id)sender; -- (IBAction) Interrupt: (id)sender; -- (IBAction) PowerKey: (id)sender; -- (IBAction) Restart: (id)sender; -- (IBAction) Resume: (id)sender; -- (IBAction) ScreenHideShow:(NSButton *)sender; -- (IBAction) Snapshot: (id)sender; -- (IBAction) SpeedChange: (NSSlider *)sender; -- (IBAction) Suspend: (id)sender; -- (IBAction) Terminate: (id)sender; -- (IBAction) ToggleState: (NSButton *)sender; -- (IBAction) ZapPRAM: (id)sender; - -- (void) createThreads; -- (void) exitThreads; - -- (void) emulThread; // Thread for processor emulator -- (void) RTCinterrupt; // Emulator real time clock update -- (void) redrawScreen; // Draw emulator screen in window -- (void) tickInterrupt; // Draw emulator screen in window -- (void) xPRAMbackup; // PRAM watchdog - -@end diff --git a/BasiliskII/src/MacOSX/Emulator.mm b/BasiliskII/src/MacOSX/Emulator.mm deleted file mode 100644 index 61d191ff..00000000 --- a/BasiliskII/src/MacOSX/Emulator.mm +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Emulator.mm - Class whose actions are attached to GUI widgets in a window, - * used to control a single Basilisk II emulated Macintosh. - * - * $Id$ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import "Emulator.h" -#import "EmulatorView.h" - -#import "sysdeps.h" // Types used in Basilisk C++ code - -#import "main_macosx.h" // Prototypes for QuitEmuNoExit() and InitEmulator() -#import "misc_macosx.h" // Some other prototypes -#import "video_macosx.h" // Some window/view globals - -#import "adb.h" -#import "main.h" -#import "prefs.h" -#import "timer.h" - -#undef check // memory.h defines a check macro, - // which may clash with an OS X one on 10.1 or 10.2 -#import "cpu_emulation.h" - -#define DEBUG 0 -#import "debug.h" - -@implementation Emulator - -// NSWindow method, which is invoked via delegation - -- (BOOL) windowShouldClose: (id)sender -{ - if ( uaeCreated ) - { - NSLog(@"windowShouldClose returning NO"); - return NO; // Should initiate poweroff and return NSTerminateLater ? - } - - NSLog(@"windowShouldClose returning YES"); - return YES; -} - -// Default methods - -- (Emulator *) init -{ - int frameSkip; - - self = [super init]; - - running = NO; // Save churn when application loads -// running = YES; - uaeCreated = NO; - - frameSkip = PrefsFindInt32("frameskip"); - if ( frameSkip ) - redrawDelay = frameSkip / 60.0; - else - redrawDelay = 0.0; - - // We do this so that we can work out if we are in full screen mode: - parse_screen_prefs(PrefsFindString("screen")); - - [self createThreads]; - - return self; -} - -- (void) awakeFromNib -{ - the_win = win; // Set global for access by Basilisk C++ code - - - [win setDelegate: self]; // Enable windowShouldClose calling - - // Try to speed up everything - //[win setHasShadow: NO]; // This causes view & window to now be drawn correctly - [win useOptimizedDrawing: YES]; - - [win makeKeyAndOrderFront:self]; - - if ( redrawDelay ) - [speed setFloatValue: 1.0 / redrawDelay]; - else - [speed setFloatValue: 60.0]; - - - if ( runOrPause == nil ) - NSLog(@"%s - runOrPause button pointer is nil!", __PRETTY_FUNCTION__); - - [self runUpdate]; -} - - -// Helpers which other classes use to access our private stuff - -- (BOOL) isRunning { return running; } -- (BOOL) uaeCreated { return uaeCreated; } -- (EmulatorView *) screen { return screen; } -- (NSSlider *) speed { return speed; } -- (NSWindow *) window { return win; } - - -// Update some UI elements - -- (void) runUpdate -{ - if ( running ) - [runOrPause setState: NSOnState]; // Running. Change button label to 'Pause' - else - [runOrPause setState: NSOffState]; // Paused. Change button label to 'Run' - - [win setDocumentEdited: uaeCreated]; // Set the little dimple in the close button -} - - -// Methods invoked by buttons & menu items - -- (IBAction) Benchmark: (id)sender; -{ - BOOL wasRunning = running; - - if ( running ) - [self Suspend: self]; - [screen benchmark]; - if ( wasRunning ) - [self Resume: self]; -} - -#ifdef NIGEL -- (IBAction) EjectCD: (id)sender; -{ - NSString *path; - const char *cdrom = PrefsFindString("cdrom"); - - if ( cdrom ) - { - #include - #define KERNEL - #include - - struct statfs buf; - if ( fsstat(path, &buf) < 0 ) - return; - - path = [NSString stringWithCString: cdrom]; - - [[NSWorkspace sharedWorkspace] unmountAndEjectDeviceAtPath: path]; -// [path release]; - } -} -#endif - -- (IBAction) Interrupt: (id)sender; -{ - WarningSheet (@"Interrupt action not yet supported", win); -} - -- (IBAction) PowerKey: (id)sender; -{ - if ( uaeCreated ) // If Mac has started - { - ADBKeyDown(0x7f); // Send power key, which is also - ADBKeyUp(0x7f); // called ADB_RESET or ADB_POWER - } - else - { - running = YES; // Start emulator - [self runUpdate]; - [self Resume: nil]; - } -} - -- (IBAction) Restart: (id)sender -{ - if ( ! running ) - { - running = YES; // Start emulator - [self runUpdate]; - [self Resume: nil]; - } - - if ( running ) -#ifdef UAE_CPU_HAS_RESET - reset680x0(); -#else - { - uaeCreated = NO; - [redraw suspend]; - NSLog (@"%s - uae_cpu reset not yet supported, will try to fake it", - __PRETTY_FUNCTION__); - - [screen clear]; - [screen display]; - - [emul terminate]; QuitEmuNoExit(); - - - // OK. We have killed & cleaned up. Now, start afresh: - #include - int argc = 0; - char **argv; - - PrefsInit(NULL, argc, argv); - SysInit(); - - emul = [NNThread new]; - [emul perform:@selector(emulThread) of:self]; - [emul start]; - - if ( display_type != DISPLAY_SCREEN ) - [redraw resume]; - } -#endif -} - -- (IBAction) Resume: (id)sender -{ - [RTC resume]; - [emul resume]; - if ( display_type != DISPLAY_SCREEN ) - [redraw resume]; - [tick resume]; - [xPRAM resume]; -} - -- (IBAction) ScreenHideShow: (NSButton *)sender; -{ - WarningSheet(@"Nigel doesn't know how to shrink or grow this window", - @"Maybe you can grab the source code and have a go yourself?", - nil, win); -} - -- (IBAction) Snapshot: (id) sender -{ - if ( screen == nil || uaeCreated == NO ) - WarningSheet(@"The emulator has not yet started.", - @"There is no screen output to snapshot", - nil, win); - else - { - NSData *TIFFdata; - - [self Suspend: self]; - - TIFFdata = [screen TIFFrep]; - if ( TIFFdata == nil ) - NSLog(@"%s - Unable to convert Basilisk screen to a TIFF representation", - __PRETTY_FUNCTION__); - else - { - NSSavePanel *sp = [NSSavePanel savePanel]; - - [sp setRequiredFileType:@"tiff"]; - - if ( [sp runModalForDirectory:NSHomeDirectory() - file:@"B2-screen-snapshot.tiff"] == NSOKButton ) - if ( ! [TIFFdata writeToFile:[sp filename] atomically:YES] ) - NSLog(@"%s - Could not write TIFF data to file @%", - __PRETTY_FUNCTION__, [sp filename]); - - } - if ( running ) - [self Resume: self]; - } -} - -- (IBAction) SpeedChange: (NSSlider *)sender -{ - float frequency = [sender floatValue]; - - [redraw suspend]; - - if ( frequency == 0.0 ) - redrawDelay = 0.0; - else - { - frequencyToTickDelay(frequency); - - redrawDelay = 1.0 / frequency; - - [redraw changeIntervalTo: (int)(redrawDelay * 1e6) - units: NNmicroSeconds]; - if ( running && display_type != DISPLAY_SCREEN ) - [redraw resume]; - } -} - -- (IBAction) Suspend: (id)sender -{ - [RTC suspend]; - [emul suspend]; - [redraw suspend]; - [tick suspend]; - [xPRAM suspend]; -} - -- (IBAction) ToggleState: (NSButton *)sender -{ - running = [sender state]; // State of the toggled NSButton - if ( running ) - [self Resume: nil]; - else - [self Suspend: nil]; -} - -- (IBAction) Terminate: (id)sender; -{ - [self exitThreads]; - [win performClose: self]; -} - -#include - -#define XPRAM_SIZE 256 - -uint8 lastXPRAM[XPRAM_SIZE]; // Copy of PRAM - -- (IBAction) ZapPRAM: (id)sender; -{ - memset(XPRAM, 0, XPRAM_SIZE); - memset(lastXPRAM, 0, XPRAM_SIZE); - ZapPRAM(); -} - -// -// Threads, Timers and stuff to manage them: -// - -- (void) createThreads -{ -#ifdef USE_PTHREADS - // Make UI threadsafe: - [NSThread detachNewThreadSelector:(SEL)"" toTarget:nil withObject:nil]; - //emul = [[NNThread alloc] initWithAutoReleasePool]; -#endif - emul = [NNThread new]; - RTC = [NNTimer new]; - redraw = [[NNTimer alloc] initWithAutoRelPool]; - tick = [NNTimer new]; - xPRAM = [NNTimer new]; - - [emul perform:@selector(emulThread) of:self]; - [RTC repeat:@selector(RTCinterrupt) of:self - every:1 - units:NNseconds]; - [redraw repeat:@selector(redrawScreen) of:self - every:(int)(1000*redrawDelay) - units:NNmilliSeconds]; - [tick repeat:@selector(tickInterrupt) of:self - every:16625 - units:NNmicroSeconds]; - [xPRAM repeat:@selector(xPRAMbackup) of:self - every:60 - units:NNseconds]; - - if ( running ) // Start emulator, then threads in most economical order - { - [emul start]; - [xPRAM start]; - [RTC start]; - if ( display_type != DISPLAY_SCREEN ) - [redraw start]; - [tick start]; - } -} - -- (void) exitThreads -{ - running = NO; - [emul terminate]; [emul release]; emul = nil; - [tick invalidate]; [tick release]; tick = nil; - [redraw invalidate]; [redraw release]; redraw = nil; - [RTC invalidate]; [RTC release]; RTC = nil; - [xPRAM invalidate]; [xPRAM release]; xPRAM = nil; -} - -- (void) emulThread -{ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - - if ( ! InitEmulator() ) - { - [redraw suspend]; // Stop the barberpole - - ErrorSheet(@"Cannot start Emulator", @"", @"Quit", win); - } - else - { - memcpy(lastXPRAM, XPRAM, XPRAM_SIZE); - - uaeCreated = YES; // Enable timers to access emulated Mac's memory - - while ( screen == nil ) // If we are still loading from Nib? - [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow: 1.0]]; - - [self runUpdate]; // Set the window close gadget to dimpled - - Start680x0(); // Start 68k and jump to ROM boot routine - - puts ("Emulator exited normally"); - } - - [pool release]; - QuitEmulator(); -} - -- (void) RTCinterrupt -{ - if ( ! uaeCreated ) - return; - - WriteMacInt32 (0x20c, TimerDateTime() ); // Update MacOS time - - SetInterruptFlag(INTFLAG_1HZ); - TriggerInterrupt(); -} - -- (void) redrawScreen -{ - if ( display_type == DISPLAY_SCREEN ) - { - NSLog(@"We are in fullscreen mode - why was redrawScreen() called?"); - return; - } - [barberPole animate:self]; // wobble the pole - [screen setNeedsDisplay: YES]; // redisplay next time through runLoop - // Or, use a direct method. e.g. - // [screen display] or [screen cgDrawInto: ...]; -} - -#include // For #define INTFLAG_60HZ -#include // For ROMVersion -#include "macos_util_macosx.h" // For HasMacStarted() - -- (void) tickInterrupt -{ - if ( ROMVersion != ROM_VERSION_CLASSIC || HasMacStarted() ) - { - SetInterruptFlag (INTFLAG_60HZ); - TriggerInterrupt (); - } -} - -- (void) xPRAMbackup -{ - if ( uaeCreated && - memcmp(lastXPRAM, XPRAM, XPRAM_SIZE) ) // if PRAM changed from copy - { - memcpy (lastXPRAM, XPRAM, XPRAM_SIZE); // re-copy - SaveXPRAM (); // and save to disk - } -} - -@end diff --git a/BasiliskII/src/MacOSX/EmulatorView.h b/BasiliskII/src/MacOSX/EmulatorView.h deleted file mode 100644 index 9fc152b5..00000000 --- a/BasiliskII/src/MacOSX/EmulatorView.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * EmulatorView.h - Custom NSView for Basilisk II window input & output - * - * $Id$ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef NSBITMAP -#import -#endif - -#import - - -@interface EmulatorView : NSView -{ -#ifdef CGIMAGEREF - CGImageRef cgImgRep; -#endif -#ifdef NSBITMAP - NSBitmapImageRep *bitmap; -#else - void *bitmap; -#endif -#ifdef CGDRAWBITMAP - short bps, spp, bpp; - int bytesPerRow; - BOOL isPlanar, hasAlpha; -#endif - float numBytes; - - short x, y; - - BOOL drawView, // Set when the bitmap is all set up - // and ready to display - fullScreen; // Is this Emulator using the whole screen? - - NSRect displayBox; // Cached dimensions of the screen - - int screen_height; // Height of the screen with the key window -} - -- (void) benchmark; -- (NSData *) TIFFrep; // Used for snapshot function - -// Enable display of, and drawing into, the view -#ifdef NSBITMAP -- (void) readyToDraw: (NSBitmapImageRep *) theBitmap - imageWidth: (short) width - imageHeight: (short) height; -#endif -#ifdef CGIMAGEREF -- (void) readyToDraw: (CGImageRef) image - bitmap: (void *) theBitmap - imageWidth: (short) width - imageHeight: (short) height; -#endif -#ifdef CGDRAWBITMAP -- (void) readyToDraw: (void *) theBitmap - width: (short) width - height: (short) height - bps: (short) bitsPerSample - spp: (short) samplesPerPixel - bpp: (short) bitsPerPixel - bpr: (int) bpr - isPlanar: (BOOL) planar - hasAlpha: (BOOL) alpha; -#endif - -- (void) disableDrawing; -- (void) startedFullScreen: (CGDirectDisplayID) theDisplay; - -- (void) blacken; -- (void) clear; - -- (short) width; -- (short) height; - -- (BOOL) isFullScreen; -- (BOOL) mouseInView: (NSEvent *) event; -- (BOOL) mouseInView; -- (void) fullscreenMouseMove; -- (BOOL) processMouseMove: (NSEvent *) event; - -#ifdef CGDRAWBITMAP -- (void) CGDrawBitmap; -#endif - -#ifdef CGIMAGEREF -void cgDrawInto(NSRect rect, CGImageRef bitmap); -#endif - -@end diff --git a/BasiliskII/src/MacOSX/EmulatorView.mm b/BasiliskII/src/MacOSX/EmulatorView.mm deleted file mode 100644 index cf300481..00000000 --- a/BasiliskII/src/MacOSX/EmulatorView.mm +++ /dev/null @@ -1,550 +0,0 @@ -/* - * EmulatorView.mm - Custom NSView for Basilisk II windowed graphics output - * - * $Id$ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import "sysdeps.h" // Types used in Basilisk C++ code, - -#define DEBUG 0 -#import - -#import - -#import "main_macosx.h" // For WarningAlert() et al prototypes -#import "misc_macosx.h" // For InfoSheet() prototype -#import "video_macosx.h" // For init_* globals, and bitmap drawing strategy - -#import "EmulatorView.h" - -@implementation EmulatorView - - -// -// Standard NSView methods that we override -// - -- (id) initWithFrame: (NSRect) frameRect -{ - self = [super initWithFrame: frameRect]; - - output = self; // Set global for access by Basilisk C++ code -// bitmap = nil; // Set by readyToDraw: - drawView = NO; // Disable drawing until later - fullScreen = NO; - - return self; -} - -- (void) awakeFromNib -{ - // Here we store the height of the screen which the app was opened on. - // NSApplication's sendEvent: always uses that screen for its mouse co-ords - screen_height = (int) [[NSScreen mainScreen] frame].size.height; -} - - -// Mouse click in this window. If window is not active, -// should the click be passed to this view? -- (BOOL) acceptsFirstMouse: (NSEvent *) event -{ - return [self mouseInView]; -} - - -// -// Key event processing. -// OS X doesn't send us separate events for the modifier keys -// (shift/control/command), so we need to monitor them separately -// - -#include - -static int prevFlags; - -- (void) flagsChanged: (NSEvent *) event -{ - int flags = [event modifierFlags]; - - if ( (flags & NSAlphaShiftKeyMask) != (prevFlags & NSAlphaShiftKeyMask) ) - if ( flags & NSAlphaShiftKeyMask ) - ADBKeyDown(0x39); // CAPS_LOCK - else - ADBKeyUp(0x39); - - if ( (flags & NSShiftKeyMask) != (prevFlags & NSShiftKeyMask) ) - if ( flags & NSShiftKeyMask ) - ADBKeyDown(0x38); // SHIFT_LEFT - else - ADBKeyUp(0x38); - - if ( (flags & NSControlKeyMask) != (prevFlags & NSControlKeyMask) ) - if ( flags & NSControlKeyMask ) - ADBKeyDown(0x36); // CTL_LEFT - else - ADBKeyUp(0x36); - - if ( (flags & NSAlternateKeyMask) != (prevFlags & NSAlternateKeyMask) ) - if ( flags & NSAlternateKeyMask ) - ADBKeyDown(0x3a); // OPTION_LEFT - else - ADBKeyUp(0x3a); - - if ( (flags & NSCommandKeyMask) != (prevFlags & NSCommandKeyMask) ) - if ( flags & NSCommandKeyMask ) - ADBKeyDown(0x37); // APPLE_LEFT - else - ADBKeyUp(0x37); - - prevFlags = flags; -} - -// -// Windowed mode. We only send mouse/key events -// if the OS X mouse is within the little screen -// -- (BOOL) mouseInView: (NSEvent *) event -{ - NSRect box; - NSPoint loc; - - if ( fullScreen ) - { - box = displayBox; - loc = [NSEvent mouseLocation]; - } - else - { - box = [self frame]; - loc = [event locationInWindow]; - } - - D(NSLog (@"%s - loc.x=%f, loc.y=%f, box.origin.x=%f, box.origin.y=%f, box.size.width=%f, box.size.height=%f", __PRETTY_FUNCTION__, loc.x, loc.y, box.origin.x, box.origin.y, box.size.width, box.size.height)); - return [self mouse: loc inRect: box]; -} - -- (BOOL) mouseInView -{ - NSPoint loc = [[self window] mouseLocationOutsideOfEventStream]; - NSRect box = [self frame]; - D(NSLog (@"%s - loc.x=%f, loc.y=%f, box.origin.x=%f, box.origin.y=%f", - __PRETTY_FUNCTION__, loc.x, loc.y, box.origin.x, box.origin.y)); - return [self mouse: loc inRect: box]; -} - -// -// Custom methods -// - -- (void) benchmark -{ - int i; - float seconds; - NSDate *startDate; - const char *method; - - if ( ! drawView ) - { - WarningSheet (@"The emulator has not been setup yet.", - @"Try to run, then pause the emulator, first.", nil, [self window]); - return; - } - - drawView = NO; - [self lockFocus]; - startDate = [NSDate date]; - for (i = 1; i < 300; ++i ) -#ifdef NSBITMAP - [bitmap draw]; -#endif -#ifdef CGIMAGEREF - cgDrawInto([self bounds], cgImgRep); -#endif -#ifdef CGDRAWBITMAP - [self CGDrawBitmap]; -#endif - seconds = -[startDate timeIntervalSinceNow]; - [self unlockFocus]; - drawView = YES; - -#ifdef NSBITMAP - method = "NSBITMAP"; -#endif -#ifdef CGIMAGEREF - method = "CGIMAGEREF"; -#endif -#ifdef CGDRAWBITMAP - method = "CGDRAWBITMAP"; -#endif - - InfoSheet(@"Ran benchmark (300 screen redraws)", - [NSString stringWithFormat: - @"%.2f seconds, %.3f frames per second (using %s implementation)", - seconds, i/seconds, method], - @"Thanks", [self window]); -} - -// Return a TIFF for a snapshot of the screen image -- (NSData *) TIFFrep -{ -#ifdef NSBITMAP - return [bitmap TIFFRepresentation]; -#else - NSBitmapImageRep *b = [NSBitmapImageRep alloc]; - - b = [b initWithBitmapDataPlanes: (unsigned char **) &bitmap - pixelsWide: x - pixelsHigh: y - #ifdef CGIMAGEREF - bitsPerSample: CGImageGetBitsPerComponent(cgImgRep) - samplesPerPixel: 3 - hasAlpha: NO - isPlanar: NO - colorSpaceName: NSCalibratedRGBColorSpace - bytesPerRow: CGImageGetBytesPerRow(cgImgRep) - bitsPerPixel: CGImageGetBitsPerPixel(cgImgRep)]; - #endif - #ifdef CGDRAWBITMAP - bitsPerSample: bps - samplesPerPixel: spp - hasAlpha: hasAlpha - isPlanar: isPlanar - colorSpaceName: NSCalibratedRGBColorSpace - bytesPerRow: bytesPerRow - bitsPerPixel: bpp]; - #endif - - if ( ! b ) - { - ErrorAlert("Could not allocate an NSBitmapImageRep for the TIFF\nTry setting the emulation to millions of colours?"); - return nil; - } - - return [b TIFFRepresentation]; -#endif -} - -// Enable display of, and drawing into, the view -#ifdef NSBITMAP -- (void) readyToDraw: (NSBitmapImageRep *) theBitmap - imageWidth: (short) width - imageHeight: (short) height -{ - numBytes = [theBitmap bytesPerRow] * height; -#endif -#ifdef CGIMAGEREF -- (void) readyToDraw: (CGImageRef) image - bitmap: (void *) theBitmap - imageWidth: (short) width - imageHeight: (short) height -{ - cgImgRep = image; - numBytes = CGImageGetBytesPerRow(image) * height; -#endif -#ifdef CGDRAWBITMAP -- (void) readyToDraw: (void *) theBitmap - width: (short) width - height: (short) height - bps: (short) bitsPerSample - spp: (short) samplesPerPixel - bpp: (short) bitsPerPixel - bpr: (int) bpr - isPlanar: (BOOL) planar - hasAlpha: (BOOL) alpha -{ - bps = bitsPerSample; - spp = samplesPerPixel; - bpp = bitsPerPixel; - bytesPerRow = bpr; - isPlanar = planar; - hasAlpha = alpha; - numBytes = bpr * height; -#endif - D(NSLog(@"readyToDraw: theBitmap=%lx\n", theBitmap)); - - bitmap = theBitmap; - x = width, y = height; - drawView = YES; - [[self window] setAcceptsMouseMovedEvents: YES]; -// [[self window] setInitialFirstResponder: self]; - [[self window] makeFirstResponder: self]; -} - -- (void) disableDrawing -{ - drawView = NO; -} - -- (void) startedFullScreen: (CGDirectDisplayID) display -{ - CGRect displayBounds = CGDisplayBounds(display); - - fullScreen = YES; - memcpy(&displayBox, &displayBounds, sizeof(displayBox)); -} - -- (short) width -{ - return (short)[self bounds].size.width; -} - -- (short) height -{ - return (short)[self bounds].size.height; -} - -- (BOOL) isFullScreen -{ - return fullScreen; -} - -- (BOOL) isOpaque -{ - return drawView; -} - -- (BOOL) processKeyEvent: (NSEvent *) event -{ - if ( fullScreen || [self acceptsFirstMouse: event] ) - if ( [event isARepeat] ) - return NO; - else - return YES; - - [self interpretKeyEvents:[NSArray arrayWithObject:event]]; - return NO; -} - -- (void) keyDown: (NSEvent *) event -{ - if ( [self processKeyEvent: event] ) - { - int code = [event keyCode]; - - if ( code == 126 ) code = 0x3e; // CURS_UP - if ( code == 125 ) code = 0x3d; // CURS_DOWN - if ( code == 124 ) code = 0x3c; // CURS_RIGHT - if ( code == 123 ) code = 0x3b; // CURS_LEFT - - ADBKeyDown(code); - } -} - -- (void) keyUp: (NSEvent *) event -{ - if ( [self processKeyEvent: event] ) - { - int code = [event keyCode]; - - if ( code == 126 ) code = 0x3e; // CURS_UP - if ( code == 125 ) code = 0x3d; // CURS_DOWN - if ( code == 124 ) code = 0x3c; // CURS_RIGHT - if ( code == 123 ) code = 0x3b; // CURS_LEFT - - ADBKeyUp(code); - } -} - - -- (void) fullscreenMouseMove -{ - NSPoint location = [NSEvent mouseLocation]; - - D(NSLog (@"%s - loc.x=%f, loc.y=%f", - __PRETTY_FUNCTION__, location.x, location.y)); - D(NSLog (@"%s - Sending ADBMouseMoved(%d,%d). (%d-%d)", - __PRETTY_FUNCTION__, (int)location.x, - screen_height - (int)location.y, screen_height, (int)location.y)); - ADBMouseMoved((int)location.x, screen_height - (int)location.y); -} - -static NSPoint mouse; // Previous/current mouse location - -- (BOOL) processMouseMove: (NSEvent *) event -{ - if ( ! drawView ) - { - D(NSLog(@"Unable to process event - Emulator has not started yet")); - return NO; - } - - if ( fullScreen ) - { - [self fullscreenMouseMove]; - return YES; - } - - NSPoint location = [self convertPoint: [event locationInWindow] fromView:nil]; - - D(NSLog (@"%s - loc.x=%f, loc.y=%f", - __PRETTY_FUNCTION__, location.x, location.y)); - - if ( NSEqualPoints(location, mouse) ) - return NO; - - mouse = location; - - int mouseY = y - (int) (y * mouse.y / [self height]); - int mouseX = (int) (x * mouse.x / [self width]); - // If the view was not resizable, then this would be simpler: - // int mouseY = y - (int) mouse.y; - // int mouseX = (int) mouse.x; - - ADBMouseMoved(mouseX, mouseY); - return YES; -} - -- (void) mouseDown: (NSEvent *) event -{ - [self processMouseMove: event]; - ADBMouseDown(0); -} - -- (void) mouseDragged: (NSEvent *) event -{ - [self processMouseMove: event]; -} - -- (void) mouseMoved: (NSEvent *) event -{ -#if DEBUG - if ( ! [self mouseInView] ) - { - NSLog (@"%s - Received event while outside of view", __PRETTY_FUNCTION__); - return; - } -#endif - [self processMouseMove: event]; -} - -- (void) mouseUp: (NSEvent *) event -{ - [self processMouseMove: event]; - ADBMouseUp(0); -} - -#if DEBUG -- (void) randomise // Draw some coloured snow in the bitmap -{ - unsigned char *data, - *pixel; - - #ifdef NSBITMAP - data = [bitmap bitmapData]; - #else - data = bitmap; - #endif - - for ( int i = 0; i < 1000; ++i ) - { - pixel = data + (int) (numBytes * rand() / RAND_MAX); - *pixel = (unsigned char) (256.0 * rand() / RAND_MAX); - } -} -#endif - -- (void) drawRect: (NSRect) rect -{ - if ( ! drawView ) // If the emulator is still being setup, - return; // we do not want to draw - -#if DEBUG - NSLog(@"In drawRect"); - [self randomise]; -#endif - -#ifdef NSBITMAP - NSRectClip(rect); - [bitmap draw]; -#endif -#ifdef CGIMAGEREF - cgDrawInto(rect, cgImgRep); -#endif -#ifdef CGDRAWBITMAP - [self CGDrawBitmap]; -#endif -} - -- (void) setTo: (int) val // Set all of bitmap to val -{ - unsigned char *data - #ifdef NSBITMAP - = [bitmap bitmapData]; - #else - = (unsigned char *) bitmap; - #endif - - memset(data, val, (long unsigned)numBytes); -} - -- (void) blacken // Set bitmap black -{ - [self setTo: 0]; -} - -- (void) clear // Set bitmap white -{ - [self setTo: 0xFF]; -} - -// -// Extra drawing stuff -// - -#ifdef CGDRAWBITMAP -extern "C" void CGDrawBitmap(...); - -- (void) CGDrawBitmap -{ - CGContextRef cgContext = (CGContextRef) [[NSGraphicsContext currentContext] - graphicsPort]; - NSRect rect = [self bounds]; - CGRect cgRect = { - {rect.origin.x, rect.origin.y}, - {rect.size.width, rect.size.height} - }; - - CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); - - -// CGContextSetShouldAntialias(cgContext, NO); // Seems to have no effect? - - CGDrawBitmap(cgContext, cgRect, x, y, bps, spp, bpp, - bytesPerRow, isPlanar, hasAlpha, colourSpace, &bitmap); -} -#endif - -#ifdef CGIMAGEREF -void -cgDrawInto(NSRect rect, CGImageRef cgImgRep) -{ - CGContextRef cgContext = (CGContextRef) [[NSGraphicsContext currentContext] - graphicsPort]; - CGRect cgRect = { - {rect.origin.x, rect.origin.y}, - {rect.size.width, rect.size.height} - }; - -// CGContextSetShouldAntialias(cgContext, NO); // Seems to have no effect? - - CGContextDrawImage(cgContext, cgRect, cgImgRep); -} -#endif - -@end diff --git a/BasiliskII/src/MacOSX/English.lproj/InfoPlist.strings b/BasiliskII/src/MacOSX/English.lproj/InfoPlist.strings deleted file mode 100755 index fbcc2d40..00000000 --- a/BasiliskII/src/MacOSX/English.lproj/InfoPlist.strings +++ /dev/null @@ -1,3 +0,0 @@ -/* Localized versions of Info.plist keys */ - -NSHumanReadableCopyright = "Copyright © 1997-2006 Christian Bauer et al. Freely distributable under the terms of the GNU GPL."; diff --git a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/Collapsed.tiff b/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/Collapsed.tiff deleted file mode 100644 index e4647bbb..00000000 Binary files a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/Collapsed.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/Expanded.tiff b/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/Expanded.tiff deleted file mode 100644 index 819a88f0..00000000 Binary files a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/Expanded.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/classes.nib b/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/classes.nib deleted file mode 100644 index 8d5b001b..00000000 --- a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/classes.nib +++ /dev/null @@ -1,131 +0,0 @@ -{ - IBClasses = ( - { - ACTIONS = { - HelpHowTo = id; - HelpToDo = id; - HelpVersions = id; - NewEmulator = id; - PauseAll = id; - RunAll = id; - TerminateAll = id; - }; - CLASS = Controller; - LANGUAGE = ObjC; - OUTLETS = {theEmulator = id; thePrefsEditor = id; }; - SUPERCLASS = NSApplication; - }, - { - ACTIONS = { - Benchmark = id; - Interrupt = id; - PowerKey = id; - Restart = id; - Resume = id; - ScreenHideShow = id; - Snapshot = id; - SpeedChange = id; - Suspend = id; - Terminate = id; - ToggleState = id; - ZapPRAM = id; - }; - CLASS = Emulator; - LANGUAGE = ObjC; - OUTLETS = {barberPole = id; runOrPause = id; screen = id; speed = id; win = id; }; - SUPERCLASS = NSObject; - }, - {CLASS = EmulatorView; LANGUAGE = ObjC; SUPERCLASS = NSView; }, - { - ACTIONS = { - Interrupt = id; - PowerKey = id; - Restart = id; - Resume = id; - Snapshot = id; - Suspend = id; - Terminate = id; - ZapPRAM = id; - }; - CLASS = FirstResponder; - LANGUAGE = ObjC; - SUPERCLASS = NSObject; - }, - { - ACTIONS = { - AddSCSI = id; - AddVolume = id; - BrowseExtFS = id; - BrowsePrefs = id; - BrowseROM = id; - ChangeBootFrom = id; - ChangeCPU = id; - ChangeDisableCD = id; - ChangeDisableSound = id; - ChangeFPU = id; - ChangeKeyboard = id; - ChangeModel = id; - ChangeScreen = id; - CreateVolume = id; - DeleteVolume = id; - EditBytes = id; - EditDelay = id; - EditEtherNetDevice = id; - EditExtFS = id; - EditFrequency = id; - EditMB = id; - EditModemDevice = id; - EditPrinterDevice = id; - EditROMpath = id; - LoadPrefs = id; - RemoveSCSI = id; - RemoveVolume = id; - ResetPrefs = id; - SavePrefs = id; - ShowPrefs = id; - }; - CLASS = PrefsEditor; - LANGUAGE = ObjC; - OUTLETS = { - CPU68000 = id; - CPU68020 = id; - CPU68030 = id; - CPU68040 = id; - FPU = id; - IIci = id; - MB = id; - ROMfile = id; - SCSIdisks = id; - bootFromAny = id; - bootFromCD = id; - bytes = id; - classic = id; - delay = id; - depth = id; - disableCD = id; - disableSound = id; - diskImages = id; - emuFreq = id; - emuWin = id; - etherNet = id; - extFS = id; - frequency = id; - height = id; - keyboard = id; - modem = id; - newVolumeSize = id; - newVolumeView = id; - panel = id; - prefsFile = id; - printer = id; - quadra900 = id; - screen = id; - theEmulator = id; - width = id; - window = id; - }; - SUPERCLASS = NSObject; - } - ); - IBVersion = 1; -} \ No newline at end of file diff --git a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/info.nib b/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/info.nib deleted file mode 100644 index 86784542..00000000 --- a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/info.nib +++ /dev/null @@ -1,36 +0,0 @@ - - - - - IBDocumentLocation - 3 11 521 240 0 4 1152 742 - IBEditorPositions - - 29 - 3 256 365 44 0 0 1152 746 - - IBFramework Version - 349.0 - IBLockedObjects - - 288 - - IBOpenObjects - - 29 - 813 - - IBSystem Version - 7D24 - IBUserGuides - - VolumeSize - - guideLocations - - guidesLocked - NO - - - - diff --git a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/objects.nib b/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/objects.nib deleted file mode 100644 index c86a0e8f..00000000 Binary files a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/objects.nib and /dev/null differ diff --git a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/resetH.tiff b/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/resetH.tiff deleted file mode 100644 index ed556af4..00000000 Binary files a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/resetH.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/resetN.tiff b/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/resetN.tiff deleted file mode 100644 index c0c18a6c..00000000 Binary files a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/resetN.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/shutdownH.tiff b/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/shutdownH.tiff deleted file mode 100644 index 522409ab..00000000 Binary files a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/shutdownH.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/shutdownN.tiff b/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/shutdownN.tiff deleted file mode 100644 index 61f5a7dd..00000000 Binary files a/BasiliskII/src/MacOSX/English.lproj/MainMenu.nib/shutdownN.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/HowTo.html b/BasiliskII/src/MacOSX/HowTo.html deleted file mode 100644 index 49fcb4c6..00000000 --- a/BasiliskII/src/MacOSX/HowTo.html +++ /dev/null @@ -1,226 +0,0 @@ - -Basilisk II, Mac OS X port, HowTos - - -

Index

- - - -
- -

Minimum Requirements

- -To run Basilisk II, you need both: -
    -
  • A Mac ROM image. Even though there is a ROM in your OS X Mac, - it is too new for a 68k Mac to make use of. Any Mac II ROM, - and most of the Quadra ROMS, will work. -
    (Quadra 660av and 840av ROMs are currently unusable. - I don't know about Mac LC ROMs. In the near future, Mac Plus, - SE or Classic ROMS may also be usable, though only for emulating - a monochrome Mac).
  • -
  • A copy of the MacOS, which at the moment has to either be on - a CD-ROM, or on a disk image
  • -
- -
- -

Macintosh ROM image

- -

To run Basilisk II, you need a ROM image, which is a data file -containing a copy of the ROM chips from a real 68k Macintosh.

- -

The best way (i.e. most legally acceptable) to get a ROM -image is to produce it from your old Mac. Take a program like CopyROM, -download it onto your old Mac, and use it to produce the image file, -which you then copy or upload to your OS X Mac. -A good page which describes this process is -here. -

- -

The easiest way to get a ROM image is to get one from someone else -(e.g. another Basilisk II user, or an emulation web site). -Note that this probably contravenes several copyright laws.

- -

Once you have your ROM image, you need to tell Basilisk II to use it: -

    -
  1. Open the Basilisk II application
  2. -
  3. Go to the 'BasiliskII' menu, then the Preferences...' menu item
  4. -
  5. On the Emulation tab, there is a field 'ROM file:'. Either type in the -path to the ROM file, or click the Browse button and Open the ROM file
  6. -
  7. Click the Save button, so that Basilisk II will be able to find the ROM -each time you boot it
  8. -
-

- -

If you want to test this, press the Run or Power button -(in the top right corner of the 'BasiliskII Emulator' window). -After a few moments you should see a Mac screen, with a picture of a floppy -disk with a flashing question mark. That is the Mac telling you that it needs -a disk to boot from.

- -
- -

Finding a boot disk

- -

Basilisk II needs a copy of the MacOS to boot from. Anything from System 7 -through to MacOS 8.1 should be usable. -
(Felix Eng and I have only tested System 7.0.1, 7.1, 7.5.3 and 7.6, -although Felix also got System 6.0.8 to work with SE/30 Roms)

- -Basilisk II can currently boot from: - - - - - - - - - - - - - -
CD-ROM Most (not all) MacOS Install CDs will also boot your Mac. I also think - that some old Norton Utilities install CDs might have booted 68k Macs
Floppy disk image Jonathan C. Silverstein reports that - this Apple floppy disk image will boot Basilisk II
Preinstalled Basilisk II disk image Another Basilisk II user might be willing to loan you the disk image -that they are using
- -

It is possible to use Basilisk II with a CD-ROM or floppy image, but -because most bootable CDs have a minimal System Folder, it is better if you -use a disk image with a more complete MacOS installed on it. The next section -tells you how to do this.

- -

Note that there is currently no Install CD image on Apple's Web site, but -they do seem to have MacOS 7.5.3 floppy disk images (all 19 of them). Burning -those images onto a CD (not in the extended format) should allow you to install. -
Thanks to Attilio Farina for this tip!

- -

Installing the MacOS

- -

Create a new BasiliskII disk

- -

Before you can install the MacOS onto a disk volume, -you need to create a disk to install onto:

- -
    -
  1. Start up the Basilisk application.
    - (If it is already running, skip this step)
  2. -
  3. Open the preferences.
  4. -
  5. Go to the Disk Volumes tab.
  6. -
  7. Press the 'Create...' button - (go with the defaults, unless you think you will need a huge disk).
  8. -
- -

If you want to have more than one hard disk available to Basilisk II, -you could create additional volumes here.

- -

Installing the MacOS

- -

Insert your MacOS install CD-ROM, and wait a few moments for the -OS X Finder to mount the disk. While still in your preferences:

- -
    -
  1. Go to the Emulation tab and check that your emulation is appropriate - for your install image -
    (e.g. I had to change from Quadra900 to IIci, - because my generic 7.1 install CD didn't support the Quadra), - and that you have the RAM size set appropriately -
    (e.g. 8MB RAM may not be enough for a 7.5.3 install).
  2. -
  3. Click the save button.
  4. -
  5. In the BasiliskII Emulator window, click Run.
    - (If it is already running, but showing the floppy with the question mark, - press the restart button - the triangle in the bottom right hand corner)
    - You should get a HappyMac, and the emulator will start to boot from the CD. - You should then a dialog asking you to format a disk.
  6. -
  7. Click Initialize, then Erase, give the disk an appropriate name - (e.g. Hard Disk), then click OK.
  8. -
  9. Find the OS installer (in my case the CD booted into At Ease, and one of - the first buttons was 'Install System'), and go with the defaults.
  10. -
- -

After the installer finishes it may try to reboot (or you may need to -force a reboot). When it reboots, BasiliskII may exit. Start it again, -and you should boot into your installed OS.

- -
- -

Mounting Unix Files

- -

If Basilisk II is running MacOS 7.5.3 or newer, you can easily access some -of the files from your OS X disks. Just set the 'Unix directory to mount' in the -Volumes tab of the Preferences. Next time the Emulator starts up, a new disk -will appear on its Desktop (called Unix).

- -

To prevent clashes with the OS X desktop files, I suggest that the directory -you select is not a whole disk (e.g. '/' or '/Volumes/disk'). Mount a -sub-folder instead (like '/Applications (Mac OS 9)').

- -
- -

Importing Mac Files

- -

If you are not running MacOS 7.5.3 or newer, the above trick won't work. -This makes getting files into Basilisk II harder. Luckily, Apple's 'Disk Copy' -or 'Disk Utility' can create a disk image file that is compatible -with Basilisk II (i.e. you can add it as a disk volume).

- -
    -
  1. Open 10.1's 'Disk Copy' program, and create a 'Mac Standard' image, -
    or 10.3's 'Disk Utility', and create a 'read/write disk image', -
    or Disk Copy 6.??? in Classic, and create new image
  2. -
  3. If the image is not mounted, mount it
  4. -
  5. Copy any files that you want to access in the emulator to the mounted - image
  6. -
  7. Unmount the image
  8. -
  9. In Basilisk II's preferences, go to the 'Disk Volumes' tab, - add your new image, and start the emulation
  10. -
- -A new disk should appear on the emulation's desktop which contains the files -that you wanted to access. If the emulator complains about a disk needing to -be formatted, you may have chosen the wrong type of image type in 'Disk Copy' -or 'Disk Utility.' - -
-

Networking

- -

If your Mac is networked, then your emulated MacOS can also access that -network: -

    -
  1. Open Basilisk II, go to the Preferences, then the Hardware tab, -and set the emulator's EtherNet interface to slirp
  2. -
  3. Start the Emulator
  4. -
  5. In the emulated MacOS, open the TCP/IP Control Panel and set: -
      -
    • 'Connect via:' to EtherNet, and
    • -
    • 'Configure:' to 'Using DHCP Server'
    • -
    -
  6. Restart the emulation.
  7. -
-You should now be able to surf the web, or FTP download software, -in the emulated Mac. Not sure about AppleTalk networking, though.

- -

Note that this does not require the OS X Mac to be using EtherNet, -any working TCP/IP networking should be fine. I have tested it over -DHCP EtherNet (ADSL modem/router at home), and with a static IP -address at work (which also has an external web proxy/firewall).

- -
- -$Id$ -
-Written by Nigel Pearson on 26th March, 2003. - - - - diff --git a/BasiliskII/src/MacOSX/Info.plist b/BasiliskII/src/MacOSX/Info.plist deleted file mode 100644 index 31a02329..00000000 --- a/BasiliskII/src/MacOSX/Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - BasiliskII - CFBundleGetInfoString - Basilisk II version 1.0, Copyright © 1997-2006 Christian Bauer et al. Mac OS X port 19 - CFBundleIconFile - BasiliskII.icns - CFBundleIdentifier - - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - BasiliskII - CFBundlePackageType - APPL - CFBundleShortVersionString - Basilisk II 1.0, Mac OS X port 19 - CFBundleSignature - ???? - NSHelpFile - README.txt - NSMainNibFile - MainMenu - NSPrincipalClass - Controller - - diff --git a/BasiliskII/src/MacOSX/MacOSX_sound_if.cpp b/BasiliskII/src/MacOSX/MacOSX_sound_if.cpp deleted file mode 100644 index bb463c65..00000000 --- a/BasiliskII/src/MacOSX/MacOSX_sound_if.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * MacOSX_sound_if.h - * BasiliskII - * - * Copyright 2006 Daniel Sumorok. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include "AudioBackEnd.h" -#include "MacOSX_sound_if.h" - -OSXsoundOutput::OSXsoundOutput() : - player(NULL), - callback(NULL) { -} - -void OSXsoundOutput::getMoreSamples(void *arg) { - OSXsoundOutput *me; - - me = (OSXsoundOutput *)arg; - - if(me == NULL) { - return; - } - - if(me->callback == NULL) { - return; - } - - me->callback(); -} - -int OSXsoundOutput::start(int bitsPerSample, int numChannels, int sampleRate) { - stop(); - player = new AudioBackEnd(bitsPerSample, numChannels, sampleRate); - if(player != NULL) { - player->setCallback(getMoreSamples, (void *)this); - player->Start(); - } - return 0; -} - -int OSXsoundOutput::stop() { - if(player != NULL) { - player->Stop(); - delete player; - player = NULL; - } - return 0; -} - -OSXsoundOutput::~OSXsoundOutput() { - stop(); -} - -void OSXsoundOutput::setCallback(audioCallback fn) { - callback = fn; -} - -unsigned int OSXsoundOutput::bufferSizeFrames() { - if(player != NULL) { - return player->BufferSizeFrames(); - } - - return 0; -} - -int OSXsoundOutput::sendAudioBuffer(void *buffer, int numFrames) { - if(player != NULL) { - return player->sendAudioBuffer(buffer, numFrames); - } - - return 0; -} diff --git a/BasiliskII/src/MacOSX/MacOSX_sound_if.h b/BasiliskII/src/MacOSX/MacOSX_sound_if.h deleted file mode 100644 index 5cfdd438..00000000 --- a/BasiliskII/src/MacOSX/MacOSX_sound_if.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * MacOSX_sound_if.h - * BasiliskII - * - * Copyright 2006 Daniel Sumorok. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -typedef int (*audioCallback)(void); - -class AudioBackEnd; - -class OSXsoundOutput { - private: - static void getMoreSamples(void *arg); - - AudioBackEnd *player; - audioCallback callback; - public: - OSXsoundOutput(); - ~OSXsoundOutput(); - int start(int bitsPerSample, int numChannels, int sampleRate); - int stop(); - int putBuffer(void *buffer, int numSamples); - void setCallback(audioCallback fn); - unsigned int bufferSizeFrames(); - int sendAudioBuffer(void *buffer, int numFrames); -}; diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/InfoPlist.strings b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/InfoPlist.strings deleted file mode 100755 index da3ff3eb..00000000 --- a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/InfoPlist.strings +++ /dev/null @@ -1,4 +0,0 @@ -/* Localized versions of Info.plist keys */ - -CFBundleName = "BasiliskII"; -NSHumanReadableCopyright = "Copyright 1997-2001 Christian Bauer et al., Freely distributable under the terms of the GNU GPL"; diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/MainMenu.nib/classes.nib b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/MainMenu.nib/classes.nib deleted file mode 100644 index aee209e4..00000000 --- a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/MainMenu.nib/classes.nib +++ /dev/null @@ -1,118 +0,0 @@ -{ - IBClasses = ( - { - ACTIONS = { - NewEmulator = id; - PauseAll = id; - RunAll = id; - ShowAbout = id; - TerminateAll = id; - }; - CLASS = Controller; - LANGUAGE = ObjC; - OUTLETS = {myEmulator = id; }; - SUPERCLASS = NSObject; - }, - { - ACTIONS = { - Interrupt = id; - PowerKey = id; - Restart = id; - Resume = id; - Snapshot = id; - SpeedChange = id; - Suspend = id; - Terminate = id; - ToggleState = id; - ZapPRAM = id; - }; - CLASS = Emulator; - LANGUAGE = ObjC; - OUTLETS = {barberPole = id; runOrPause = id; screen = id; speed = id; win = id; }; - SUPERCLASS = NSObject; - }, - {CLASS = EmulatorView; LANGUAGE = ObjC; SUPERCLASS = NSView; }, - { - ACTIONS = { - Interrupt = id; - PowerKey = id; - Restart = id; - Resume = id; - Snapshot = id; - Suspend = id; - Terminate = id; - ZapPRAM = id; - }; - CLASS = FirstResponder; - LANGUAGE = ObjC; - SUPERCLASS = NSObject; - }, - { - ACTIONS = { - AddSCSI = id; - AddVolume = id; - BrowseEtherNet = id; - BrowseExtFS = id; - BrowseModem = id; - BrowsePrinter = id; - BrowseROM = id; - ChangeBootFrom = id; - ChangeCPU = id; - ChangeDisableCD = id; - ChangeDisableSound = id; - ChangeFPU = id; - ChangeModel = id; - CreateVolume = id; - DeleteVolume = id; - EditBytes = id; - EditDelay = id; - EditDepth = id; - EditEtherNetDevice = id; - EditExtFS = id; - EditFrequency = id; - EditHeight = id; - EditMB = id; - EditModemDevice = id; - EditPrinterDevice = id; - EditROMpath = id; - EditWidth = id; - RemoveSCSI = id; - RemoveVolume = id; - ShowPrefs = id; - }; - CLASS = PrefsEditor; - LANGUAGE = ObjC; - OUTLETS = { - CPU68000 = id; - CPU68020 = id; - CPU68030 = id; - CPU68040 = id; - FPU = id; - IIci = id; - MB = id; - Quadra900 = id; - ROMfile = id; - SCSIdisks = id; - bootFromAny = id; - bootFromCD = id; - bytes = id; - classic = id; - delay = id; - depth = id; - disableCD = id; - disableSound = id; - diskImages = id; - etherNet = id; - extFS = id; - frequency = id; - height = id; - modem = id; - panel = id; - printer = id; - width = id; - }; - SUPERCLASS = NSObject; - } - ); - IBVersion = 1; -} \ No newline at end of file diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/MainMenu.nib/info.nib b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/MainMenu.nib/info.nib deleted file mode 100644 index c3bc0447..00000000 --- a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/MainMenu.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBDocumentLocation - 5 42 473 240 0 41 1024 705 - IBMainMenuLocation - 0 702 365 44 0 42 1152 704 - IBUserGuides - - About - - guideLocations - - guidesLocked - NO - - - - diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/MainMenu.nib/objects.nib b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/MainMenu.nib/objects.nib deleted file mode 100644 index 25afc5f2..00000000 Binary files a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/MainMenu.nib/objects.nib and /dev/null differ diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/Collapsed.tiff b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/Collapsed.tiff deleted file mode 100644 index e4647bbb..00000000 Binary files a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/Collapsed.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/Expanded.tiff b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/Expanded.tiff deleted file mode 100644 index 819a88f0..00000000 Binary files a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/Expanded.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/classes.nib b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/classes.nib deleted file mode 100644 index e78b8572..00000000 --- a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/classes.nib +++ /dev/null @@ -1,32 +0,0 @@ -{ - IBClasses = ( - { - ACTIONS = {NewEmulator = id; ShowAbout = id; pauseAll = id; terminateAll = id; }; - CLASS = Controller; - LANGUAGE = ObjC; - OUTLETS = {myEmulator = id; }; - SUPERCLASS = NSObject; - }, - { - ACTIONS = { - Interrupt = id; - PowerKey = id; - Restart = id; - Resume = id; - Snapshot = id; - SpeedChange = id; - Suspend = id; - Terminate = id; - ToggleState = id; - ZapPRAM = id; - }; - CLASS = Emulator; - LANGUAGE = ObjC; - OUTLETS = {barberPole = id; runOrPause = id; screen = id; speed = id; win = id; }; - SUPERCLASS = NSObject; - }, - {CLASS = EmulatorView; LANGUAGE = ObjC; SUPERCLASS = NSView; }, - {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; } - ); - IBVersion = 1; -} \ No newline at end of file diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/info.nib b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/info.nib deleted file mode 100644 index 8c4ad339..00000000 --- a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBDocumentLocation - 18 42 473 240 0 41 1024 705 - IBMainMenuLocation - 0 702 365 44 0 41 1024 705 - IBUserGuides - - Window - - guideLocations - - guidesLocked - NO - - - - diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/objects.nib b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/objects.nib deleted file mode 100644 index a1bd5ec9..00000000 Binary files a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/objects.nib and /dev/null differ diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/resetH.tiff b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/resetH.tiff deleted file mode 100644 index ed556af4..00000000 Binary files a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/resetH.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/resetN.tiff b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/resetN.tiff deleted file mode 100644 index c0c18a6c..00000000 Binary files a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/resetN.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/shutdownH.tiff b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/shutdownH.tiff deleted file mode 100644 index 522409ab..00000000 Binary files a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/shutdownH.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/shutdownN.tiff b/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/shutdownN.tiff deleted file mode 100644 index 61f5a7dd..00000000 Binary files a/BasiliskII/src/MacOSX/Multiple-Windows/English.lproj/Win512x342.nib/shutdownN.tiff and /dev/null differ diff --git a/BasiliskII/src/MacOSX/Multiple-Windows/README b/BasiliskII/src/MacOSX/Multiple-Windows/README deleted file mode 100644 index b67bd892..00000000 --- a/BasiliskII/src/MacOSX/Multiple-Windows/README +++ /dev/null @@ -1,5 +0,0 @@ -This is a version of the interface that would allow multiple emulations to -run side-by-side, in different windows. Currently, the uae_cpu engine is not -re-entrant, and some of the Basilisk glue would not allow this, so this will -probably never be used. I will save it here for educational purposes, and just -in case this feature is ever needed. diff --git a/BasiliskII/src/MacOSX/NNThread.h b/BasiliskII/src/MacOSX/NNThread.h deleted file mode 100644 index 72a0a1d5..00000000 --- a/BasiliskII/src/MacOSX/NNThread.h +++ /dev/null @@ -1,91 +0,0 @@ -// -// NNThread.h -Not Nextstep Thread? -// Nigel's Nice Thread? -// -// Revision 1.2, Tuesday May 25 2004 -// -// Created by Nigel Pearson on Tue Nov 28 2000. -// Public Domain. No rights reserved. -// - -// Define what flavour of threading to use: -#define USE_NSTHREAD -//#define USE_PTHREAD - -#import - -#import -#import - -#ifdef USE_PTHREAD -#include - -struct pthreadArgs // This duplicates most of the stuff in the NNThread object -{ - id *object; - SEL *sel; - - NSAutoreleasePool *pool; - BOOL allocPool, - *completed; -}; -#endif - -@interface NNThread : NSObject -{ - id object; - SEL sel; - thread_t machThread; -#ifdef USE_PTHREAD - pthread_t pThread; - struct pthreadArgs pthreadArgs; -#endif - NSAutoreleasePool *pool; - BOOL allocPool, - completed, - suspended; -} - -- (NNThread *) initWithAutoReleasePool; -- (NNThread *) initSuspended: (BOOL) startSuspended - withAutoreleasePool: (BOOL) allocatePool; - -- (void) perform: (SEL)action of: (id)receiver; -- (void) resume; -- (BOOL) start; -- (void) suspend; -- (void) terminate; - -@end - -typedef enum _NNTimeUnits -{ - NNnanoSeconds = 1, - NNmicroSeconds = 2, - NNmilliSeconds = 3, - NNseconds = 4 -} -NNTimeUnits; - -#import - -@interface NNTimer : NNThread -{ - struct timespec delay; - BOOL repeating; - id timerObject; - SEL timerSel; -} - -- (NNTimer *) initWithAutoRelPool; - -- (void) changeIntervalTo: (int)number units: (NNTimeUnits)units; -- (void) invalidate; - -- (void) perform: (SEL)action of: (id)receiver - after: (int)number units: (NNTimeUnits)units; - -- (void) repeat: (SEL)action of: (id)receiver - every: (int)number units: (NNTimeUnits)units; - -@end \ No newline at end of file diff --git a/BasiliskII/src/MacOSX/NNThread.m b/BasiliskII/src/MacOSX/NNThread.m deleted file mode 100644 index 535aa877..00000000 --- a/BasiliskII/src/MacOSX/NNThread.m +++ /dev/null @@ -1,257 +0,0 @@ -// -// NNThread.m -Not Nextstep Thread? -// Nigel's Nice Thread? -// -// Revision 1.4, Tuesday May 25 2004 -// -// Created by Nigel Pearson on Tue Nov 28 2000. -// Public Domain. No rights reserved. -// - -#import "NNThread.h" -#import // For objc_msgSend() prototype - -@implementation NNThread - -// Define the wrapper first so that init knows about it without having to put it in the .h - -#ifdef USE_NSTHREAD -- (void) wrapper -{ - machThread = mach_thread_self(); - - if ( object == nil || sel == (SEL) nil || suspended ) - thread_suspend (machThread); // Suspend myself - - if ( allocPool ) - pool = [NSAutoreleasePool new]; - - // [object sel] caused "cannot find method" warnings, so I do it a non-obvious way: - objc_msgSend (object, sel); - - completed = YES; - - if ( allocPool ) - [pool release]; -} -#endif - -#ifdef USE_PTHREAD -void * -pthreadWrapper (void *arg) -{ - struct pthreadArgs *args = arg; - - if ( args -> allocPool ) - args -> pool = [NSAutoreleasePool new]; - - objc_msgSend (*(args->object), *(args->sel)); - - *(args->completed) = YES; - - if ( args -> allocPool ) - [args -> pool release]; - - return NULL; -} - -- (BOOL) wrapper -{ - int error; - - pthreadArgs.object = &object; - pthreadArgs.sel = &sel; - pthreadArgs.allocPool = allocPool; - pthreadArgs.completed = &completed; - pthreadArgs.pool = nil; - - if ( object == nil || sel == (SEL) nil || suspended ) - error = pthread_create_suspended_np (&pThread, NULL, &pthreadWrapper, &pthreadArgs); - else - error = pthread_create (&pThread, NULL, &pthreadWrapper, &pthreadArgs); - - if ( error ) - NSLog(@"%s - pthread_create failed"); - else - machThread = pthread_mach_thread_np (pThread); - - return ! error; -} -#endif - -- (NNThread *) initSuspended: (BOOL) startSuspended - withAutoreleasePool: (BOOL) allocatePool -{ - self = [super init]; - - allocPool = allocatePool; - completed = NO; - suspended = startSuspended; - object = nil; - sel = (SEL) nil; - -#ifdef USE_NSTHREAD - [NSThread detachNewThreadSelector:@selector(wrapper) - toTarget:self - withObject:nil]; -#endif - -#ifdef USE_PTHREAD - if ( ! [self wrapper] ) // Wrapper does the thread creation - { - NSLog(@"%s - pthread wrapper failed", __PRETTY_FUNCTION__); - return nil; - } -#endif - - return self; -} - -- (NNThread *) init -{ - return [self initSuspended: YES withAutoreleasePool: NO]; -} - -- (NNThread *) initWithAutoReleasePool -{ - return [self initSuspended: YES withAutoreleasePool: YES]; -} - -- (BOOL) completed -{ - return completed; -} - -- (void) perform: (SEL)action of: (id)receiver -{ - object = receiver, sel = action; -} - -- (void) resume -{ - if ( suspended ) - [self start]; - else - NSLog (@"%s - thread not suspended", __PRETTY_FUNCTION__); -} - -- (BOOL) start -{ - kern_return_t error; - - if ( object == nil || sel == (SEL) nil ) - { - NSLog (@"%s - cannot start thread, object or selector invalid", __PRETTY_FUNCTION__); - return NO; - } - if ( ( error = thread_resume (machThread) ) != KERN_SUCCESS ) - NSLog (@"%s - thread_resume() failed, returned %d", __PRETTY_FUNCTION__, error); - suspended = NO; - return YES; -} - -- (void) suspend -{ - if ( ! suspended ) - { - kern_return_t error; - - if ( ( error = thread_suspend (machThread) ) != KERN_SUCCESS ) - NSLog (@"%s - thread_resume() failed, returned %d", __PRETTY_FUNCTION__, error); - suspended = YES; - } -} - -- (void) terminate -{ - kern_return_t error; - - if ( ( error = thread_terminate (machThread) ) != KERN_SUCCESS ) - NSLog (@"%s - thread_terminate() failed, returned %d", __PRETTY_FUNCTION__, error); -} - -@end - -@implementation NNTimer - -- (NNTimer *) init -{ - self = [super init]; - repeating = YES; - return self; -} - -- (NNTimer *) initWithAutoRelPool -{ - self = [super init]; - allocPool = YES; - repeating = YES; - return self; -} - - -- (void) changeIntervalTo: (int)number - units: (NNTimeUnits)units -{ - switch ( units ) - { - case NNnanoSeconds: - delay.tv_nsec = number; - delay.tv_sec = 0; - break; - case NNmicroSeconds: - delay.tv_nsec = number * 1000; - delay.tv_sec = 0; - break; - case NNmilliSeconds: - delay.tv_nsec = number * 1000000; - delay.tv_sec = 0; - break; - case NNseconds: - delay.tv_nsec = 0; - delay.tv_sec = number; - break; - default: - NSLog (@"%s illegal units(%d)", __PRETTY_FUNCTION__, units); - } -} - -- (void) invalidate -{ - repeating = NO; -} - -- (void) timerLoop -{ - // For some strange reason, Mac OS X does not have this prototype - extern int nanosleep (const struct timespec *rqtp, struct timespec *rmtp); - - while ( repeating ) - { - nanosleep(&delay, NULL); - completed = NO; - // This caused a few warnings: - // [timerObject timerSel]; - // so I do it a non-obvious way: - objc_msgSend (timerObject, timerSel); - completed = YES; - } -} - -- (void) perform: (SEL)action of: (id)receiver - after: (int)number units: (NNTimeUnits)units -{ - object = self, sel = @selector(timerLoop), - timerObject = receiver, timerSel = action, repeating = NO; - [self changeIntervalTo: number units: units]; -} - -- (void) repeat: (SEL)action of: (id)receiver - every: (int)number units: (NNTimeUnits)units -{ - object = self, sel = @selector(timerLoop), - timerObject = receiver, timerSel = action, repeating = YES; - [self changeIntervalTo: number units: units]; -} - -@end \ No newline at end of file diff --git a/BasiliskII/src/MacOSX/PrefsEditor.h b/BasiliskII/src/MacOSX/PrefsEditor.h deleted file mode 100644 index b67c2310..00000000 --- a/BasiliskII/src/MacOSX/PrefsEditor.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * PrefsEditor.h - GUI stuff for Basilisk II preferences - * (which is a text file in the user's home directory) - * - * $Id$ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import - -@interface TableDS : NSObject -{ - int numItems; - NSMutableArray *col1, - *col2; -} - -- (void) addInt: (int)target - withPath: (NSString *)path; - -- (void) addObject: (NSObject *)obj - withPath: (NSString *)path; - -- (void) deleteAll; - -- (BOOL) deleteRow: (int)row; - -- (int) intAtRow: (int)row; - -- (int) numberOfRowsInTableView: (NSTableView *)tView; - -- (NSString *) pathAtRow: (int)row; - -- (id) tableView: (NSTableView *)tView - objectValueForTableColumn: (NSTableColumn *)tColumn - row: (int)rowIndex; -@end - -#include "Emulator.h" - -@interface PrefsEditor : NSObject -{ - IBOutlet NSSlider *emuFreq; - IBOutlet NSView *newVolumeView; - IBOutlet NSTextField *newVolumeSize; - IBOutlet NSWindow *panel; - IBOutlet Emulator *theEmulator; - - - IBOutlet NSButton *bootFromAny, - *bootFromCD; - IBOutlet NSTextField *bytes; - IBOutlet NSButton *classic, - *CPU68000, - *CPU68020, - *CPU68030, - *CPU68040; - IBOutlet NSTextField *delay, - *depth; - IBOutlet NSButton *disableCD, - *disableSound; - IBOutlet NSTableView *diskImages; - IBOutlet NSTextField *etherNet, - *extFS; - IBOutlet NSButton *FPU; - IBOutlet NSTextField *frequency, - *height; - IBOutlet NSButton *IIci; - IBOutlet NSPopUpButton *keyboard; - IBOutlet NSTextField *MB, - *modem; - IBOutlet NSButton *openGL; - IBOutlet NSTextField *prefsFile, - *printer; - IBOutlet NSButton *quadra900; - IBOutlet NSTextField *ROMfile; - IBOutlet NSButton *screen; - IBOutlet NSTableView *SCSIdisks; - IBOutlet NSTextField *width; - IBOutlet NSButton *window; - - NSString *devs, - *home; - - TableDS *volsDS, // Object managing tha data in the Volumes, - *SCSIds; // and SCSI devices, tables - - NSImage *locked, - *blank; - NSImageCell *lockCell; - - BOOL edited; // Set if the user changes anything, reset on save -} - -- (BOOL) hasEdited; -- (NSWindow *) window; - -- (IBAction) AddSCSI: (id)sender; -- (IBAction) AddVolume: (id)sender; -- (IBAction) BrowseExtFS: (id)sender; -- (IBAction) BrowsePrefs: (id)sender; -- (IBAction) BrowseROM: (id)sender; -- (IBAction) ChangeBootFrom: (NSMatrix *)sender; -- (IBAction) ChangeCPU: (NSMatrix *)sender; -- (IBAction) ChangeDisableCD: (NSButton *)sender; -- (IBAction) ChangeDisableSound:(NSButton *)sender; -- (IBAction) ChangeFPU: (NSButton *)sender; -- (IBAction) ChangeKeyboard: (NSPopUpButton *)sender; -- (IBAction) ChangeModel: (NSMatrix *)sender; -- (IBAction) ChangeScreen: (id)sender; -- (IBAction) CreateVolume: (id)sender; -- (IBAction) DeleteVolume: (id)sender; -- (IBAction) EditBytes: (NSTextField *)sender; -- (IBAction) EditDelay: (NSTextField *)sender; -- (IBAction) EditEtherNetDevice:(NSTextField *)sender; -- (IBAction) EditExtFS: (NSTextField *)sender; -- (IBAction) EditFrequency: (NSTextField *)sender; -- (IBAction) EditMB: (NSTextField *)sender; -- (IBAction) EditModemDevice: (NSTextField *)sender; -- (IBAction) EditPrinterDevice: (NSTextField *)sender; -- (IBAction) EditROMpath: (NSTextField *)sender; -- (IBAction) LoadPrefs: (id)sender; -- (IBAction) RemoveSCSI: (id)sender; -- (IBAction) RemoveVolume: (id)sender; -- (NSString *) RemoveVolumeEntry; -- (IBAction) ResetPrefs: (id)sender; -- (IBAction) ShowPrefs: (id)sender; -- (IBAction) SavePrefs: (id)sender; - -@end \ No newline at end of file diff --git a/BasiliskII/src/MacOSX/PrefsEditor.mm b/BasiliskII/src/MacOSX/PrefsEditor.mm deleted file mode 100644 index 1b9cd13a..00000000 --- a/BasiliskII/src/MacOSX/PrefsEditor.mm +++ /dev/null @@ -1,844 +0,0 @@ -/* - * PrefsEditor.m - GUI stuff for Basilisk II preferences - * (which is a text file in the user's home directory) - * - * $Id$ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import "PrefsEditor.h" - -@implementation TableDS - -- (TableDS *) init -{ - self = [super init]; - - numItems = 0; - col1 = [NSMutableArray new]; - col2 = [NSMutableArray new]; - - return self; -} - -- (void) dealloc -{ - [col1 dealloc]; - [col2 dealloc]; - [super dealloc]; -} - -- (void) addInt: (int)target - withPath: (NSString *)path -{ - [col1 addObject: [NSNumber numberWithInt: target]]; - [col2 addObject: path]; - ++numItems; -} - -- (void) addObject: (NSObject *)obj - withPath: (NSString *)path -{ - [col1 addObject: obj]; - [col2 addObject: path]; - ++numItems; -} - -- (void) deleteAll -{ - numItems = 0; - [col1 removeAllObjects]; - [col2 removeAllObjects]; -} - -- (BOOL) deleteRow: (int)row -{ - if ( row > numItems ) - return NO; - - [col1 removeObjectAtIndex: row]; - [col2 removeObjectAtIndex: row]; - -- numItems; - - return YES; -} - -- (int)intAtRow: (int)row -{ - return [[col1 objectAtIndex: row] intValue]; -} - -- (int) numberOfRowsInTableView: (NSTableView *)tView -{ - return numItems; -} - -- (NSString *)pathAtRow: (int)row -{ - return (NSString *) [col2 objectAtIndex: row]; -} - -- (id) tableView: (NSTableView *)tView - objectValueForTableColumn: (NSTableColumn *)tColumn - row: (int)row -{ - if ( [[tColumn identifier] isEqualToString:@"path"] ) - return [col2 objectAtIndex: row]; - else - return [col1 objectAtIndex: row]; -} - -@end - -#import // For [NSBundle pathForImageResource:] proto - -#include -using std::string; -extern string UserPrefsPath; // from prefs_unix.cpp - -#import "sysdeps.h" // Types used in Basilisk C++ code -#import "video_macosx.h" // some items that we edit here -#import "misc_macosx.h" // WarningSheet() prototype -#import "main_macosx.h" // ChoiceAlert() prototype - - -#import - -#define DEBUG 0 -#import - -@implementation PrefsEditor - -- (PrefsEditor *) init -{ - self = [super init]; - - edited = NO; - - devs = @"/dev"; - home = [NSHomeDirectory() retain]; - volsDS = [TableDS new]; - SCSIds = [TableDS new]; - - lockCell = [NSImageCell new]; - if ( lockCell == nil ) - NSLog (@"%s - Can't create NSImageCell?", __PRETTY_FUNCTION__); - - blank = [NSImage new]; - locked = [[NSImage alloc] initWithContentsOfFile: - [[NSBundle mainBundle] pathForImageResource: @"nowrite.icns"]]; - if (locked == nil ) - NSLog(@"%s - Couldn't open write protection image", __PRETTY_FUNCTION__); - - return self; -} - -- (void) dealloc -{ - [home release]; - [volsDS release]; - [SCSIds release]; - [lockCell release]; - [blank release]; - [locked release]; - [super dealloc]; -} - -- (void) awakeFromNib -{ - emuFreq = [theEmulator speed]; -#if DEBUG - [self ShowPrefs: self]; // For testing -#endif -} - -- (BOOL) hasEdited -{ - return edited; -} - -- (NSWindow *) window -{ - return panel; -} - -- (IBAction) AddSCSI: (id)sender -{ - NSOpenPanel *oP = [NSOpenPanel openPanel]; - - if ( [oP runModalForDirectory:home file:nil types:nil] == NSOKButton ) - { - [SCSIds addInt: -1 - withPath: [oP filename] ]; - [SCSIdisks reloadData]; - edited = YES; - } -} - -- (IBAction) AddVolume: (id)sender -{ - NSOpenPanel *oP = [NSOpenPanel openPanel]; - - if ( [oP runModalForDirectory:home file:nil types:nil] == NSOKButton ) - { - [volsDS addObject: (NSObject *) locked - withPath: [oP filename] ]; - PrefsAddString("disk", [[oP filename] UTF8String]); - [diskImages reloadData]; - edited = YES; - } -} - -- (IBAction) BrowseExtFS: (id)sender -{ - NSOpenPanel *oP = [NSOpenPanel openPanel]; - - [oP setCanChooseDirectories: YES]; - [oP setCanChooseFiles: NO]; - [oP setPrompt: @"Select"]; - [oP setTitle: @"Select a directory to mount"]; - D(NSLog(@"%s - home = %@, [extFS stringValue] = %@", - __PRETTY_FUNCTION__, home, [extFS stringValue])); - if ( [oP runModalForDirectory: ([extFS stringValue] ? [extFS stringValue] : home) - file:nil - types:nil] == NSOKButton ) - { - [extFS setStringValue: [oP directory] ]; - PrefsReplaceString("extfs", [[oP directory] UTF8String]); - edited = YES; - } -} - -- (IBAction) BrowsePrefs: (id)sender -{ - NSOpenPanel *oP = [NSOpenPanel openPanel]; - - [oP setCanChooseFiles: YES]; - [oP setTitle: @"Select a Preferences file"]; - D(NSLog(@"%s - home = %@", __PRETTY_FUNCTION__, home)); - if ( [oP runModalForDirectory: ([prefsFile stringValue] ? [prefsFile stringValue] : home) - file:nil - types:nil] == NSOKButton ) - { - [prefsFile setStringValue: [oP filename] ]; - UserPrefsPath = [[oP filename] UTF8String]; - } -} - -- (IBAction) BrowseROM: (id)sender -{ - NSOpenPanel *oP = [NSOpenPanel openPanel]; - - [oP setCanChooseFiles: YES]; - [oP setTitle: @"Open a ROM file"]; - D(NSLog(@"%s - home = %@", __PRETTY_FUNCTION__, home)); - if ( [oP runModalForDirectory: ([ROMfile stringValue] ? [ROMfile stringValue] : home) - file:nil - types:nil] == NSOKButton ) - { - [ROMfile setStringValue: [oP filename] ]; - PrefsReplaceString("rom", [[oP filename] UTF8String]); - edited = YES; - } -} - -#include // for CDROMRefNum - -- (IBAction) ChangeBootFrom: (NSMatrix *)sender -{ - if ( [sender selectedCell] == (id)bootFromCD ) - { - [disableCD setState: NSOffState]; - - PrefsReplaceInt32("bootdriver", CDROMRefNum); - } - else - PrefsReplaceInt32("bootdriver", 0); - edited = YES; -} - -- (IBAction) ChangeCPU: (NSMatrix *)sender -{ - PrefsReplaceInt32("cpu", [[sender selectedCell] tag]); - edited = YES; -} - -- (IBAction) ChangeDisableCD: (NSButton *)sender -{ - int disabled = [disableCD state]; - - PrefsReplaceBool("nocdrom", disabled); - if ( disabled ) - { - [bootFromAny setState: NSOnState]; - [bootFromCD setState: ![disableCD state]]; - } - edited = YES; -} - -- (IBAction) ChangeDisableSound: (NSButton *)sender -{ - BOOL noSound = [disableSound state]; - - if ( ! noSound ) - WarningSheet(@"Sound is currently unimplemented", panel); - - PrefsReplaceBool("nosound", noSound); - edited = YES; -} - -- (IBAction) ChangeFPU: (NSButton *)sender -{ - PrefsReplaceBool("fpu", [FPU state]); - edited = YES; -} - -- (IBAction) ChangeKeyboard: (NSPopUpButton *)sender -{ - // Deselest current item - int current = [keyboard indexOfItemWithTag: PrefsFindInt32("keyboardtype")]; - if ( current != -1 ) - [[keyboard itemAtIndex: current] setState: FALSE]; - - PrefsReplaceInt32("keyboardtype", [[sender selectedItem] tag]); - edited = YES; -} - -- (IBAction) ChangeModel: (NSMatrix *)sender -{ - PrefsReplaceInt32("modelid", [[sender selectedCell] tag]); - edited = YES; -} - - -// If we are not using the CGIMAGEREF drawing strategy, -// then source bitmaps must be 32bits deep. - -- (short) testWinDepth: (int) newbpp -{ -#ifdef CGIMAGEREF - return newbpp; -#else - if ( newbpp != 32 ) - WarningSheet(@"Sorry - In windowed mode, depth must be 32", panel); - return 32; -#endif -} - -// This is called when the screen/window, -// width, height or depth is clicked. -// -// Note that sender may not actually be an NSMatrix. - -- (IBAction) ChangeScreen: (NSMatrix *)sender -{ - NSButton *cell = [sender selectedCell]; - - short newx = [width intValue]; - short newy = [height intValue]; - short newbpp = [depth intValue]; - short newtype; - char str[20]; - - if ( cell == screen ) - newtype = DISPLAY_SCREEN; - else if ( cell == window ) - newtype = DISPLAY_WINDOW; - else - newtype = display_type; - - // Check that a field actually changed - if ( newbpp == init_depth && newx == init_width && - newy == init_height && newtype == display_type ) - { - D(NSLog(@"No changed GUI items in ChangeScreen")); - return; - } - - // If we are changing type, supply some sensible defaults - - short screenx = CGDisplayPixelsWide(kCGDirectMainDisplay), - screeny = CGDisplayPixelsHigh(kCGDirectMainDisplay), - screenb = CGDisplayBitsPerPixel(kCGDirectMainDisplay); - - if ( newtype != display_type ) - { - D(NSLog(@"Changing display type in ChangeScreen")); - - // If changing to full screen, supply main screen dimensions as a default - if ( newtype == DISPLAY_SCREEN ) - newx = screenx, newy = screeny, newbpp = screenb; - - // If changing from full screen, use minimum screen resolutions - if ( display_type == DISPLAY_SCREEN ) - { - newx = MIN_WIDTH, newy = MIN_HEIGHT; - newbpp = [self testWinDepth: newbpp]; - } - } - else - { - newbpp = [self testWinDepth: newbpp]; - - // Check size is within ranges of MIN_WIDTH ... MAX_WIDTH - // and MIN_HEIGHT ... MAX_HEIGHT - // ??? - } - - [width setIntValue: newx]; - [height setIntValue: newy]; - [depth setIntValue: newbpp]; - - - // Store new prefs - *str = '\0'; - switch ( newtype ) - { - case DISPLAY_WINDOW: - if ( newbpp ) - sprintf(str, "win/%hd/%hd/%hd", newx, newy, newbpp); - else - sprintf(str, "win/%hd/%hd", newx, newy); - break; - case DISPLAY_SCREEN: - if ( newbpp ) - sprintf(str, "full/%hd/%hd/%hd", newx, newy, newbpp); - else - sprintf(str, "full/%hd/%hd", newx, newy); - break; - }; - PrefsReplaceString("screen", str); - - parse_screen_prefs(str); - - edited = YES; - - if ( display_type != DISPLAY_SCREEN ) - { - D(NSLog(@"Display type is not SCREEN (%d), resizing window", - display_type)); - resizeWinTo(newx, newy); - } -} - -- (IBAction) CreateVolume: (id)sender -{ - NSSavePanel *sP = [NSSavePanel savePanel]; - - [sP setAccessoryView: newVolumeView]; - [sP setPrompt: @"Create"]; - [sP setTitle: @"Create new volume as"]; - - if ( [sP runModalForDirectory:NSHomeDirectory() file:@"basilisk-II.vol"] == NSOKButton ) - { - char cmd[1024]; - const char *filename = [[sP filename] UTF8String]; - int retVal, - size = [newVolumeSize intValue]; - - sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", filename, size); - - retVal = system(cmd); - if (retVal != 0) - { - NSString *details = [NSString stringWithFormat: - @"The dd command failed.\nReturn status %d (%s)", - retVal, strerror(errno)]; - WarningSheet(@"Unable to create volume", details, nil, panel); - } - else - { - [volsDS addObject: (NSObject *) blank - withPath: [sP filename] ]; - PrefsAddString("disk", filename); - [diskImages reloadData]; - } - } -} - -- (BOOL) fileManager: (NSFileManager *) manager -shouldProceedAfterError: (NSDictionary *) errorDict -{ - NSRunAlertPanel(@"File operation error", - @"%@ %@, toPath %@", - @"Bugger!", nil, nil, - [errorDict objectForKey:@"Error"], - [errorDict objectForKey:@"Path"], - [errorDict objectForKey:@"ToPath"]); - return NO; -} - -- (IBAction) DeleteVolume: (id)sender -{ - NSString *Path = [self RemoveVolumeEntry]; - - if ( ! Path ) - return; - - if ( ! [[NSFileManager defaultManager] removeFileAtPath: Path - handler: self] ) - { - WarningSheet(@"Unable to delete volume", panel); - NSLog(@"%s unlink(%s) failed - %s", __PRETTY_FUNCTION__, - [Path cString], strerror(errno)); - } -} - -- (IBAction) EditDelay: (NSTextField *)sender -{ - int ticks = [delay intValue]; - float freq; - - if ( ticks ) - freq = 60.0 / ticks; - else - freq = 60.0; - - [frequency setFloatValue: freq]; - [emuFreq setFloatValue: freq]; - PrefsReplaceInt32("frameskip", ticks); - edited = YES; -} - -- (IBAction) EditBytes: (NSTextField *)sender -{ - int B = (int) [bytes floatValue]; - float M = B / 1024 / 1024; - - D(NSLog(@"%s = %f %d", __PRETTY_FUNCTION__, M, B)); - PrefsReplaceInt32("ramsize", B); - [MB setFloatValue: M]; - edited = YES; -} - -- (IBAction) EditEtherNetDevice: (NSTextField *)sender -{ - NSString *path = [etherNet stringValue]; - - PrefsReplaceString("ether", [path UTF8String]); - edited = YES; -} - -- (IBAction) EditExtFS: (NSTextField *)sender -{ - NSString *path = [extFS stringValue]; - - PrefsReplaceString("extfs", [path UTF8String]); - edited = YES; -} - -- (IBAction) EditFrequency: (NSTextField *)sender -{ - float freq = [frequency floatValue]; - - [delay setIntValue: frequencyToTickDelay(freq)]; - [emuFreq setFloatValue: freq]; - edited = YES; -} - -- (IBAction) EditModemDevice: (NSTextField *)sender -{ - NSString *path = [modem stringValue]; - - PrefsReplaceString("seriala", [path UTF8String]); - edited = YES; -} - -- (IBAction) EditMB: (NSTextField *)sender -{ - float M = [MB floatValue]; - int B = (int) (M * 1024 * 1024); - - D(NSLog(@"%s = %f %d", __PRETTY_FUNCTION__, M, B)); - PrefsReplaceInt32("ramsize", B); - [bytes setIntValue: B]; - edited = YES; -} - -- (IBAction) EditPrinterDevice: (NSTextField *)sender -{ - NSString *path = [printer stringValue]; - - PrefsReplaceString("serialb", [path UTF8String]); - edited = YES; -} - -- (IBAction) EditROMpath: (NSTextField *)sender -{ - NSString *path = [ROMfile stringValue]; - - PrefsReplaceString("rom", [path UTF8String]); -} - -- (IBAction) RemoveSCSI: (id)sender -{ - char pref[6]; - int row = [SCSIdisks selectedRow], - SCSIid = [SCSIds intAtRow: row]; - - if ( ! [SCSIds deleteRow: row] ) - NSLog (@"%s - [SCSIds deleteRow: %d] failed", __PRETTY_FUNCTION__, row); - [SCSIdisks reloadData]; - sprintf(pref, "scsi%d", SCSIid); - //PrefsRemoveItem(pref,0); - PrefsRemoveItem(pref, 1); -} - -- (NSString *) RemoveVolumeEntry -{ - int row = [diskImages selectedRow]; - - if ( row != -1 ) - { - NSString *Path = [volsDS pathAtRow: row]; - const char *path = [Path UTF8String], - *str; - int tmp = 0; - - NSString *prompt = [NSString stringWithFormat: @"%s\n%s", - "Are you sure you want to delete the file", - path]; - - if ( ! ChoiceAlert([prompt cString], "Delete", "Cancel") ) - return NULL; - - while ( (str = PrefsFindString("disk", tmp) ) != NULL ) - { - if ( strcmp(str, path) == 0 ) - { - PrefsRemoveItem("disk", tmp); - D(NSLog(@"%s - Deleted prefs entry \"disk\", %d", - __PRETTY_FUNCTION__, tmp)); - edited = YES; - break; - } - ++tmp; - } - - if ( str == NULL ) - { - NSLog(@"%s - Couldn't find any disk preference to match %s", - __PRETTY_FUNCTION__, path); - return NULL; - } - - if ( ! [volsDS deleteRow: row] ) - NSLog (@"%s - RemoveVolume %d failed", __PRETTY_FUNCTION__, tmp); - [diskImages reloadData]; -// return path; - return Path; - } - else - { - WarningSheet(@"Please select a volume first", panel); - return NULL; - } -} - -- (IBAction) RemoveVolume: (id)sender -{ - [self RemoveVolumeEntry]; -} - -- (void) loadPrefs: (int) argc - args: (char **) argv -{ - [panel close]; // Temporarily hide preferences panel - - PrefsExit(); // Purge all the old pref values - - PrefsInit(NULL, argc, argv); - AddPrefsDefaults(); - AddPlatformPrefsDefaults(); // and only create basic ones - - [SCSIds deleteAll]; // Clear out datasources for the tables - [volsDS deleteAll]; - - [self ShowPrefs: self]; // Reset items in panel, and redisplay - edited = NO; -} - -- (IBAction) LoadPrefs: (id)sender -{ - int argc = 2; - char *argv[2]; - - argv[0] = "--prefs", - argv[1] = (char *) [[prefsFile stringValue] UTF8String]; - - [self loadPrefs: argc - args: argv]; -} - -- (IBAction) ResetPrefs: (id)sender -{ - [self loadPrefs: 0 - args: NULL]; -} - -- (void) setStringOf: (NSTextField *) field - fromPref: (const char *) prefName -{ - const char *value = PrefsFindString(prefName, 0); - - if ( value ) - [field setStringValue: [NSString stringWithUTF8String: value] ]; -} - -- (IBAction) SavePrefs: (id)sender -{ - SavePrefs(); - edited = NO; -} - -- (IBAction) ShowPrefs: (id)sender -{ - NSTableColumn *locks; - const char *str; - int cpu, tmp, val; - - - // Set simple single field items - - val = PrefsFindInt32("frameskip"); - [delay setIntValue: val]; - if ( val ) - [frequency setFloatValue: 60.0 / val]; - else - [frequency setFloatValue: 60.0]; - - val = PrefsFindInt32("ramsize"); - [bytes setIntValue: val]; - [MB setFloatValue: val / (1024.0 * 1024.0)]; - - [disableCD setState: PrefsFindBool("nocdrom")]; - [disableSound setState: PrefsFindBool("nosound")]; - [FPU setState: PrefsFindBool("fpu") ]; - - [self setStringOf: etherNet fromPref: "ether" ]; - [self setStringOf: extFS fromPref: "extfs" ]; - [self setStringOf: modem fromPref: "seriala"]; - [self setStringOf: printer fromPref: "serialb"]; - [self setStringOf: ROMfile fromPref: "rom"]; - - [prefsFile setStringValue: [NSString stringWithUTF8String: UserPrefsPath.c_str()] ]; - - - parse_screen_prefs(PrefsFindString("screen")); - - [width setIntValue: init_width]; - [height setIntValue: init_height]; - [depth setIntValue: init_depth]; - - [screen setState: NO]; - switch ( display_type ) - { - case DISPLAY_WINDOW: [window setState: YES]; break; - case DISPLAY_SCREEN: [screen setState: YES]; break; - } - - [newVolumeSize setIntValue: 10]; - - // Radio button groups: - - val = PrefsFindInt32("bootdriver"); - [bootFromAny setState: val != CDROMRefNum]; - [bootFromCD setState: val == CDROMRefNum]; - - cpu = PrefsFindInt32("cpu"); - val = PrefsFindInt32("modelid"); - -#if REAL_ADDRESSING || DIRECT_ADDRESSING - puts("Current memory model does not support 24bit addressing"); - if ( val == [classic tag] ) - { - // Window already created by NIB file, just display - [panel makeKeyAndOrderFront:self]; - WarningSheet(@"Compiled-in memory model does not support 24bit", - @"Disabling Mac Classic emulation", nil, panel); - cpu = [CPU68030 tag]; - PrefsReplaceInt32("cpu", cpu); - val = [IIci tag]; - PrefsReplaceInt32("modelid", val); - } - - puts("Disabling 68000 & Mac Classic buttons"); - [CPU68000 setEnabled:FALSE]; - [classic setEnabled:FALSE]; -#endif - - [CPU68000 setState: [CPU68000 tag] == cpu]; - [CPU68020 setState: [CPU68020 tag] == cpu]; - [CPU68030 setState: [CPU68030 tag] == cpu]; - [CPU68040 setState: [CPU68040 tag] == cpu]; - - [classic setState: [classic tag] == val]; - [IIci setState: [IIci tag] == val]; - [quadra900 setState: [quadra900 tag] == val]; - - - // Lists of thingies: - - val = PrefsFindInt32("keyboardtype"); - tmp = [keyboard indexOfItemWithTag: val]; - if ( tmp != -1 ) - [keyboard selectItemAtIndex: tmp]; - for ( tmp = 0; tmp < [keyboard numberOfItems]; ++tmp ) - { - NSMenuItem *type = [keyboard itemAtIndex: tmp]; - [type setState: [type tag] == val]; - } - - - for ( tmp = 0; tmp < 7; ++tmp) - { - char pref[6]; - - pref[0] = '\0'; - - sprintf (pref, "scsi%d", tmp); - if ( (str = PrefsFindString(pref, 0) ) ) - [SCSIds addInt: tmp - withPath: [NSString stringWithCString: str] ]; - } - - [SCSIdisks setDataSource: SCSIds]; - - locks = [diskImages tableColumnWithIdentifier: @"locked"]; - if ( locks == nil ) - NSLog (@"%s - Can't find column for lock images", __PRETTY_FUNCTION__); - [locks setDataCell: lockCell]; - - tmp = 0; - while ( (str = PrefsFindString("disk", tmp++) ) != NULL ) - { - if ( *str == '*' ) - [volsDS addObject: (NSObject *) locked - withPath: [NSString stringWithUTF8String: str+1]]; - else - [volsDS addObject: (NSObject *) blank - withPath: [NSString stringWithUTF8String: str]]; - } - - [diskImages setDataSource: volsDS]; - - - [panel makeKeyAndOrderFront:self]; // Window already created by NIB file, just display -} - -@end diff --git a/BasiliskII/src/MacOSX/ToDo.html b/BasiliskII/src/MacOSX/ToDo.html deleted file mode 100644 index d4b4f66d..00000000 --- a/BasiliskII/src/MacOSX/ToDo.html +++ /dev/null @@ -1,61 +0,0 @@ - -Bugs: -
    -
  • In window mode, if the framerate is low (e.g. if you leave it at the - default of 10fps) or if the emulated screen is too large, - really fast mouse clicks are sometimes not picked up - by the Emulator. For now, click more slowly
  • -
  • In full screen mode after a restart, when the mouse is first moved, - the emulated pointer jumps to the location that it was before the restart. - Disturbing, but not damaging.
  • -
  • Ejecting a CD only works in 10.2 or higher, and it freezes the emulation - for about 5 seconds.
  • -
  • Status of 'dd' command is not always correct. (If it runs out of space, - an error about file not found is printed?)
  • -
  • The Snapshot function is currently broken in some situations - (if the emulation changes its own screen settings, and the program - is compiled with the default window drawing mode of CGIMAGEREF). - Setting the depth to millions (in the emulator) is a workaround for now
  • -
  • Cut and paste between emulator and OS X only half works
  • -
-Untested: -
    -
  • Mac Classic emulation. I don't have a ROM, but I suspect it will crash
  • -
  • Serial port code
  • -
-Unimplemented: -
    -
  • CD audio stuff. I am still trying to get this to work
  • -
  • CD insert detection. At the moment, if a CD isn't there when the - emulator boots, or if you change CDs, it will never know. I don't - know how to register with the OS for disk insertion and mount events. - (Gwenolé rewrote the CD code, and it should poll for new disks, - but it don't work for me. I must be doing something wrong!)
  • -
  • Floppy stuff. If a floppy is mounted by the OS X Finder, - it is busy and cannot be opened by the emulator
  • -
  • Interrupt function for emulator
  • -
  • 'nogui' to disable GUI alerts (and maybe preferences, but I need to split - MainMenu.nib to do that)
  • -
-Possible Enhancements: -
    -
  • Use NSFileManager's movePath:toPath:handler to rename all a file's forks - in extfs_macosx.mm
  • -
  • Emulator snapshot - save the current emulator state - (memory + registers) to a file for fast startup next time
  • -
  • Multiple emulators. The window stuff is mostly there, - but the uae_cpu code has lots of globals, and is not re-entrant
  • -
  • Real addressing mode for the emulator. Mike Sliczniak had done most of the - work, but with real addressing the emulator just crashes for me
  • -
  • Improve Objective-C object allocation. e.g. http://www.mulle-kybernetik.com/artikel/Optimisation/opti-5.html
  • -
  • Use automake instead of the current 1_prepare_files.sh ?
  • -
  • Add JIT options to preferences?
  • -
  • Use internal windows to display Help doco?
  • -
  • Provide feedback during external commands (e.g. ejecting a CD or - creating a disk volume)
  • -
  • Widescreen window layout (suggestion by Michael Franz), so that users - with widescreen displays can squeeze a bigger emulated screen in. - I have a mock up of this that can be pasted in (MainMenu.nib). - Ideally, this would be via a generalised "theme" facility, - but who has time for that :-)
  • -
diff --git a/BasiliskII/src/MacOSX/Versions.html b/BasiliskII/src/MacOSX/Versions.html deleted file mode 100644 index 9486ef74..00000000 --- a/BasiliskII/src/MacOSX/Versions.html +++ /dev/null @@ -1,120 +0,0 @@ - -Versions of MacOS X port of Basilisk II: -
    -
  1. Initial port to Public Beta, made minor changes to get it to compile under Final Release. -
    Gave a copy of this version to Gwenolé Beauchesne (one of the other porters)
  2. -
  3. Ported to version 0.9 of the Basilisk II tarball. -
    Re-engineered autoconfig files to give a clean autoconf and make of cpu_uae code. -
    Fixed a bug in the EmulatorView class (I was customising release instead of dealloc). -
    Added: -
      -
    • Transparency to icon
    • -
    • Port-specific doco: 0_HOW_TO_BUILD.txt, ToDo.html and Versions.html
    • -
    • Screen Snapshot code
    • -
    • Preferences saving and resetting
    • -
    • Delegate code, called when user attempts to close emulator window or quit application, - to check whether preferences need saving or application should be allowed to quit
    • -
    • ExtFS resource and type/creator access code
    • -
    • Window resizing stuff: -
        -
      1. The screensize can be set in the preferences. If the emulator has yet to - start then the window and emulator screen is resized. Otherwise, and
      2. -
      3. At any time, the window can be resized, which scales the emulator screen image
      4. -
      -
    • -
    - Gave a copy of this to Max Horn
  4. -
  5. Some code fixes suggested by Max, doco updates, and porting to OS 10.1
  6. -
  7. Event handling re-write inspired by Max (subclassing NSApplication for custom sendEvent:). - Command key and double clicks are now passed correctly to the Emulator. Took out the custom - "About" window stuff, and added some credits (with an html link to the official Basilisk home - page) in the standard About box. Also has the standard README in the help menu. -
    Gave a copy to Max
  8. -
  9. Streamlining of event sending (filter mouseMoved events when not in Emulator screen)
  10. -
  11. Recompile in Project Builder, because the makefile generated binary dies at startup
  12. -
  13. Ported to the Basilisk II 1.0 snapshot's source and implemented video resolution switching. - Also uses Objective-C++, which eliminates some of the wrapper code which was previously needed.
  14. -
  15. Video preferences fixes, small tidyup of source.
  16. -
  17. Full screen mode added, more source tidied up.
  18. - -
  19. Finally checked into CVS repository. Key event bug fixes: -
      -
    • Cursor keys are now decoded and passed to the Emulator correctly
    • -
    • New one (in version 9) reported by Kentaro Nakatani - - full screen mode was not passing key events
    • -
  20. -
  21. Repaired help menu item, added documentation folder.
  22. -
  23. Several monitor resolution-changing fixes. Windowed mode now supports all depths, - and is up to 6 times faster. I now no longer have any plans to do an OpenGL mode. -
    Minor change in preferences (RAM size fields no longer require - the user to press return or enter for the value to "take"). -
    Some modifications for compilation on 10.2 and 10.1 -
    Initial CD-ROM reading code.
  24. -
  25. Restarting the emulator should be safe and fairly reliable, - and errors in starting the emulator should now be caught. -
    Resizing of window is now animated, and window is centred afterwards. -
    Reduced memory leaks when changing screensize in windowed mode. -
    Screen default pref is now Mac II (and not Classic) size. -
    Fixed: -
      -
    • Bug where the Prefs could not be edited while the emulator was running
    • -
    • Help menu item (again) and added extra doco there
    • -
    • Preferences RAM size thing (again)
    • -
    • A minor Prefs editor button anomaly
    • -
  26. -
  27. Preferences file can now be specified on the command line, - and changed/loaded in the Preferences editor. - Added a feature from the windows port - now supports different keyboard types. - Changed: -
      -
    • Default extfs; was '/', now user's home directory (Suggestion by Olaf Pluta. - Seeing all the Unix dirs is a bit scary!)
    • -
    • HowTo now displayed by default web browser (as it contains links)
    • -
    • Project Builder defaults so that debug symbols are not included
    • -
  28. -
  29. Now built on 10.3 and Xcode. Also adds: -
      -
    • Xcode project files
    • -
    • Initial floppy and serial port locating code
    • -
    • Some help labels on the buttons - (some users didn't understand what the triangle button meant)
    • -
    • Signal handling for crash protection - (thanks to Mike Sliczniak's hard work)
    • -
    -
  30. -
  31. Now distributed as two applications; the usual one (which should be faster), - and one for emulating a Mac Classic (which may also help the 10.2/10.3 users - who are having problems with a black screen at startup). The difference is - that the "classic" version uses virtual or "banks" memory addressing. - Fixed: -
      -
    • Loading of ROM or disk images from directories or filenames which - contain non-ASCII characters
    • -
    • Floppy locating code. It can't actually access a floppy, but at - least it now won't add the cdrom multiple times
    • -
    -
  32. -
  33. Working ethernet, without extra drivers, thanks to Gwenolé. -
    Lots of bug fixes by Bernie Zenis. Some 10.4 fixes by Kirk Kerekes. -
    Some fixes by Marcus Gail ( 'Boot From: CD-ROM' vs - 'Disable CD-ROM Driver' clash). -
    Some cosmetic changes (widened RAM MB in prefs, added confirmation - when deleting volumes). -
    Now no need for "classic" version - - Gwenolé fixed the black screen problem
  34. -
  35. (actually 18a) Minor fixes: -
      -
    • Mouse should always woork in fullscreen mode, and
    • -
    • If snapshot fails, the dialog makes a workaround suggestion
    • -
    -
  36. -
  37. Updated the HowTo, external filesystem fix on 10.4, CD code rewrite. - Added some new features: -
      -
    • Sound support by Daniel Sumorok! Thanks also to Dave Vasilevsky, - who produced earlier versions of sound code that I didn't use.
    • -
    • Cut & Paste support from Gwenolé. You can now paste from the OS X - clipboard into the emulator (pasting the other way doesn't work - for me yet)
    • -
    -
diff --git a/BasiliskII/src/MacOSX/audio_defs_macosx.h b/BasiliskII/src/MacOSX/audio_defs_macosx.h deleted file mode 100644 index dc37fb42..00000000 --- a/BasiliskII/src/MacOSX/audio_defs_macosx.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * $Id$ - * - * audio_defs_macosx.h - Work around clashes with the enums in - * Based on: - * - * audio_defs.h - Definitions for MacOS audio components - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef AUDIO_DEFS_H -#define AUDIO_DEFS_H - -#include "macos_util_macosx.h" - -enum { // ComponentResource struct - componentType = 0, - componentSubType = 4, - componentManufacturer = 8, - componentFlags = 12, - componentFlagsMask = 16, - componentResType = 20, - componentResID = 24, - componentNameType = 26, - componentNameID = 30, - componentInfoType = 32, - componentInfoID = 36, - componentIconType = 38, - componentIconID = 42, - componentVersion = 44, - componentRegisterFlags = 48, - componentIconFamily = 52, - componentPFCount = 54, - componentPFFlags = 58, - componentPFResType = 62, - componentPFResID = 66, - componentPFPlatform = 68 -}; - - -enum { // ComponentParameters struct - cp_flags = 0, // call modifiers: sync/async, deferred, immed, etc - cp_paramSize = 1, // size in bytes of actual parameters passed to this call - cp_what = 2, // routine selector, negative for Component management calls - cp_params = 4 // actual parameters for the indicated routine -}; - -enum { // SoundComponentData struct - scd_flags = 0, - scd_format = 4, - scd_numChannels = 8, - scd_sampleSize = 10, - scd_sampleRate = 12, - scd_sampleCount = 16, - scd_buffer = 20, - scd_reserved = 24, - SIZEOF_scd = 28 -}; - -enum { // SoundInfoList struct - sil_count = 0, - sil_infoHandle = 2 -}; - -#endif diff --git a/BasiliskII/src/MacOSX/audio_macosx.cpp b/BasiliskII/src/MacOSX/audio_macosx.cpp deleted file mode 100644 index 840d2f13..00000000 --- a/BasiliskII/src/MacOSX/audio_macosx.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* - * audio_macosx.cpp - Audio support, implementation Mac OS X - * Copyright (C) 2006, Daniel Sumorok - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "audio.h" -#include "audio_defs.h" -#include "MacOSX_sound_if.h" - -#define DEBUG 0 -#include "debug.h" - - -// The currently selected audio parameters (indices in -// audio_sample_rates[] etc. vectors) -static int audio_sample_rate_index = 0; -static int audio_sample_size_index = 0; -static int audio_channel_count_index = 0; - -// Prototypes -static OSXsoundOutput *soundOutput = NULL; -static bool main_mute = false; -static bool speaker_mute = false; - -/* - * Initialization - */ -static int audioInt(void); - -static bool open_audio(void) -{ - AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index]; - AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index]; - AudioStatus.channels = audio_channel_counts[audio_channel_count_index]; - - if (soundOutput) - delete soundOutput; - - soundOutput = new OSXsoundOutput(); - soundOutput->start(AudioStatus.sample_size, AudioStatus.channels, - AudioStatus.sample_rate >> 16); - soundOutput->setCallback(audioInt); - audio_frames_per_block = soundOutput->bufferSizeFrames(); - - audio_open = true; - return true; -} - -void AudioInit(void) -{ - // Sound disabled in prefs? Then do nothing - if (PrefsFindBool("nosound")) - return; - - //audio_sample_sizes.push_back(8); - audio_sample_sizes.push_back(16); - - audio_channel_counts.push_back(1); - audio_channel_counts.push_back(2); - - audio_sample_rates.push_back(11025 << 16); - audio_sample_rates.push_back(22050 << 16); - audio_sample_rates.push_back(44100 << 16); - - // Default to highest supported values - audio_sample_rate_index = audio_sample_rates.size() - 1; - audio_sample_size_index = audio_sample_sizes.size() - 1; - audio_channel_count_index = audio_channel_counts.size() - 1; - - AudioStatus.mixer = 0; - AudioStatus.num_sources = 0; - audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; - audio_component_flags = 0; - - open_audio(); -} - - -/* - * Deinitialization - */ - -static void close_audio(void) -{ - D(bug("Closing Audio\n")); - - if (soundOutput) - { - delete soundOutput; - soundOutput = NULL; - } - - audio_open = false; -} - -void AudioExit(void) -{ - // Close audio device - close_audio(); -} - - -/* - * First source added, start audio stream - */ - -void audio_enter_stream() -{ - // Streaming thread is always running to avoid clicking noises -} - - -/* - * Last source removed, stop audio stream - */ - -void audio_exit_stream() -{ - // Streaming thread is always running to avoid clicking noises -} - - -/* - * MacOS audio interrupt, read next data block - */ - -void AudioInterrupt(void) -{ - D(bug("AudioInterrupt\n")); - uint32 apple_stream_info; - uint32 numSamples; - int16 *p; - M68kRegisters r; - - if (!AudioStatus.mixer) - { - numSamples = 0; - soundOutput->sendAudioBuffer((void *)p, (int)numSamples); - D(bug("AudioInterrupt done\n")); - return; - } - - // Get data from apple mixer - r.a[0] = audio_data + adatStreamInfo; - r.a[1] = AudioStatus.mixer; - Execute68k(audio_data + adatGetSourceData, &r); - D(bug(" GetSourceData() returns %08lx\n", r.d[0])); - - apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (apple_stream_info && (main_mute == false) && (speaker_mute == false)) - { - numSamples = ReadMacInt32(apple_stream_info + scd_sampleCount); - p = (int16 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)); - } - else - { - numSamples = 0; - p = NULL; - } - - soundOutput->sendAudioBuffer((void *)p, (int)numSamples); - - D(bug("AudioInterrupt done\n")); -} - - -/* - * Set sampling parameters - * "index" is an index into the audio_sample_rates[] etc. vectors - * It is guaranteed that AudioStatus.num_sources == 0 - */ - -bool audio_set_sample_rate(int index) -{ - close_audio(); - audio_sample_rate_index = index; - return open_audio(); -} - -bool audio_set_sample_size(int index) -{ - close_audio(); - audio_sample_size_index = index; - return open_audio(); -} - -bool audio_set_channels(int index) -{ - close_audio(); - audio_channel_count_index = index; - return open_audio(); -} - -/* - * Get/set volume controls (volume values received/returned have the - * left channel volume in the upper 16 bits and the right channel - * volume in the lower 16 bits; both volumes are 8.8 fixed point - * values with 0x0100 meaning "maximum volume")) - */ -bool audio_get_main_mute(void) -{ - return main_mute; -} - -uint32 audio_get_main_volume(void) -{ - return 0x01000100; -} - -bool audio_get_speaker_mute(void) -{ - return speaker_mute; -} - -uint32 audio_get_speaker_volume(void) -{ - return 0x01000100; -} - -void audio_set_main_mute(bool mute) -{ - main_mute = mute; -} - -void audio_set_main_volume(uint32 vol) -{ -} - -void audio_set_speaker_mute(bool mute) -{ - speaker_mute = mute; -} - -void audio_set_speaker_volume(uint32 vol) -{ -} - -static int audioInt(void) -{ - SetInterruptFlag(INTFLAG_AUDIO); - TriggerInterrupt(); - return 0; -} diff --git a/BasiliskII/src/MacOSX/autorelease.h b/BasiliskII/src/MacOSX/autorelease.h deleted file mode 100644 index c89cb100..00000000 --- a/BasiliskII/src/MacOSX/autorelease.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * autorelease.h - a macro wrapping autorelease pools for use with Objective-C++ source files. - * - * Expands to @autoreleasepool on clang, uses a little hack to emulate @autoreleasepool on gcc. - * - * (C) 2012 Charles Srstka - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import - -#ifndef __Autorelease_H__ -#define __Autorelease_H__ - -// just a little forward compatibility in case we ever support LLVM/clang -#if __clang__ -#define AUTORELEASE_POOL @autoreleasepool -#else -class Autorelease_Pool_Wrapper { -public: - Autorelease_Pool_Wrapper() { m_pool = [[NSAutoreleasePool alloc] init]; } - ~Autorelease_Pool_Wrapper() { [m_pool drain]; } - operator bool() const { return true; } -private: - NSAutoreleasePool *m_pool; -}; - -#define POOL_NAME(x, y) x##_##y -#define POOL_NAME2(x, y) POOL_NAME(x, y) -#define AUTORELEASE_POOL if(Autorelease_Pool_Wrapper POOL_NAME2(pool, __LINE__) = Autorelease_Pool_Wrapper()) -#endif // !__clang__ - -#endif // __Autorelease_H__ diff --git a/BasiliskII/src/MacOSX/clip_macosx.cpp b/BasiliskII/src/MacOSX/clip_macosx.cpp deleted file mode 100644 index 1d37edfc..00000000 --- a/BasiliskII/src/MacOSX/clip_macosx.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * clip_macosx.cpp - Clipboard handling, MacOS X (Carbon) implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#define _UINT64 -#include - -#include "clip.h" -#include "main.h" -#include "cpu_emulation.h" -#include "emul_op.h" - -#define DEBUG 0 -#include "debug.h" - - -// Flag for PutScrap(): the data was put by GetScrap(), don't bounce it back to the MacOS X side -static bool we_put_this_data = false; - - -static void SwapScrapData(uint32 type, void *data, int32 length, int from_host) { -#if BYTE_ORDER != BIG_ENDIAN - if (type == kScrapFlavorTypeTextStyle) { - uint16 *sdata = (uint16 *) data; - // the first short stores the number of runs - uint16 runs = sdata[0]; - sdata[0] = htons(sdata[0]); - if (from_host) - runs = sdata[0]; - sdata++; - // loop through each run - for (int i = 0; i < runs; i++) { - struct style_data { - uint32 offset; - uint16 line_height; - uint16 line_ascent; - uint16 font_family; - uint16 character_style; // not swapped - uint16 point_size; - uint16 red; - uint16 green; - uint16 blue; - } *style = (struct style_data *) (sdata + i*10); - style->offset = htonl(style->offset); - style->line_height = htons(style->line_height); - style->line_ascent = htons(style->line_ascent); - style->font_family = htons(style->font_family); - style->point_size = htons(style->point_size); - style->red = htons(style->red); - style->green = htons(style->green); - style->blue = htons(style->blue); - } - } else { - // add byteswapping code for other flavor types here ... - } -#endif -} - - -/* - * Initialization - */ - -void ClipInit(void) -{ -} - - -/* - * Deinitialization - */ - -void ClipExit(void) -{ -} - - -/* - * Mac application reads clipboard - */ - -void GetScrap(void **handle, uint32 type, int32 offset) -{ -#if defined(__LP64__) - D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset)); - #warning Carbon scrapbook function are not implemented in 64-bit mode -#else - D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset)); - ScrapRef theScrap; - - if (GetCurrentScrap(&theScrap) != noErr) { - D(bug(" could not open scrap\n")); - return; - } - - Size byteCount; - if (GetScrapFlavorSize(theScrap, type, &byteCount) == noErr) { - - // Allocate space for new scrap in MacOS side - M68kRegisters r; - r.d[0] = byteCount; - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32 scrap_area = r.a[0]; - - // Get the native clipboard data - if (scrap_area) { - uint8 * const data = Mac2HostAddr(scrap_area); - if (GetScrapFlavorData(theScrap, type, &byteCount, data) == noErr) { - SwapScrapData(type, data, byteCount, FALSE); - // Add new data to clipboard - static uint8 proc[] = { - 0x59, 0x8f, // subq.l #4,sp - 0xa9, 0xfc, // ZeroScrap() - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #length,-(sp) - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #type,-(sp) - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #outbuf,-(sp) - 0xa9, 0xfe, // PutScrap() - 0x58, 0x8f, // addq.l #4,sp - M68K_RTS >> 8, M68K_RTS & 0xff - }; - r.d[0] = sizeof(proc); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32 proc_area = r.a[0]; - - if (proc_area) { - Host2Mac_memcpy(proc_area, proc, sizeof(proc)); - WriteMacInt32(proc_area + 6, byteCount); - WriteMacInt32(proc_area + 12, type); - WriteMacInt32(proc_area + 18, scrap_area); - we_put_this_data = true; - Execute68k(proc_area, &r); - - r.a[0] = proc_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - } - } - - r.a[0] = scrap_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - } - } -#endif -} - -/* - * ZeroScrap() is called before a Mac application writes to the clipboard; clears out the previous contents - */ - -void ZeroScrap() -{ - D(bug("ZeroScrap\n")); - - we_put_this_data = false; -} - -/* - * Mac application wrote to clipboard - */ - -void PutScrap(uint32 type, void *scrap, int32 length) -{ -#if defined(__LP64__) - #warning Carbon scrapbook function are not implemented in 64-bit mode - D(bug("PutScrap type %4.4s, data %08lx, length %ld\n", &type, scrap, length)); -#else - static bool clear = true; - D(bug("PutScrap type %4.4s, data %08lx, length %ld\n", &type, scrap, length)); - ScrapRef theScrap; - - if (we_put_this_data) { - we_put_this_data = false; - clear = true; - return; - } - if (length <= 0) - return; - - if (clear) { - D(bug(" calling ClearCurrentScrap\n")); - ClearCurrentScrap(); - } - if (GetCurrentScrap(&theScrap) != noErr) { - D(bug(" could not open scrap\n")); - return; - } - - SwapScrapData(type, scrap, length, TRUE); - if (PutScrapFlavor(theScrap, type, kScrapFlavorMaskNone, length, scrap) != noErr) { - D(bug(" could not put to scrap\n")); - //return; - } - SwapScrapData(type, scrap, length, FALSE); // swap it back -#endif -} diff --git a/BasiliskII/src/MacOSX/clip_macosx64.mm b/BasiliskII/src/MacOSX/clip_macosx64.mm deleted file mode 100644 index 23261890..00000000 --- a/BasiliskII/src/MacOSX/clip_macosx64.mm +++ /dev/null @@ -1,1286 +0,0 @@ -/* - * clip_macosx64.mm - Clipboard handling, MacOS X (Pasteboard Manager) implementation - * - * (C) 2012 Jean-Pierre Stierlin - * (C) 2012 Alexei Svitkine - * (C) 2012 Charles Srstka - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#define _UINT64 -#import -#include - -#include "clip.h" -#include "main.h" -#include "cpu_emulation.h" -#include "emul_op.h" -#include "autorelease.h" -#include "pict.h" - -#define DEBUG 0 -#include "debug.h" - -#ifndef FOURCC -#define FOURCC(a,b,c,d) (((uint32)(a) << 24) | ((uint32)(b) << 16) | ((uint32)(c) << 8) | (uint32)(d)) -#endif - -#define TYPE_PICT FOURCC('P','I','C','T') -#define TYPE_TEXT FOURCC('T','E','X','T') -#define TYPE_STYL FOURCC('s','t','y','l') -#define TYPE_UTXT FOURCC('u','t','x','t') -#define TYPE_UT16 FOURCC('u','t','1','6') -#define TYPE_USTL FOURCC('u','s','t','l') -#define TYPE_MOOV FOURCC('m','o','o','v') -#define TYPE_SND FOURCC('s','n','d',' ') -#define TYPE_ICNS FOURCC('i','c','n','s') - -static NSPasteboard *g_pboard; -static NSInteger g_pb_change_count = 0; - -// Flag for PutScrap(): the data was put by GetScrap(), don't bounce it back to the MacOS X side -static bool we_put_this_data = false; - -static bool should_clear = false; - -static NSMutableDictionary *g_macScrap; - -// flavor UTIs - -static NSString * const UTF16_TEXT_FLAVOR_NAME = @"public.utf16-plain-text"; -static NSString * const TEXT_FLAVOR_NAME = @"com.apple.traditional-mac-plain-text"; -static NSString * const STYL_FLAVOR_NAME = @"net.cebix.basilisk.styl-data"; - -// font face types - -enum { - FONT_FACE_PLAIN = 0, - FONT_FACE_BOLD = 1, - FONT_FACE_ITALIC = 2, - FONT_FACE_UNDERLINE = 4, - FONT_FACE_OUTLINE = 8, - FONT_FACE_SHADOW = 16, - FONT_FACE_CONDENSED = 32, - FONT_FACE_EXTENDED = 64 -}; - -// Script Manager constants - -#define smRoman 0 -#define smMacSysScript 18 -#define smMacRegionCode 40 - -static NSString *UTIForFlavor(uint32_t type) -{ - switch (type) { - case TYPE_MOOV: - return (NSString *)kUTTypeQuickTimeMovie; - case TYPE_SND: - return (NSString *)kUTTypeAudio; - case TYPE_ICNS: - return (NSString *)kUTTypeAppleICNS; - default: { - CFStringRef typeString = UTCreateStringForOSType(type); - NSString *uti = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, typeString, NULL); - - CFRelease(typeString); - - if (uti == nil || [uti hasPrefix:@"dyn."]) { - // The docs threaten that this may stop working at some unspecified point in the future. - // However, it seems to work on Lion and Mountain Lion, and there's no other way to do this - // that I can see. Most likely, whichever release eventually breaks this will probably also - // drop support for the 32-bit applications which typically use these 32-bit scrap types anyway, - // making it irrelevant. When this happens, we should include a version check for the version of - // OS X that dropped this support, and leave uti alone in that case. - - [uti release]; - uti = [[NSString alloc] initWithFormat:@"CorePasteboardFlavorType 0x%08x", type]; - } - - return [uti autorelease]; - } - } -} - -static uint32_t FlavorForUTI(NSString *uti) -{ - CFStringRef typeTag = UTTypeCopyPreferredTagWithClass((CFStringRef)uti, kUTTagClassOSType); - - if (!typeTag) - return 0; - - uint32_t type = UTGetOSTypeFromString(typeTag); - - CFRelease(typeTag); - - return type; -} - -/* - * Get current system script encoding on Mac - */ - -static int GetMacScriptManagerVariable(uint16_t varID) -{ - int ret = -1; - M68kRegisters r; - static uint8_t proc[] = { - 0x59, 0x4f, // subq.w #4,sp - 0x3f, 0x3c, 0x00, 0x00, // move.w #varID,-(sp) - 0x2f, 0x3c, 0x84, 0x02, 0x00, 0x08, // move.l #-2080243704,-(sp) - 0xa8, 0xb5, // ScriptUtil() - 0x20, 0x1f, // move.l (a7)+,d0 - M68K_RTS >> 8, M68K_RTS & 0xff - }; - r.d[0] = sizeof(proc); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32_t proc_area = r.a[0]; - if (proc_area) { - Host2Mac_memcpy(proc_area, proc, sizeof(proc)); - WriteMacInt16(proc_area + 4, varID); - Execute68k(proc_area, &r); - ret = r.d[0]; - r.a[0] = proc_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - } - return ret; -} - -static ScriptCode ScriptNumberForFontID(int16_t fontID) -{ - ScriptCode ret = -1; - M68kRegisters r; - static uint8_t proc[] = { - 0x55, 0x4f, // subq.w #2,sp - 0x3f, 0x3c, 0x00, 0x00, // move.w #fontID,-(sp) - 0x2f, 0x3c, 0x82, 0x02, 0x00, 0x06, // move.l #-2113798138,-(sp) - 0xa8, 0xb5, // ScriptUtil() - 0x30, 0x1f, // move.w (sp)+,d0 - M68K_RTS >> 8, M68K_RTS & 0xff - }; - r.d[0] = sizeof(proc); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32_t proc_area = r.a[0]; - if (proc_area) { - Host2Mac_memcpy(proc_area, proc, sizeof(proc)); - WriteMacInt16(proc_area + 4, fontID); - Execute68k(proc_area, &r); - ret = r.d[0]; - r.a[0] = proc_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - } - return ret; -} - -/* - * Get Mac's default text encoding - */ - -static TextEncoding MacDefaultTextEncoding() -{ - int script = GetMacScriptManagerVariable(smMacSysScript); - int region = GetMacScriptManagerVariable(smMacRegionCode); - TextEncoding encoding; - - if (UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, region, NULL, &encoding)) - encoding = kTextEncodingMacRoman; - - return encoding; -} - -static NSData *ConvertToMacTextEncoding(NSAttributedString *aStr, NSArray **styleAndScriptRuns) -{ - NSUInteger length = [aStr length]; - - NSMutableArray *styleRuns = [NSMutableArray array]; - - for (NSUInteger index = 0; index < length;) { - NSRange attrRange; - NSDictionary *attrs = [aStr attributesAtIndex:index effectiveRange:&attrRange]; - - [styleRuns addObject:[NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithUnsignedInteger:index], @"offset", - attrs, @"attributes", nil]]; - - index = NSMaxRange(attrRange); - } - - UnicodeToTextRunInfo info; - - OSStatus err = CreateUnicodeToTextRunInfoByScriptCode(0, NULL, &info); - - if (err != noErr) { - if (styleAndScriptRuns) - *styleAndScriptRuns = styleRuns; - - return [[aStr string] dataUsingEncoding:CFStringConvertEncodingToNSStringEncoding(MacDefaultTextEncoding())]; - } - - unichar chars[length]; - - [[aStr string] getCharacters:chars range:NSMakeRange(0, length)]; - - NSUInteger unicodeLength = length * sizeof(unichar); - NSUInteger bufLen = unicodeLength * 2; - uint8_t buf[bufLen]; - ByteCount bytesRead; - - ItemCount scriptRunCount = 1601; // max number of allowed style changes - ScriptCodeRun scriptRuns[scriptRunCount]; - - ItemCount inOffsetCount = [styleRuns count]; - ByteOffset inOffsets[inOffsetCount]; - - if (inOffsetCount) { - for (NSUInteger i = 0; i < inOffsetCount; i++) { - NSDictionary *eachRun = [styleRuns objectAtIndex:i]; - - inOffsets[i] = [[eachRun objectForKey:@"offset"] unsignedLongValue] * 2; - } - } - - ItemCount offsetCount; - ByteOffset offsets[inOffsetCount]; - - err = ConvertFromUnicodeToScriptCodeRun(info, unicodeLength, chars, - kUnicodeTextRunMask | kUnicodeUseFallbacksMask | kUnicodeLooseMappingsMask, - inOffsetCount, inOffsets, &offsetCount, offsets, - bufLen, &bytesRead, &bufLen, buf, - scriptRunCount, &scriptRunCount, scriptRuns); - - if (err != noErr) { - if (styleAndScriptRuns) - *styleAndScriptRuns = styleRuns; - - return [[aStr string] dataUsingEncoding:CFStringConvertEncodingToNSStringEncoding(MacDefaultTextEncoding())]; - } - - if (styleAndScriptRuns) { - NSMutableArray *runs = [NSMutableArray array]; - NSUInteger currentStyleRun = 0; - NSUInteger currentScriptRun = 0; - - for (NSUInteger currentOffset = 0; currentOffset < bufLen;) { - ScriptCodeRun scriptRun = scriptRuns[currentScriptRun]; - NSDictionary *attrs = [[styleRuns objectAtIndex:currentStyleRun] objectForKey:@"attributes"]; - - NSUInteger nextStyleOffset = (currentStyleRun < offsetCount - 1) ? offsets[currentStyleRun + 1] : bufLen; - NSUInteger nextScriptOffset = (currentScriptRun < scriptRunCount - 1) ? scriptRuns[currentScriptRun + 1].offset : bufLen; - - [runs addObject:[NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithUnsignedInteger:currentOffset], @"offset", - [NSNumber numberWithShort:scriptRun.script], @"script", - attrs, @"attributes", nil]]; - - if (nextStyleOffset == nextScriptOffset) { - currentStyleRun++; - currentScriptRun++; - currentOffset = nextStyleOffset; - } else if (nextStyleOffset < nextScriptOffset) { - currentStyleRun++; - currentOffset = nextStyleOffset; - } else { - currentScriptRun++; - currentOffset = nextScriptOffset; - } - } - - *styleAndScriptRuns = runs; - } - - return [NSData dataWithBytes:buf length:bufLen]; -} - -/* - * Count all Mac font IDs on the system - */ - -static NSUInteger CountMacFonts() -{ - M68kRegisters r; - static uint8_t proc[] = { - 0x55, 0x4f, // subq.w #2,sp - 0x2f, 0x3c, 'F', 'O', 'N', 'D', // move.l #'FOND',-(sp) - 0xa9, 0x9c, // CountResources() - 0x30, 0x1f, // move.w (sp)+,D0 - M68K_RTS >> 8, M68K_RTS & 0xff - }; - r.d[0] = sizeof(proc); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32_t proc_area = r.a[0]; - int16_t fontCount = 0; - - if (proc_area) { - Host2Mac_memcpy(proc_area, proc, sizeof(proc)); - Execute68k(proc_area, &r); - - fontCount = r.d[0]; - - r.a[0] = proc_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - } - - if (fontCount < 0) { - fontCount = 0; - } - - return fontCount; -} - -/* - * Get Mac font ID at index - */ - -static int16_t MacFontIDAtIndex(NSUInteger index) -{ - M68kRegisters r; - static uint8_t get_res_handle_proc[] = { - 0x42, 0x27, // clr.b -(sp) - 0xa9, 0x9b, // SetResLoad() - 0x59, 0x4f, // subq.w #4,sp - 0x2f, 0x3c, 'F', 'O', 'N', 'D', // move.l #'FOND',-(sp) - 0x3f, 0x3c, 0, 0, // move.w #index,-(sp) - 0xa9, 0x9d, // GetIndResource() - 0x26, 0x5f, // movea.l (sp)+,A3 - 0x1f, 0x3c, 0x00, 0x01, // move.b #1,-(sp) - 0xa9, 0x9b, // SetResLoad() - M68K_RTS >> 8, M68K_RTS & 0xff - }; - r.d[0] = sizeof(get_res_handle_proc); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32_t proc_area = r.a[0]; - - uint32_t res_handle = 0; - int16_t fontID = 0; - - if (proc_area) { - Host2Mac_memcpy(proc_area, get_res_handle_proc, sizeof(get_res_handle_proc)); - WriteMacInt16(proc_area + 14, (uint16_t)(index + 1)); - - Execute68k(proc_area, &r); - - res_handle = r.a[3]; - - r.a[0] = proc_area; - Execute68kTrap(0xa01f, &r); // DisposePtr() - } - - if (res_handle) { - static uint8_t get_info_proc[] = { - 0x2f, 0x0a, // move.l A2,-(sp) - 0x2f, 0x0b, // move.l A3,-(sp) - 0x42, 0xa7, // clr.l -(sp) - 0x42, 0xa7, // clr.l -(sp) - 0xa9, 0xa8, // GetResInfo() - 0x2f, 0x0a, // move.l A2,-(sp) - 0xa9, 0xa3, // ReleaseResource() - M68K_RTS >> 8, M68K_RTS & 0xff, - 0, 0 - }; - - r.d[0] = sizeof(get_info_proc); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - proc_area = r.a[0]; - - if (proc_area) { - Host2Mac_memcpy(proc_area, get_info_proc, sizeof(get_info_proc)); - r.a[2] = res_handle; - r.a[3] = proc_area + 16; - - Execute68k(proc_area, &r); - - fontID = ReadMacInt16(proc_area + 16); - - r.a[0] = proc_area; - Execute68kTrap(0xa01f, &r); // DisposePtr() - } - } - - return fontID; -} - -/* - * List all font IDs on the system - */ - -static NSArray *ListMacFonts() -{ - NSUInteger fontCount = CountMacFonts(); - NSMutableArray *fontIDs = [NSMutableArray array]; - - for (NSUInteger i = 0; i < fontCount; i++) { - int16_t eachFontID = MacFontIDAtIndex(i); - - [fontIDs addObject:[NSNumber numberWithShort:eachFontID]]; - } - - return fontIDs; -} - -/* - * List all font IDs having a certain script - */ - -static NSArray *ListMacFontsForScript(ScriptCode script) -{ - NSMutableArray *fontIDs = [NSMutableArray array]; - - for (NSNumber *eachFontIDNum in ListMacFonts()) { - if (ScriptNumberForFontID([eachFontIDNum shortValue]) == script) - [fontIDs addObject:eachFontIDNum]; - } - - return fontIDs; -} - -/* - * Convert Mac font ID to font name - */ - -static NSString *FontNameFromFontID(int16_t fontID) -{ - M68kRegisters r; - r.d[0] = 256; // Str255: 255 characters + length byte - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32_t name_area = r.a[0]; - - if (!name_area) - return nil; - - uint8_t proc[] = { - 0x3f, 0x3c, 0, 0, // move.w #fontID,-(sp) - 0x2f, 0x0a, // move.l A2,-(sp) - 0xa8, 0xff, // GetFontName() - M68K_RTS >> 8, M68K_RTS & 0xff - }; - - r.d[0] = sizeof(proc); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32_t proc_area = r.a[0]; - - if (proc_area) { - Host2Mac_memcpy(proc_area, proc, sizeof(proc)); - WriteMacInt16(proc_area + 2, fontID); - r.a[2] = name_area; - Execute68k(proc_area, &r); - - r.a[0] = proc_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - } - - uint8_t * const namePtr = Mac2HostAddr(name_area); - - NSString *name = (NSString *)CFStringCreateWithPascalString(kCFAllocatorDefault, namePtr, kCFStringEncodingMacRoman); - - r.a[0] = name_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - - return [name autorelease]; -} - -/* - * Convert font name to Mac font ID - */ - -static int16_t FontIDFromFontName(NSString *fontName) -{ - M68kRegisters r; - r.d[0] = 256; // Str255: 255 characters + length byte - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32_t name_area = r.a[0]; - - if (!name_area) - return 0; - - uint8_t * const namePtr = Mac2HostAddr(name_area); - - CFStringGetPascalString((CFStringRef)fontName, namePtr, 256, kCFStringEncodingMacRoman); - - uint8_t proc[] = { - 0x2f, 0x0a, // move.l A2,-(sp) - 0x2f, 0x0b, // move.l A3,-(sp) - 0xa9, 0x00, // GetFNum() - M68K_RTS >> 8, M68K_RTS & 0xff, - 0, 0 - }; - - r.d[0] = sizeof(proc); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32_t proc_area = r.a[0]; - int16_t fontID = 0; - - if (proc_area) { - Host2Mac_memcpy(proc_area, proc, sizeof(proc)); - r.a[2] = name_area; - r.a[3] = proc_area + 8; - - Execute68k(proc_area, &r); - - fontID = ReadMacInt16(proc_area + 8); - - r.a[0] = proc_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - } - - r.a[0] = name_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - - return fontID; -} - -/* - * Get font ID in desired script if possible; otherwise, try to get some font in the desired script. - */ - -static int16_t FontIDFromFontNameAndScript(NSString *fontName, ScriptCode script) -{ - int16_t fontID = FontIDFromFontName(fontName); - - if (ScriptNumberForFontID(fontID) == script) - return fontID; - - NSArray *fontIDs = ListMacFontsForScript(script); - - if ([fontIDs count] == 0) - return fontID; // no fonts are going to work; might as well return the original one - - if (fontName) { - // look for a localized version of our font; e.g. "Helvetica CE" if our font is Helvetica - for (NSNumber *eachFontIDNum in fontIDs) { - int16_t eachFontID = [eachFontIDNum shortValue]; - - if ([FontNameFromFontID(eachFontID) hasPrefix:fontName]) - return eachFontID; - } - } - - // Give up and just return a font that will work - return [[fontIDs objectAtIndex:0] shortValue]; -} - -/* - * Convert Mac TEXT/styl to attributed string - */ - -static NSAttributedString *AttributedStringFromMacTEXTAndStyl(NSData *textData, NSData *stylData) -{ - NSMutableAttributedString *aStr = [[[NSMutableAttributedString alloc] init] autorelease]; - - if (aStr == nil) - return nil; - - const uint8_t *bytes = (const uint8_t *)[stylData bytes]; - NSUInteger length = [stylData length]; - - if (length < 2) - return nil; - - uint16_t elements = CFSwapInt16BigToHost(*(uint16_t *)bytes); - const NSUInteger elementSize = 20; - - if (length < elements * elementSize) - return nil; - - NSUInteger cursor = 2; - - for (NSUInteger i = 0; i < elements; i++) AUTORELEASE_POOL { - int32_t startChar = CFSwapInt32BigToHost(*(int32_t *)(bytes + cursor)); cursor += 4; - int16_t height __attribute__((unused)) = CFSwapInt16BigToHost(*(int16_t *)&bytes[cursor]); cursor += 2; - int16_t ascent __attribute__((unused)) = CFSwapInt16BigToHost(*(int16_t *)&bytes[cursor]); cursor += 2; - int16_t fontID = CFSwapInt16BigToHost(*(int16_t *)&bytes[cursor]); cursor += 2; - uint8_t face = bytes[cursor]; cursor += 2; - int16_t size = CFSwapInt16BigToHost(*(int16_t *)&bytes[cursor]); cursor += 2; - uint16_t red = CFSwapInt16BigToHost(*(int16_t *)&bytes[cursor]); cursor += 2; - uint16_t green = CFSwapInt16BigToHost(*(int16_t *)&bytes[cursor]); cursor += 2; - uint16_t blue = CFSwapInt16BigToHost(*(int16_t *)&bytes[cursor]); cursor += 2; - - int32_t nextChar; - - if (i + 1 == elements) - nextChar = [textData length]; - else - nextChar = CFSwapInt32BigToHost(*(int32_t *)(bytes + cursor)); - - NSMutableDictionary *attrs = [[NSMutableDictionary alloc] init]; - NSColor *color = [NSColor colorWithDeviceRed:(CGFloat)red / 65535.0 green:(CGFloat)green / 65535.0 blue:(CGFloat)blue / 65535.0 alpha:1.0]; - NSFont *font; - TextEncoding encoding; - - if (fontID == 0) { // System font - CGFloat fontSize = (size == 0) ? [NSFont systemFontSize] : (CGFloat)size; - font = [NSFont systemFontOfSize:fontSize]; - } else if (fontID == 1) { // Application font - font = [NSFont userFontOfSize:(CGFloat)size]; - } else { - NSString *fontName = FontNameFromFontID(fontID); - font = [NSFont fontWithName:fontName size:(CGFloat)size]; - - if (font == nil) { - // Convert localized variants of fonts; e.g. "Helvetica CE" to "Helvetica" - - NSRange wsRange = [fontName rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet] options:NSBackwardsSearch]; - - if (wsRange.length) { - fontName = [fontName substringToIndex:wsRange.location]; - font = [NSFont fontWithName:fontName size:(CGFloat)size]; - } - } - } - - if (font == nil) - font = [NSFont userFontOfSize:(CGFloat)size]; - - if (UpgradeScriptInfoToTextEncoding(ScriptNumberForFontID(fontID), kTextLanguageDontCare, kTextRegionDontCare, NULL, &encoding)) - encoding = MacDefaultTextEncoding(); - - NSFontManager *fm = [NSFontManager sharedFontManager]; - - if (face & FONT_FACE_BOLD) - font = [fm convertFont:font toHaveTrait:NSBoldFontMask]; - - if (face & FONT_FACE_ITALIC) - font = [fm convertFont:font toHaveTrait:NSItalicFontMask]; - - if (face & FONT_FACE_CONDENSED) - font = [fm convertFont:font toHaveTrait:NSCondensedFontMask]; - - if (face & FONT_FACE_EXTENDED) - font = [fm convertFont:font toHaveTrait:NSExpandedFontMask]; - - [attrs setObject:font forKey:NSFontAttributeName]; - - if (face & FONT_FACE_UNDERLINE) - [attrs setObject:[NSNumber numberWithInteger:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName]; - - if (face & FONT_FACE_OUTLINE) { - [attrs setObject:color forKey:NSStrokeColorAttributeName]; - [attrs setObject:[NSNumber numberWithInteger:3] forKey:NSStrokeWidthAttributeName]; - } - - if (face & FONT_FACE_SHADOW) { - NSShadow *shadow = [[NSShadow alloc] init]; - NSColor *shadowColor = [NSColor colorWithDeviceRed:(CGFloat)red / 65535.0 green:(CGFloat)green / 65535.0 blue:(CGFloat)blue / 65535.0 alpha:0.5]; - - [shadow setShadowColor:shadowColor]; - [shadow setShadowOffset:NSMakeSize(2, -2.0)]; - - [attrs setObject:shadow forKey:NSShadowAttributeName]; - - [shadow release]; - } - - [attrs setObject:color forKey:NSForegroundColorAttributeName]; - - NSData *partialData = [textData subdataWithRange:NSMakeRange(startChar, nextChar - startChar)]; - NSString *partialString = [[NSString alloc] initWithData:partialData encoding:CFStringConvertEncodingToNSStringEncoding(encoding)]; - - if (partialString) { - NSAttributedString *partialAttribString = [[NSAttributedString alloc] initWithString:partialString attributes:attrs]; - - [aStr appendAttributedString:partialAttribString]; - - [partialAttribString release]; - } - - [partialString release]; - [attrs release]; - } - - return aStr; -} - -/* - * Append styl data for one text run - */ - -static void AppendStylRunData(NSMutableData *stylData, NSDictionary *attrs, ScriptCode script) -{ - NSFontManager *fontManager = [NSFontManager sharedFontManager]; - NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; - - NSFont *font = [attrs objectForKey:NSFontAttributeName]; - NSColor *color = [[attrs objectForKey:NSForegroundColorAttributeName] colorUsingColorSpaceName:NSDeviceRGBColorSpace device:nil]; - NSFontTraitMask traits = [fontManager traitsOfFont:font]; - NSNumber *underlineStyle = [attrs objectForKey:NSUnderlineStyleAttributeName]; - NSNumber *strokeWidth = [attrs objectForKey:NSStrokeWidthAttributeName]; - NSShadow *shadow = [attrs objectForKey:NSShadowAttributeName]; - - int16_t hostFontID = FontIDFromFontNameAndScript([font familyName], script); - - if (hostFontID == 0) { - hostFontID = [font isFixedPitch] ? 4 /* Monaco */ : 1 /* Application font */; - } - - int16_t height = CFSwapInt16HostToBig((int16_t)rint([layoutManager defaultLineHeightForFont:font])); - int16_t ascent = CFSwapInt16HostToBig((int16_t)rint([font ascender])); - int16_t fontID = CFSwapInt16HostToBig(hostFontID); - uint8_t face = 0; - int16_t size = CFSwapInt16HostToBig((int16_t)rint([font pointSize])); - uint16_t red = CFSwapInt16HostToBig((int16_t)rint([color redComponent] * 65535.0)); - uint16_t green = CFSwapInt16HostToBig((int16_t)rint([color greenComponent] * 65535.0)); - uint16_t blue = CFSwapInt16HostToBig((int16_t)rint([color blueComponent] * 65535.0)); - - if (traits & NSBoldFontMask) { - face |= FONT_FACE_BOLD; - } - - if (traits & NSItalicFontMask) { - face |= FONT_FACE_ITALIC; - } - - if (traits & NSCondensedFontMask) { - face |= FONT_FACE_CONDENSED; - } - - if (traits & NSExpandedFontMask) { - face |= FONT_FACE_EXTENDED; - } - - if (underlineStyle && [underlineStyle integerValue] != NSUnderlineStyleNone) { - face |= FONT_FACE_UNDERLINE; - } - - if (strokeWidth && [strokeWidth doubleValue] > 0.0) { - face |= FONT_FACE_OUTLINE; - } - - if (shadow) { - face |= FONT_FACE_SHADOW; - } - - [stylData appendBytes:&height length:2]; - [stylData appendBytes:&ascent length:2]; - [stylData appendBytes:&fontID length:2]; - [stylData appendBytes:&face length:1]; - [stylData increaseLengthBy:1]; - [stylData appendBytes:&size length:2]; - [stylData appendBytes:&red length:2]; - [stylData appendBytes:&green length:2]; - [stylData appendBytes:&blue length:2]; - - [layoutManager release]; -} - -/* - * Convert attributed string to TEXT/styl - */ - -static NSData *ConvertToMacTEXTAndStyl(NSAttributedString *aStr, NSData **outStylData) -{ - // Limitations imposed by the Mac TextEdit system. - const NSUInteger charLimit = 32 * 1024; - const NSUInteger elementLimit = 1601; - - NSUInteger length = [aStr length]; - - if (length > charLimit) { - aStr = [aStr attributedSubstringFromRange:NSMakeRange(0, charLimit)]; - } - - NSArray *runs = nil; - - NSData *textData = ConvertToMacTextEncoding(aStr, &runs); - - NSMutableData *stylData = [NSMutableData dataWithLength:2]; // number of styles to be filled in at the end - - NSUInteger elements = 0; - - for (NSDictionary *eachRun in runs) { - if (elements >= elementLimit) - break; - - NSUInteger offset = [[eachRun objectForKey:@"offset"] unsignedIntegerValue]; - ScriptCode script = [[eachRun objectForKey:@"script"] shortValue]; - NSDictionary *attrs = [eachRun objectForKey:@"attributes"]; - - int32_t startChar = CFSwapInt32HostToBig((int32_t)offset); - [stylData appendBytes:&startChar length:4]; - - AppendStylRunData(stylData, attrs, script); - - elements++; - } - - uint16_t bigEndianElements = CFSwapInt16HostToBig((uint16_t)elements); - - [stylData replaceBytesInRange:NSMakeRange(0, 2) withBytes:&bigEndianElements length:2]; - - if (outStylData) - *outStylData = stylData; - - return textData; -} - -/* - * Get data of a particular flavor from the pasteboard - */ - -static NSData *DataFromPasteboard(NSPasteboard *pboard, NSString *flavor) -{ - return [pboard dataForType:flavor]; -} - -/* - * Convert Mac TEXT/styl to RTF - */ - -static void WriteMacTEXTAndStylToPasteboard(NSPasteboard *pboard, NSData *textData, NSData *stylData) -{ - NSMutableAttributedString *aStr = [AttributedStringFromMacTEXTAndStyl(textData, stylData) mutableCopy]; - - if (!aStr) { - NSString *string = [[NSString alloc] initWithData:textData encoding:CFStringConvertEncodingToNSStringEncoding(MacDefaultTextEncoding())]; - - if (!string) - return; - - aStr = [[NSMutableAttributedString alloc] initWithString:string attributes:nil]; - - [string release]; - } - - // fix line endings - [[aStr mutableString] replaceOccurrencesOfString:@"\r" withString:@"\n" options:NSLiteralSearch range:NSMakeRange(0, [aStr length])]; - - [pboard writeObjects:[NSArray arrayWithObject:aStr]]; - - [aStr release]; -} - -/* - * Convert RTF to Mac TEXT/styl - */ - -static NSData *MacTEXTAndStylDataFromPasteboard(NSPasteboard *pboard, NSData **outStylData) -{ - NSMutableAttributedString *aStr; - - NSArray *objs = [pboard readObjectsForClasses:[NSArray arrayWithObject:[NSAttributedString class]] options:nil]; - - if ([objs count]) { - aStr = [[objs objectAtIndex:0] mutableCopy]; - } else { - objs = [pboard readObjectsForClasses:[NSArray arrayWithObject:[NSString class]] options:nil]; - - if (![objs count]) - return nil; - - aStr = [[NSMutableAttributedString alloc] initWithString:[objs objectAtIndex:0]]; - } - - // fix line endings - [[aStr mutableString] replaceOccurrencesOfString:@"\n" withString:@"\r" options:NSLiteralSearch range:NSMakeRange(0, [[aStr mutableString] length])]; - - NSData *stylData = nil; - NSData *textData = ConvertToMacTEXTAndStyl(aStr, &stylData); - - [aStr release]; - - if (outStylData) - *outStylData = stylData; - - return textData; -} - -/* - * Initialization - */ - -void ClipInit(void) -{ - g_pboard = [[NSPasteboard generalPasteboard] retain]; - if (!g_pboard) { - D(bug("could not create Pasteboard\n")); - } - - g_macScrap = [[NSMutableDictionary alloc] init]; -} - - -/* - * Deinitialization - */ - -void ClipExit(void) -{ - [g_pboard release]; - g_pboard = nil; - - [g_macScrap release]; - g_macScrap = nil; -} - -/* - * Convert an NSImage to PICT format. - */ - -static NSData *ConvertImageToPICT(NSImage *image) { - if ([[image representations] count] == 0) { - return nil; - } - - NSImageRep *rep = [[image representations] objectAtIndex:0]; - NSUInteger width; - NSUInteger height; - - if ([rep isKindOfClass:[NSBitmapImageRep class]]) { - width = [rep pixelsWide]; - height = [rep pixelsHigh]; - } else { - width = lrint([image size].width); - height = lrint([image size].height); - } - - // create a new bitmap image rep in our desired format, following the advice here: - // https://developer.apple.com/library/mac/#releasenotes/Cocoa/AppKitOlderNotes.html#X10_6Notes - - NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL - pixelsWide:width - pixelsHigh:height - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace - bytesPerRow:width * 4 - bitsPerPixel:32]; - - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap]]; - [rep draw]; - [NSGraphicsContext restoreGraphicsState]; - - unsigned char *rgba = [bitmap bitmapData]; - - long bufSize = ConvertRGBAToPICT(NULL, 0, rgba, width, height); - - NSData *pictData = nil; - - if (bufSize > 0) { - uint8_t *buf = (uint8_t *)malloc(bufSize); - - long pictSize = ConvertRGBAToPICT(buf, bufSize, rgba, width, height); - - if (pictSize > 0) - pictData = [NSData dataWithBytes:buf length:pictSize]; - - free(buf); - } - - [bitmap release]; - - return pictData; -} - -/* - * Convert any images that may be on the clipboard to PICT format if possible. - */ - -static NSData *MacPICTDataFromPasteboard(NSPasteboard *pboard) -{ - // check if there's any PICT data on the pasteboard - NSData *pictData = DataFromPasteboard(pboard, (NSString *)kUTTypePICT); - - if (pictData) - return pictData; - - // now check to see if any images on the pasteboard have PICT representations - NSArray *objs = [pboard readObjectsForClasses:[NSArray arrayWithObject:[NSImage class]] options:nil]; - - for (NSImage *eachImage in objs) { - for (NSImageRep *eachRep in [eachImage representations]) { - - if ([eachRep isKindOfClass:[NSPICTImageRep class]]) - return [(NSPICTImageRep *)eachRep PICTRepresentation]; - } - } - - // Give up and perform the conversion ourselves - if ([objs count]) - return ConvertImageToPICT([objs objectAtIndex:0]); - - // If none of that worked, sorry, we're out of options - return nil; -} - -/* - * Zero Mac clipboard - */ - -static void ZeroMacClipboard() -{ - D(bug("Zeroing Mac clipboard\n")); - M68kRegisters r; - static uint8_t proc[] = { - 0x59, 0x8f, // subq.l #4,sp - 0xa9, 0xfc, // ZeroScrap() - 0x58, 0x8f, // addq.l #4,sp - M68K_RTS >> 8, M68K_RTS & 0xff - }; - r.d[0] = sizeof(proc); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32_t proc_area = r.a[0]; - - if (proc_area) { - Host2Mac_memcpy(proc_area, proc, sizeof(proc)); - Execute68k(proc_area, &r); - - [g_macScrap removeAllObjects]; - - r.a[0] = proc_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - } -} - -/* - * Write data to Mac clipboard - */ - -static void WriteDataToMacClipboard(NSData *pbData, uint32_t type) -{ - D(bug("Writing data %s to Mac clipboard with type '%c%c%c%c'\n", [[pbData description] UTF8String], - (type >> 24) & 0xff, (type >> 16) & 0xff, (type >> 8) & 0xff, type & 0xff)); - - if ([pbData length] == 0) - return; - - NSNumber *typeNum = [NSNumber numberWithInteger:type]; - - if ([g_macScrap objectForKey:typeNum]) { - // the classic Mac OS can't have more than one object of the same type on the clipboard - return; - } - - // Allocate space for new scrap in MacOS side - M68kRegisters r; - r.d[0] = [pbData length]; - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32_t scrap_area = r.a[0]; - - // Get the native clipboard data - if (scrap_area) { - uint8_t * const data = Mac2HostAddr(scrap_area); - - memcpy(data, [pbData bytes], [pbData length]); - - // Add new data to clipboard - static uint8_t proc[] = { - 0x59, 0x8f, // subq.l #4,sp - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #length,-(sp) - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #type,-(sp) - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #outbuf,-(sp) - 0xa9, 0xfe, // PutScrap() - 0x58, 0x8f, // addq.l #4,sp - M68K_RTS >> 8, M68K_RTS & 0xff - }; - r.d[0] = sizeof(proc); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32_t proc_area = r.a[0]; - - if (proc_area) { - Host2Mac_memcpy(proc_area, proc, sizeof(proc)); - WriteMacInt32(proc_area + 4, [pbData length]); - WriteMacInt32(proc_area + 10, type); - WriteMacInt32(proc_area + 16, scrap_area); - we_put_this_data = true; - Execute68k(proc_area, &r); - - r.a[0] = proc_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - - [g_macScrap setObject:pbData forKey:typeNum]; - } - - r.a[0] = scrap_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - } -} - -/* - * Take all the data on host pasteboard and convert it to something the Mac understands if possible - */ - -static void ConvertHostPasteboardToMacScrap() -{ - D(bug("ConvertHostPasteboardToMacScrap\n")); - - ZeroMacClipboard(); - - NSData *stylData = nil; - NSData *textData = MacTEXTAndStylDataFromPasteboard(g_pboard, &stylData); - - if (textData) { - if (stylData) - WriteDataToMacClipboard(stylData, TYPE_STYL); - - WriteDataToMacClipboard(textData, TYPE_TEXT); - } - - NSData *pictData = MacPICTDataFromPasteboard(g_pboard); - - if (pictData) - WriteDataToMacClipboard(pictData, TYPE_PICT); - - for (NSString *eachType in [g_pboard types]) { - if (UTTypeConformsTo((CFStringRef)eachType, kUTTypeText)) { - // text types are already handled - continue; - } - - if (UTTypeConformsTo((CFStringRef)eachType, kUTTypeImage)) { - // image types are already handled - continue; - } - - uint32_t type = FlavorForUTI(eachType); - - // skip styl and ustl as well; those fall under text, which is handled already - if (!type || type == TYPE_STYL || type == TYPE_USTL) - continue; - - WriteDataToMacClipboard(DataFromPasteboard(g_pboard, eachType), type); - } -} - -/* - * Take all the data on the Mac clipbord and convert it to something the host pasteboard understands if possible - */ - -static void ConvertMacScrapToHostPasteboard() -{ - D(bug("ConvertMacScrapToHostPasteboard\n")); - - BOOL wroteText = NO; - - [g_pboard clearContents]; - - for (NSNumber *eachTypeNum in g_macScrap) AUTORELEASE_POOL { - uint32_t eachType = [eachTypeNum integerValue]; - - if (eachType == TYPE_TEXT || eachType == TYPE_STYL || eachType == TYPE_UTXT || eachType == TYPE_UT16 || eachType == TYPE_USTL) { - if (wroteText) - continue; - - NSData *textData; - NSData *stylData; - - textData = [g_macScrap objectForKey:[NSNumber numberWithInteger:TYPE_TEXT]]; - stylData = [g_macScrap objectForKey:[NSNumber numberWithInteger:TYPE_STYL]]; - - if (textData) { - WriteMacTEXTAndStylToPasteboard(g_pboard, textData, stylData); - wroteText = YES; - } - - // sometime, it might be interesting to write a converter for utxt/ustl if possible - - continue; - } - - NSData *pbData = [g_macScrap objectForKey:eachTypeNum]; - - if (pbData) { - NSString *typeStr = UTIForFlavor(eachType); - - if (!typeStr) - continue; - - [g_pboard setData:pbData forType:typeStr]; - } - } -} - -/* - * Check whether the pasteboard has changed since our last check; if it has, write it to the emulated pasteboard - */ - -static void ConvertHostPasteboardToMacScrapIfChanged() -{ - if (!g_pboard) - return; - - if ([g_pboard changeCount] > g_pb_change_count) { - ConvertHostPasteboardToMacScrap(); - g_pb_change_count = [g_pboard changeCount]; - } -} - -/* - * Mac application reads clipboard - */ - -void GetScrap(void **handle, uint32_t type, int32_t offset) -{ - D(bug("GetScrap handle %p, type %4.4s, offset %d\n", handle, (char *)&type, offset)); - - AUTORELEASE_POOL { - ConvertHostPasteboardToMacScrapIfChanged(); - } -} - -/* - * ZeroScrap() is called before a Mac application writes to the clipboard; clears out the previous contents - */ - -void ZeroScrap() -{ - D(bug("ZeroScrap\n")); - - we_put_this_data = false; - - // Defer clearing the host pasteboard until the Mac tries to put something on it. - // This prevents us from clearing the pasteboard when ZeroScrap() is called during startup. - should_clear = true; -} - -/* - * Mac application wrote to clipboard - */ - -void PutScrap(uint32_t type, void *scrap, int32_t length) -{ - D(bug("PutScrap type %4.4s, data %p, length %ld\n", (char *)&type, scrap, (long)length)); - - AUTORELEASE_POOL { - if (!g_pboard) - return; - - if (we_put_this_data) { - we_put_this_data = false; - return; - } - - if (length <= 0) - return; - - if (should_clear) { - [g_macScrap removeAllObjects]; - should_clear = false; - } - - NSData *pbData = [NSData dataWithBytes:scrap length:length]; - if (!pbData) - return; - - [g_macScrap setObject:pbData forKey:[NSNumber numberWithInteger:type]]; - - ConvertMacScrapToHostPasteboard(); - - // So that our PutScrap() patch won't bounce the data we just wrote back to the Mac clipboard - g_pb_change_count = [g_pboard changeCount]; - } -} diff --git a/BasiliskII/src/MacOSX/extfs_macosx.cpp b/BasiliskII/src/MacOSX/extfs_macosx.cpp deleted file mode 100644 index 41b35a18..00000000 --- a/BasiliskII/src/MacOSX/extfs_macosx.cpp +++ /dev/null @@ -1,634 +0,0 @@ -/* - * extfs_macosx.cpp - MacOS file system for access native file system access, MacOS X specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "prefs.h" -#include "extfs.h" -#include "extfs_defs.h" - -// XXX: don't clobber with native definitions -#define noErr native_noErr -#define Point native_Point -#define Rect native_Rect -#define ProcPtr native_ProcPtr -# include -#undef ProcPtr -#undef Rect -#undef Point -#undef noErr - -#define DEBUG 0 -#include "debug.h" - - -// Default Finder flags -const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited; - - -/* - * Extended attributes (Tiger+) - */ - -#define USE_XATTRS g_use_xattrs -static bool g_use_xattrs = false; - -#define XATTR_TEST "org.BasiliskII.TestAttr" -#define XATTR_FINFO "org.BasiliskII.FinderInfo" -#define XATTR_FXINFO "org.BasiliskII.ExtendedFinderInfo" - -static bool get_xattr(const char *path, const char *name, void *value, uint32 size) -{ - return syscall(SYS_getxattr, path, name, value, size, 0, 0) == size; -} - -static bool set_xattr(const char *path, const char *name, const void *value, uint32 size) -{ - return syscall(SYS_setxattr, path, name, value, size, 0, 0) == 0; -} - -static bool remove_xattr(const char *path, const char *name) -{ - return syscall(SYS_removexattr, path, name, 0) == 0; -} - -static bool check_xattr(void) -{ - const char *path = PrefsFindString("extfs"); - if (path == NULL) - return false; - const uint32 sentinel = 0xdeadbeef; - if (!set_xattr(path, XATTR_TEST, &sentinel, sizeof(sentinel))) - return false; - uint32 v; - if (!get_xattr(path, XATTR_TEST, &v, sizeof(v))) - return false; - if (!remove_xattr(path, XATTR_TEST)) - return false; - return v == sentinel; -} - - -/* - * Initialization - */ - -void extfs_init(void) -{ - g_use_xattrs = check_xattr(); -} - - -/* - * Deinitialization - */ - -void extfs_exit(void) -{ -} - - -/* - * Add component to path name - */ - -void add_path_component(char *path, const char *component) -{ - int l = strlen(path); - if (l < MAX_PATH_LENGTH-1 && path[l-1] != '/') { - path[l] = '/'; - path[l+1] = 0; - } - strncat(path, component, MAX_PATH_LENGTH-1); -} - - -/* - * Finder info manipulation helpers - */ - -typedef uint8 FinderInfo[SIZEOF_FInfo]; - -struct FinderInfoAttrBuf { - uint32 length; - FinderInfo finderInfo; - FinderInfo extendedFinderInfo; -}; - -static const FinderInfo kNativeFInfoMask = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00}; -static const FinderInfo kNativeFXInfoMask = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00}; -static const FinderInfo kNativeDInfoMask = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00}; -static const FinderInfo kNativeDXInfoMask = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00}; /* XXX: keep frScroll? */ - -static void finfo_merge(FinderInfo dst, const FinderInfo emu, const FinderInfo nat, const FinderInfo mask) -{ - for (int i = 0; i < SIZEOF_FInfo; i++) - dst[i] = (emu[i] & ~mask[i]) | (nat[i] & mask[i]); -} - -static void finfo_split(FinderInfo dst, const FinderInfo emu, const FinderInfo mask) -{ - for (int i = 0; i < SIZEOF_FInfo; i++) - dst[i] = emu[i] & mask[i]; -} - - -/* - * Finder info are kept in helper files (on anything below Tiger) - * - * Finder info: - * /path/.finf/file - * - * The .finf files store a FInfo/DInfo, followed by a FXInfo/DXInfo - * (16+16 bytes) - */ - -static void make_finf_path(const char *src, char *dest, bool only_dir = false) -{ - dest[0] = 0; - - // Get pointer to last component of path - const char *last_part = strrchr(src, '/'); - if (last_part) - last_part++; - else - last_part = src; - - // Copy everything before - strncpy(dest, src, last_part-src); - dest[last_part-src] = 0; - - // Add additional component - strncat(dest, ".finf/", MAX_PATH_LENGTH-1); - - // Add last component - if (!only_dir) - strncat(dest, last_part, MAX_PATH_LENGTH-1); -} - -static int create_finf_dir(const char *path) -{ - char finf_dir[MAX_PATH_LENGTH]; - make_finf_path(path, finf_dir, true); - if (finf_dir[strlen(finf_dir) - 1] == '/') // Remove trailing "/" - finf_dir[strlen(finf_dir) - 1] = 0; - return mkdir(finf_dir, 0777); -} - -static int open_finf(const char *path, int flag) -{ - char finf_path[MAX_PATH_LENGTH]; - make_finf_path(path, finf_path); - - if ((flag & O_ACCMODE) == O_RDWR || (flag & O_ACCMODE) == O_WRONLY) - flag |= O_CREAT; - int fd = open(finf_path, flag, 0666); - if (fd < 0) { - if (errno == ENOENT && (flag & O_CREAT)) { - // One path component was missing, probably the finf - // directory. Try to create it and re-open the file. - int ret = create_finf_dir(path); - if (ret < 0) - return ret; - fd = open(finf_path, flag, 0666); - } - } - return fd; -} - - -/* - * Resource forks are kept into their native location - * - * Resource fork: - * /path/file/..namedfork/rsrc - */ - -static void make_rsrc_path(const char *src, char *dest) -{ - int l = strlen(src); - if (l + 1 + 16 + 1 <= MAX_PATH_LENGTH) - memcpy(dest, src, l + 1); - else { - // The rsrc component is copied as is, if there is not enough - // space to add it. In that case, open() will fail gracefully - // and this is what we want. - dest[0] = '.'; - dest[1] = '\0'; - } - - add_path_component(dest, "..namedfork/rsrc"); -} - -static int open_rsrc(const char *path, int flag) -{ - char rsrc_path[MAX_PATH_LENGTH]; - make_rsrc_path(path, rsrc_path); - - return open(rsrc_path, flag); -} - - -/* - * Get/set finder info for file/directory specified by full path - */ - -struct ext2type { - const char *ext; - uint32 type; - uint32 creator; -}; - -static const ext2type e2t_translation[] = { - {".Z", FOURCC('Z','I','V','M'), FOURCC('L','Z','I','V')}, - {".gz", FOURCC('G','z','i','p'), FOURCC('G','z','i','p')}, - {".hqx", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".bin", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".pdf", FOURCC('P','D','F',' '), FOURCC('C','A','R','O')}, - {".ps", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')}, - {".sit", FOURCC('S','I','T','!'), FOURCC('S','I','T','x')}, - {".tar", FOURCC('T','A','R','F'), FOURCC('T','A','R',' ')}, - {".uu", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".uue", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".zip", FOURCC('Z','I','P',' '), FOURCC('Z','I','P',' ')}, - {".8svx", FOURCC('8','S','V','X'), FOURCC('S','N','D','M')}, - {".aifc", FOURCC('A','I','F','C'), FOURCC('T','V','O','D')}, - {".aiff", FOURCC('A','I','F','F'), FOURCC('T','V','O','D')}, - {".au", FOURCC('U','L','A','W'), FOURCC('T','V','O','D')}, - {".mid", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')}, - {".midi", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')}, - {".mp2", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')}, - {".mp3", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')}, - {".wav", FOURCC('W','A','V','E'), FOURCC('T','V','O','D')}, - {".bmp", FOURCC('B','M','P','f'), FOURCC('o','g','l','e')}, - {".gif", FOURCC('G','I','F','f'), FOURCC('o','g','l','e')}, - {".lbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')}, - {".ilbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')}, - {".jpg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')}, - {".jpeg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')}, - {".pict", FOURCC('P','I','C','T'), FOURCC('o','g','l','e')}, - {".png", FOURCC('P','N','G','f'), FOURCC('o','g','l','e')}, - {".sgi", FOURCC('.','S','G','I'), FOURCC('o','g','l','e')}, - {".tga", FOURCC('T','P','I','C'), FOURCC('o','g','l','e')}, - {".tif", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')}, - {".tiff", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')}, - {".htm", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')}, - {".html", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')}, - {".txt", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')}, - {".rtf", FOURCC('T','E','X','T'), FOURCC('M','S','W','D')}, - {".c", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".C", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cc", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".h", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hh", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".s", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".S", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".i", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".mpg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')}, - {".mpeg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')}, - {".mov", FOURCC('M','o','o','V'), FOURCC('T','V','O','D')}, - {".fli", FOURCC('F','L','I',' '), FOURCC('T','V','O','D')}, - {".avi", FOURCC('V','f','W',' '), FOURCC('T','V','O','D')}, - {".qxd", FOURCC('X','D','O','C'), FOURCC('X','P','R','3')}, - {".hfv", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')}, - {".dsk", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')}, - {".img", FOURCC('r','o','h','d'), FOURCC('d','d','s','k')}, - {NULL, 0, 0} // End marker -}; - -// Get emulated Finder info from metadata (Tiger+) -static bool get_finfo_from_xattr(const char *path, uint8 *finfo, uint8 *fxinfo) -{ - if (!get_xattr(path, XATTR_FINFO, finfo, SIZEOF_FInfo)) - return false; - if (fxinfo && !get_xattr(path, XATTR_FXINFO, fxinfo, SIZEOF_FXInfo)) - return false; - return true; -} - -// Get emulated Finder info from helper file -static bool get_finfo_from_helper(const char *path, uint8 *finfo, uint8 *fxinfo) -{ - int fd = open_finf(path, O_RDONLY); - if (fd < 0) - return false; - - ssize_t actual = read(fd, finfo, SIZEOF_FInfo); - if (fxinfo) - actual += read(fd, fxinfo, SIZEOF_FXInfo); - close(fd); - return actual == (SIZEOF_FInfo + (fxinfo ? SIZEOF_FXInfo : 0)); -} - -// Get native Finder info -static bool get_finfo_from_native(const char *path, uint8 *finfo, uint8 *fxinfo) -{ - struct attrlist attrList; - memset(&attrList, 0, sizeof(attrList)); - attrList.bitmapcount = ATTR_BIT_MAP_COUNT; - attrList.commonattr = ATTR_CMN_FNDRINFO; - - FinderInfoAttrBuf attrBuf; - if (getattrlist(path, &attrList, &attrBuf, sizeof(attrBuf), 0) < 0) - return false; - - memcpy(finfo, attrBuf.finderInfo, SIZEOF_FInfo); - if (fxinfo) - memcpy(fxinfo, attrBuf.extendedFinderInfo, SIZEOF_FXInfo); - return true; -} - -static bool do_get_finfo(const char *path, bool has_fxinfo, - FinderInfo emu_finfo, FinderInfo emu_fxinfo, - FinderInfo nat_finfo, FinderInfo nat_fxinfo) -{ - memset(emu_finfo, 0, SIZEOF_FInfo); - if (has_fxinfo) - memset(emu_fxinfo, 0, SIZEOF_FXInfo); - *((uint16 *)(emu_finfo + fdFlags)) = htonl(DEFAULT_FINDER_FLAGS); - *((uint32 *)(emu_finfo + fdLocation)) = htonl((uint32)-1); - - if (USE_XATTRS) - get_finfo_from_xattr(path, emu_finfo, has_fxinfo ? emu_fxinfo : NULL); - else - get_finfo_from_helper(path, emu_finfo, has_fxinfo ? emu_fxinfo : NULL); - - if (!get_finfo_from_native(path, nat_finfo, has_fxinfo ? nat_fxinfo : NULL)) - return false; - return true; -} - -void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Set default finder info - Mac_memset(finfo, 0, SIZEOF_FInfo); - if (fxinfo) - Mac_memset(fxinfo, 0, SIZEOF_FXInfo); - WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS); - WriteMacInt32(finfo + fdLocation, (uint32)-1); - - // Merge emulated and native Finder info - FinderInfo emu_finfo, emu_fxinfo; - FinderInfo nat_finfo, nat_fxinfo; - if (do_get_finfo(path, fxinfo, emu_finfo, emu_fxinfo, nat_finfo, nat_fxinfo)) { - if (!is_dir) { - finfo_merge(Mac2HostAddr(finfo), emu_finfo, nat_finfo, kNativeFInfoMask); - if (fxinfo) - finfo_merge(Mac2HostAddr(fxinfo), emu_fxinfo, nat_fxinfo, kNativeFXInfoMask); - if (ReadMacInt32(finfo + fdType) != 0 && ReadMacInt32(finfo + fdCreator) != 0) - return; - } - else { - finfo_merge(Mac2HostAddr(finfo), emu_finfo, nat_finfo, kNativeDInfoMask); - if (fxinfo) - finfo_merge(Mac2HostAddr(fxinfo), emu_fxinfo, nat_fxinfo, kNativeDXInfoMask); - return; - } - } - - // No native Finder info, translate file name extension to MacOS type/creator - if (!is_dir) { - int path_len = strlen(path); - for (int i=0; e2t_translation[i].ext; i++) { - int ext_len = strlen(e2t_translation[i].ext); - if (path_len < ext_len) - continue; - if (!strcmp(path + path_len - ext_len, e2t_translation[i].ext)) { - WriteMacInt32(finfo + fdType, e2t_translation[i].type); - WriteMacInt32(finfo + fdCreator, e2t_translation[i].creator); - break; - } - } - } -} - -// Set emulated Finder info into metada (Tiger+) -static bool set_finfo_to_xattr(const char *path, const uint8 *finfo, const uint8 *fxinfo) -{ - if (!set_xattr(path, XATTR_FINFO, finfo, SIZEOF_FInfo)) - return false; - if (fxinfo && !set_xattr(path, XATTR_FXINFO, fxinfo, SIZEOF_FXInfo)) - return false; - return true; -} - -// Set emulated Finder info into helper file -static bool set_finfo_to_helper(const char *path, const uint8 *finfo, const uint8 *fxinfo) -{ - int fd = open_finf(path, O_RDWR); - if (fd < 0) - return false; - - ssize_t actual = write(fd, finfo, SIZEOF_FInfo); - if (fxinfo) - actual += write(fd, fxinfo, SIZEOF_FXInfo); - close(fd); - return actual == (SIZEOF_FInfo + (fxinfo ? SIZEOF_FXInfo : 0)); -} - -// Set native Finder info -static bool set_finfo_to_native(const char *path, const uint8 *finfo, const uint8 *fxinfo, bool is_dir) -{ - struct attrlist attrList; - memset(&attrList, 0, sizeof(attrList)); - attrList.bitmapcount = ATTR_BIT_MAP_COUNT; - attrList.commonattr = ATTR_CMN_FNDRINFO; - - FinderInfoAttrBuf attrBuf; - if (getattrlist(path, &attrList, &attrBuf, sizeof(attrBuf), 0) < 0) - return false; - - finfo_merge(attrBuf.finderInfo, attrBuf.finderInfo, finfo, is_dir ? kNativeDInfoMask : kNativeFInfoMask); - if (fxinfo) - finfo_merge(attrBuf.extendedFinderInfo, attrBuf.extendedFinderInfo, fxinfo, is_dir ? kNativeDXInfoMask : kNativeFXInfoMask); - - attrList.commonattr = ATTR_CMN_FNDRINFO; - if (setattrlist(path, &attrList, attrBuf.finderInfo, 2 * SIZEOF_FInfo, 0) < 0) - return false; - return true; -} - -void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Extract native Finder info flags - FinderInfo nat_finfo, nat_fxinfo; - const uint8 *emu_finfo = Mac2HostAddr(finfo); - const uint8 *emu_fxinfo = fxinfo ? Mac2HostAddr(fxinfo) : NULL; - finfo_split(nat_finfo, emu_finfo, is_dir ? kNativeDInfoMask : kNativeFInfoMask); - if (fxinfo) - finfo_split(nat_fxinfo, emu_fxinfo, is_dir ? kNativeDXInfoMask : kNativeFXInfoMask); - - // Update Finder info file (all flags) - if (USE_XATTRS) - set_finfo_to_xattr(path, emu_finfo, emu_fxinfo); - else - set_finfo_to_helper(path, emu_finfo, emu_fxinfo); - - // Update native Finder info flags - set_finfo_to_native(path, nat_finfo, nat_fxinfo, is_dir); -} - - -/* - * Resource fork emulation functions - */ - -uint32 get_rfork_size(const char *path) -{ - // Open resource file - int fd = open_rsrc(path, O_RDONLY); - if (fd < 0) - return 0; - - // Get size - off_t size = lseek(fd, 0, SEEK_END); - - // Close file and return size - close(fd); - return size < 0 ? 0 : size; -} - -int open_rfork(const char *path, int flag) -{ - return open_rsrc(path, flag); -} - -void close_rfork(const char *path, int fd) -{ - close(fd); -} - - -/* - * Read "length" bytes from file to "buffer", - * returns number of bytes read (or -1 on error) - */ - -ssize_t extfs_read(int fd, void *buffer, size_t length) -{ - return read(fd, buffer, length); -} - - -/* - * Write "length" bytes from "buffer" to file, - * returns number of bytes written (or -1 on error) - */ - -ssize_t extfs_write(int fd, void *buffer, size_t length) -{ - return write(fd, buffer, length); -} - - -/* - * Remove file/directory (and associated helper files), - * returns false on error (and sets errno) - */ - -bool extfs_remove(const char *path) -{ - // Remove helpers first, don't complain if this fails - char helper_path[MAX_PATH_LENGTH]; - make_finf_path(path, helper_path, false); - remove(helper_path); - make_rsrc_path(path, helper_path); - remove(helper_path); - - // Now remove file or directory (and helper directories in the directory) - if (remove(path) < 0) { - if (errno == EISDIR || errno == ENOTEMPTY) { - helper_path[0] = 0; - strncpy(helper_path, path, MAX_PATH_LENGTH-1); - add_path_component(helper_path, ".finf"); - rmdir(helper_path); - return rmdir(path) == 0; - } else - return false; - } - return true; -} - - -/* - * Rename/move file/directory (and associated helper files), - * returns false on error (and sets errno) - */ - -bool extfs_rename(const char *old_path, const char *new_path) -{ - // Rename helpers first, don't complain if this fails - char old_helper_path[MAX_PATH_LENGTH], new_helper_path[MAX_PATH_LENGTH]; - make_finf_path(old_path, old_helper_path, false); - make_finf_path(new_path, new_helper_path, false); - create_finf_dir(new_path); - rename(old_helper_path, new_helper_path); - make_rsrc_path(old_path, old_helper_path); - make_rsrc_path(new_path, new_helper_path); - rename(old_helper_path, new_helper_path); - - // Now rename file - return rename(old_path, new_path) == 0; -} - - -/* - * Strings (filenames) conversion - */ - -// Convert string in the specified source and target encodings -const char *convert_string(const char *str, CFStringEncoding from, CFStringEncoding to) -{ - const char *ostr = str; - CFStringRef cfstr = CFStringCreateWithCString(NULL, str, from); - if (cfstr) { - static char buffer[MAX_PATH_LENGTH]; - memset(buffer, 0, sizeof(buffer)); - if (CFStringGetCString(cfstr, buffer, sizeof(buffer), to)) - ostr = buffer; - CFRelease(cfstr); - } - return ostr; -} - -// Convert from the host OS filename encoding to MacRoman -const char *host_encoding_to_macroman(const char *filename) -{ - return convert_string(filename, kCFStringEncodingUTF8, kCFStringEncodingMacRoman); -} - -// Convert from MacRoman to host OS filename encoding -const char *macroman_to_host_encoding(const char *filename) -{ - return convert_string(filename, kCFStringEncodingMacRoman, kCFStringEncodingUTF8); -} diff --git a/BasiliskII/src/MacOSX/macos_util_macosx.h b/BasiliskII/src/MacOSX/macos_util_macosx.h deleted file mode 100644 index 47c07859..00000000 --- a/BasiliskII/src/MacOSX/macos_util_macosx.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * $Id$ - * - * macos_util_macosx.h - Work around clashes with the enums in - * Based on: - * - * macos_util.h - MacOS definitions/utility functions - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef MACOS_UTIL_H -#define MACOS_UTIL_H - -#include "cpu_emulation.h" - -#import - -/* - * Queues - */ - -enum { // QElem struct - qLink = 0, - qType = 4, - qData = 6 -}; - -enum { // QHdr struct - qFlags = 0, - qHead = 2, - qTail = 6 -}; - - -/* - * Definitions for Device Manager - */ - -// Misc constants - -enum { // IOParam struct - ioTrap = 6, - ioCmdAddr = 8, - ioCompletion = 12, - ioResult = 16, - ioNamePtr = 18, - ioVRefNum = 22, - ioRefNum = 24, - ioVersNum = 26, - ioPermssn = 27, - ioMisc = 28, - ioBuffer = 32, - ioReqCount = 36, - ioActCount = 40, - ioPosMode = 44, - ioPosOffset = 46, - ioWPosOffset = 46, // Wide positioning offset when ioPosMode has kWidePosOffsetBit set - SIZEOF_IOParam = 50 -}; - -enum { // CntrlParam struct - csCode = 26, - csParam = 28 -}; - -enum { // DrvSts struct - dsTrack = 0, - dsWriteProt = 2, - dsDiskInPlace = 3, - dsInstalled = 4, - dsSides = 5, - dsQLink = 6, - dsQType = 10, - dsQDrive = 12, - dsQRefNum = 14, - dsQFSID = 16, - dsTwoSideFmt = 18, - dsNewIntf = 19, - dsDiskErrs = 20, - dsMFMDrive = 22, - dsMFMDisk = 23, - dsTwoMegFmt = 24 -}; - -enum { // DrvSts2 struct - dsDriveSize = 18, - dsDriveS1 = 20, - dsDriveType = 22, - dsDriveManf = 24, - dsDriveChar = 26, - dsDriveMisc = 28, - SIZEOF_DrvSts = 30 -}; - -enum { // DCtlEntry struct - dCtlDriver = 0, - dCtlFlags = 4, - dCtlQHdr = 6, - dCtlPosition = 16, - dCtlStorage = 20, - dCtlRefNum = 24, - dCtlCurTicks = 26, - dCtlWindow = 30, - dCtlDelay = 34, - dCtlEMask = 36, - dCtlMenu = 38, - dCtlSlot = 40, - dCtlSlotId = 41, - dCtlDevBase = 42, - dCtlOwner = 46, - dCtlExtDev = 50, - dCtlFillByte = 51, - dCtlNodeID = 52 -}; - - -/* - * Definitions for Deferred Task Manager - */ - -enum { // DeferredTask struct - dtFlags = 6, - dtAddr = 8, - dtParam = 12, - dtReserved = 16 -}; - - -// Definitions for DebugUtil() Selector -enum { - duDebuggerGetMax = 0, - duDebuggerEnter = 1, - duDebuggerExit = 2, - duDebuggerPoll = 3, - duGetPageState = 4, - duPageFaultFatal = 5, - duDebuggerLockMemory = 6, - duDebuggerUnlockMemory = 7, - duEnterSupervisorMode = 8 -}; - -// Functions -extern void EnqueueMac(uint32 elem, uint32 list); // Enqueue QElem in list -extern int FindFreeDriveNumber(int num); // Find first free drive number, starting at "num" -extern void MountVolume(void *fh); // Mount volume with given file handle (see sys.h) -extern void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size); // Calculate disk image file layout given file size and first 256 data bytes -extern uint32 DebugUtil(uint32 Selector); // DebugUtil() Replacement -extern uint32 TimeToMacTime(time_t t); // Convert time_t value to MacOS time - -// Construct four-character-code -#define FOURCC(a,b,c,d) (((uint32)(a) << 24) | ((uint32)(b) << 16) | ((uint32)(c) << 8) | (uint32)(d)) - -// Emulator identification codes (4 and 2 characters) -const uint32 EMULATOR_ID_4 = 0x62617369; // 'basi' -const uint16 EMULATOR_ID_2 = 0x6261; // 'ba' - -// Test if basic MacOS initializations (of the ROM) are done -static inline bool HasMacStarted(void) -{ - return ReadMacInt32(0xcfc) == FOURCC('W','L','S','C'); // Mac warm start flag -} - -#endif diff --git a/BasiliskII/src/MacOSX/main_macosx.h b/BasiliskII/src/MacOSX/main_macosx.h deleted file mode 100644 index 15fdda96..00000000 --- a/BasiliskII/src/MacOSX/main_macosx.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * main_macosx.h - Prototypes for Mac OS X general definitions - * - * $Id$ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -bool InitEmulator (); -void QuitEmuNoExit(); - - -extern void ErrorAlert (const char *text); -extern void WarningAlert(const char *text); -extern bool ChoiceAlert (const char *text, const char *pos, const char *neg); diff --git a/BasiliskII/src/MacOSX/main_macosx.mm b/BasiliskII/src/MacOSX/main_macosx.mm deleted file mode 100644 index abb046c1..00000000 --- a/BasiliskII/src/MacOSX/main_macosx.mm +++ /dev/null @@ -1,744 +0,0 @@ -/* - * $Id$ - * - * main_macosx.mm - Startup code for MacOS X - * Based (in a small way) on the default main.m, - and on Basilisk's main_unix.cpp - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import -#undef check - -#define PTHREADS // Why is this here? -#include "sysdeps.h" - -#ifdef HAVE_PTHREADS -# include -#endif - -#if REAL_ADDRESSING || DIRECT_ADDRESSING -# include -#endif - -#include -using std::string; - -#include "cpu_emulation.h" -#include "sys.h" -#include "rom_patches.h" -#include "xpram.h" -#include "video.h" -#include "prefs.h" -#include "prefs_editor.h" -#include "macos_util_macosx.h" -#include "user_strings.h" -#include "version.h" -#include "main.h" -#include "vm_alloc.h" -#include "sigsegv.h" - -#if USE_JIT -extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp -#endif - -#ifdef ENABLE_MON -# include "mon.h" -#endif - -#define DEBUG 0 -#include "debug.h" - - -#include "main_macosx.h" // To bridge between main() and misc. classes - - -// Constants -const char ROM_FILE_NAME[] = "ROM"; -const int SCRATCH_MEM_SIZE = 0x10000; // Size of scratch memory area - - -static char *bundle = NULL; // If in an OS X application bundle, its path - - -// CPU and FPU type, addressing mode -int CPUType; -bool CPUIs68060; -int FPUType; -bool TwentyFourBitAddressing; - - -// Global variables - -#ifdef HAVE_PTHREADS - -static pthread_mutex_t intflag_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to protect InterruptFlags -#define LOCK_INTFLAGS pthread_mutex_lock(&intflag_lock) -#define UNLOCK_INTFLAGS pthread_mutex_unlock(&intflag_lock) - -#else - -#define LOCK_INTFLAGS -#define UNLOCK_INTFLAGS - -#endif - -#if USE_SCRATCHMEM_SUBTERFUGE -uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes -#endif - -#ifdef ENABLE_MON -static struct sigaction sigint_sa; // sigaction for SIGINT handler -static void sigint_handler(...); -#endif - -#if REAL_ADDRESSING -static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped -#endif - - -/* - * Helpers to map memory that can be accessed from the Mac side - */ - -// NOTE: VM_MAP_32BIT is only used when compiling a 64-bit JIT on specific platforms -void *vm_acquire_mac(size_t size) -{ - return vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); -} - -static int vm_acquire_mac_fixed(void *addr, size_t size) -{ - return vm_acquire_fixed(addr, size, VM_MAP_DEFAULT | VM_MAP_32BIT); -} - - -/* - * SIGSEGV handler - */ - -static sigsegv_return_t sigsegv_handler(sigsegv_info_t *sip) -{ - const uintptr fault_address = (uintptr)sigsegv_get_fault_address(sip); -#if ENABLE_VOSF - // Handle screen fault - extern bool Screen_fault_handler(sigsegv_info_t *sip); - if (Screen_fault_handler(sip)) - return SIGSEGV_RETURN_SUCCESS; -#endif - -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - // Ignore writes to ROM - if (((uintptr)fault_address - (uintptr)ROMBaseHost) < ROMSize) - return SIGSEGV_RETURN_SKIP_INSTRUCTION; - - // Ignore all other faults, if requested - if (PrefsFindBool("ignoresegv")) - return SIGSEGV_RETURN_SKIP_INSTRUCTION; -#endif - - return SIGSEGV_RETURN_FAILURE; -} - -/* - * Dump state when everything went wrong after a SEGV - */ - -static void sigsegv_dump_state(sigsegv_info_t *sip) -{ - const sigsegv_address_t fault_address = sigsegv_get_fault_address(sip); - const sigsegv_address_t fault_instruction = sigsegv_get_fault_instruction_address(sip); - fprintf(stderr, "Caught SIGSEGV at address %p", fault_address); - if (fault_instruction != SIGSEGV_INVALID_ADDRESS) - fprintf(stderr, " [IP=%p]", fault_instruction); - fprintf(stderr, "\n"); - uaecptr nextpc; - extern void m68k_dumpstate(uaecptr *nextpc); - m68k_dumpstate(&nextpc); -#if USE_JIT && JIT_DEBUG - extern void compiler_dumpstate(void); - compiler_dumpstate(); -#endif - VideoQuitFullScreen(); -#ifdef ENABLE_MON - char *arg[4] = {"mon", "-m", "-r", NULL}; - mon(3, arg); -#endif - QuitEmulator(); -} - - -/* - * Screen fault handler - */ - -bool Screen_fault_handler(sigsegv_info_t *sip) -{ - return true; -} - - -/* - * Main program - */ - -static void usage(const char *prg_name) -{ - printf( - "Usage: %s [OPTION...]\n" - "\nUnix options:\n" - " --config FILE\n read/write configuration from/to FILE\n" - " --break ADDRESS\n set ROM breakpoint\n" - " --rominfo\n dump ROM information\n", prg_name - ); - LoadPrefs(NULL); // read the prefs file so PrefsPrintUsage() will print the correct default values - PrefsPrintUsage(); - exit(0); -} - -int main(int argc, char **argv) -{ - const char *vmdir = NULL; - char str[256]; - - // Initialize variables - RAMBaseHost = NULL; - ROMBaseHost = NULL; - srand(time(NULL)); - tzset(); - - // Print some info - printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - printf(" %s\n", GetString(STR_ABOUT_TEXT2)); - - // Parse command line arguments - for (int i=1; i i) { - k -= i; - for (int j=i+k; j 1023*1024*1024) // Cap to 1023MB (APD crashes at 1GB) - RAMSize = 1023*1024*1024; - -#if REAL_ADDRESSING || DIRECT_ADDRESSING - RAMSize = RAMSize & -getpagesize(); // Round down to page boundary -#endif - - // Initialize VM system - vm_init(); - -#if REAL_ADDRESSING - // Flag: RAM and ROM are contigously allocated from address 0 - bool memory_mapped_from_zero = false; - - // Make sure to map RAM & ROM at address 0 only on platforms that - // supports linker scripts to relocate the Basilisk II executable - // above 0x70000000 -#if HAVE_LINKER_SCRIPT - const bool can_map_all_memory = true; -#else - const bool can_map_all_memory = false; -#endif - - // Try to allocate all memory from 0x0000, if it is not known to crash - if (can_map_all_memory && (vm_acquire_mac_fixed(0, RAMSize + 0x100000) == 0)) { - D(bug("Could allocate RAM and ROM from 0x0000\n")); - memory_mapped_from_zero = true; - } - -#ifndef PAGEZERO_HACK - // Otherwise, just create the Low Memory area (0x0000..0x2000) - else if (vm_acquire_mac_fixed(0, 0x2000) == 0) { - D(bug("Could allocate the Low Memory globals\n")); - lm_area_mapped = true; - } - - // Exit on failure - else { - sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno)); - ErrorAlert(str); - QuitEmulator(); - } -#endif -#else - *str = 0; // Eliminate unused variable warning -#endif /* REAL_ADDRESSING */ - - // Create areas for Mac RAM and ROM -#if REAL_ADDRESSING - if (memory_mapped_from_zero) { - RAMBaseHost = (uint8 *)0; - ROMBaseHost = RAMBaseHost + RAMSize; - } - else -#endif - { - uint8 *ram_rom_area = (uint8 *)vm_acquire_mac(RAMSize + 0x100000); - if (ram_rom_area == VM_MAP_FAILED) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - RAMBaseHost = ram_rom_area; - ROMBaseHost = RAMBaseHost + RAMSize; - } - -#if USE_SCRATCHMEM_SUBTERFUGE - // Allocate scratch memory - ScratchMem = (uint8 *)vm_acquire_mac(SCRATCH_MEM_SIZE); - if (ScratchMem == VM_MAP_FAILED) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - ScratchMem += SCRATCH_MEM_SIZE/2; // ScratchMem points to middle of block -#endif - -#if DIRECT_ADDRESSING - // RAMBaseMac shall always be zero - MEMBaseDiff = (uintptr)RAMBaseHost; - RAMBaseMac = 0; - ROMBaseMac = Host2MacAddr(ROMBaseHost); -#endif -#if REAL_ADDRESSING - RAMBaseMac = Host2MacAddr(RAMBaseHost); - ROMBaseMac = Host2MacAddr(ROMBaseHost); -#endif - D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac)); - D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac)); - - // Get rom file path from preferences - const char *rom_path = PrefsFindString("rom"); - if ( ! rom_path ) - if ( bundle ) - WarningAlert("No rom pathname set. Trying BasiliskII.app/ROM"); - else - WarningAlert("No rom pathname set. Trying ./ROM"); - - // Load Mac ROM - int rom_fd = open(rom_path ? rom_path : ROM_FILE_NAME, O_RDONLY); - if (rom_fd < 0) { - ErrorAlert(STR_NO_ROM_FILE_ERR); - QuitEmulator(); - } - printf(GetString(STR_READING_ROM_FILE)); - ROMSize = lseek(rom_fd, 0, SEEK_END); - if (ROMSize != 64*1024 && ROMSize != 128*1024 && ROMSize != 256*1024 && ROMSize != 512*1024 && ROMSize != 1024*1024) { - ErrorAlert(STR_ROM_SIZE_ERR); - close(rom_fd); - QuitEmulator(); - } - lseek(rom_fd, 0, SEEK_SET); - if (read(rom_fd, ROMBaseHost, ROMSize) != (ssize_t)ROMSize) { - ErrorAlert(STR_ROM_FILE_READ_ERR); - close(rom_fd); - QuitEmulator(); - } - - - // Initialize everything - if (!InitAll(vmdir)) - QuitEmulator(); - D(bug("Initialization complete\n")); - - -#ifdef ENABLE_MON - // Setup SIGINT handler to enter mon - sigemptyset(&sigint_sa.sa_mask); - sigint_sa.sa_handler = (void (*)(int))sigint_handler; - sigint_sa.sa_flags = 0; - sigaction(SIGINT, &sigint_sa, NULL); -#endif - - - return YES; -} - -#undef QuitEmulator() - - -/* - * Quit emulator - */ - -void QuitEmuNoExit() -{ - D(bug("QuitEmulator\n")); - - // Exit 680x0 emulation - Exit680x0(); - - // Deinitialize everything - ExitAll(); - - // Free ROM/RAM areas - if (RAMBaseHost != VM_MAP_FAILED) { - vm_release(RAMBaseHost, RAMSize + 0x100000); - RAMBaseHost = NULL; - ROMBaseHost = NULL; - } - -#if USE_SCRATCHMEM_SUBTERFUGE - // Delete scratch memory area - if (ScratchMem != (uint8 *)VM_MAP_FAILED) { - vm_release((void *)(ScratchMem - SCRATCH_MEM_SIZE/2), SCRATCH_MEM_SIZE); - ScratchMem = NULL; - } -#endif - -#if REAL_ADDRESSING - // Delete Low Memory area - if (lm_area_mapped) - vm_release(0, 0x2000); -#endif - - // Exit VM wrappers - vm_exit(); - - // Exit system routines - SysExit(); - - // Exit preferences - PrefsExit(); -} - -void QuitEmulator(void) -{ - QuitEmuNoExit(); - - // Stop run loop? - [NSApp terminate: nil]; - - exit(0); -} - - -/* - * Code was patched, flush caches if neccessary (i.e. when using a real 680x0 - * or a dynamically recompiling emulator) - */ - -void FlushCodeCache(void *start, uint32 size) -{ -#if USE_JIT - if (UseJIT) - flush_icache_range((uint8 *)start, size); -#endif -} - - -/* - * SIGINT handler, enters mon - */ - -#ifdef ENABLE_MON -static void sigint_handler(...) -{ - uaecptr nextpc; - extern void m68k_dumpstate(uaecptr *nextpc); - m68k_dumpstate(&nextpc); - VideoQuitFullScreen(); - char *arg[4] = {"mon", "-m", "-r", NULL}; - mon(3, arg); - QuitEmulator(); -} -#endif - - -#ifdef HAVE_PTHREADS -/* - * Pthread configuration - */ - -void Set_pthread_attr(pthread_attr_t *attr, int priority) -{ - pthread_attr_init(attr); -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - // Some of these only work for superuser - if (geteuid() == 0) { - pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedpolicy(attr, SCHED_FIFO); - struct sched_param fifo_param; - fifo_param.sched_priority = ((sched_get_priority_min(SCHED_FIFO) - + sched_get_priority_max(SCHED_FIFO)) - / 2 + priority); - pthread_attr_setschedparam(attr, &fifo_param); - } - if (pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM) != 0) { -#ifdef PTHREAD_SCOPE_BOUND_NP - // If system scope is not available (eg. we're not running - // with CAP_SCHED_MGT capability on an SGI box), try bound - // scope. It exposes pthread scheduling to the kernel, - // without setting realtime priority. - pthread_attr_setscope(attr, PTHREAD_SCOPE_BOUND_NP); -#endif - } -#endif -} -#endif // HAVE_PTHREADS - - -/* - * Mutexes - */ - -#ifdef HAVE_PTHREADS - -struct B2_mutex { - B2_mutex() { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - // Initialize the mutex for priority inheritance -- - // required for accurate timing. -#ifdef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL - pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); -#endif -#if defined(HAVE_PTHREAD_MUTEXATTR_SETTYPE) && defined(PTHREAD_MUTEX_NORMAL) - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); -#endif -#ifdef HAVE_PTHREAD_MUTEXATTR_SETPSHARED - pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE); -#endif - pthread_mutex_init(&m, &attr); - pthread_mutexattr_destroy(&attr); - } - ~B2_mutex() { - pthread_mutex_trylock(&m); // Make sure it's locked before - pthread_mutex_unlock(&m); // unlocking it. - pthread_mutex_destroy(&m); - } - pthread_mutex_t m; -}; - -B2_mutex *B2_create_mutex(void) -{ - return new B2_mutex; -} - -void B2_lock_mutex(B2_mutex *mutex) -{ - pthread_mutex_lock(&mutex->m); -} - -void B2_unlock_mutex(B2_mutex *mutex) -{ - pthread_mutex_unlock(&mutex->m); -} - -void B2_delete_mutex(B2_mutex *mutex) -{ - delete mutex; -} - -#else - -struct B2_mutex { - int dummy; -}; - -B2_mutex *B2_create_mutex(void) -{ - return new B2_mutex; -} - -void B2_lock_mutex(B2_mutex *mutex) -{ -} - -void B2_unlock_mutex(B2_mutex *mutex) -{ -} - -void B2_delete_mutex(B2_mutex *mutex) -{ - delete mutex; -} - -#endif - - -/* - * Interrupt flags (must be handled atomically!) - */ - -uint32 InterruptFlags = 0; - -void SetInterruptFlag(uint32 flag) -{ - LOCK_INTFLAGS; - InterruptFlags |= flag; - UNLOCK_INTFLAGS; -} - -void ClearInterruptFlag(uint32 flag) -{ - LOCK_INTFLAGS; - InterruptFlags &= ~flag; - UNLOCK_INTFLAGS; -} - - -/* - * Display error alert - */ - -void ErrorAlert(const char *text) -{ - NSString *title = [NSString stringWithCString: - GetString(STR_ERROR_ALERT_TITLE) ]; - NSString *error = [NSString stringWithCString: text]; - NSString *button = [NSString stringWithCString: GetString(STR_QUIT_BUTTON) ]; - - NSLog(error); - if ( PrefsFindBool("nogui") ) - return; - VideoQuitFullScreen(); - NSRunCriticalAlertPanel(title, error, button, nil, nil); -} - - -/* - * Display warning alert - */ - -void WarningAlert(const char *text) -{ - NSString *title = [NSString stringWithCString: - GetString(STR_WARNING_ALERT_TITLE) ]; - NSString *warning = [NSString stringWithCString: text]; - NSString *button = [NSString stringWithCString: GetString(STR_OK_BUTTON) ]; - - NSLog(warning); - if ( PrefsFindBool("nogui") ) - return; - VideoQuitFullScreen(); - NSRunAlertPanel(title, warning, button, nil, nil); -} - - -/* - * Display choice alert - */ - -bool ChoiceAlert(const char *text, const char *pos, const char *neg) -{ - NSString *title = [NSString stringWithCString: - GetString(STR_WARNING_ALERT_TITLE) ]; - NSString *warning = [NSString stringWithCString: text]; - NSString *yes = [NSString stringWithCString: pos]; - NSString *no = [NSString stringWithCString: neg]; - - return NSRunInformationalAlertPanel(title, warning, yes, no, nil); -} diff --git a/BasiliskII/src/MacOSX/misc_macosx.h b/BasiliskII/src/MacOSX/misc_macosx.h deleted file mode 100644 index b22f1c10..00000000 --- a/BasiliskII/src/MacOSX/misc_macosx.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * $Id$ - * - * misc_macosx.h - Some prototypes of functions defined in misc_macosx.mm - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if defined(__APPLE__) && defined(__MACH__) - // This means we are on Mac OS X of some sort -#endif - -extern void ErrorSheet (NSString *msg, NSWindow *win), - ErrorSheet (NSString *msg1, NSString *msg2, - NSString *button, NSWindow *win), - WarningSheet (NSString *message,NSWindow *win), - WarningSheet (NSString *msg1, NSString *msg2, - NSString *button, NSWindow *win), - InfoSheet (NSString *msg, NSWindow *win), - InfoSheet (NSString *msg1, NSString *msg2, - NSString *button, NSWindow *win), - EndSheet (NSWindow * window); - -extern int frequencyToTickDelay (float frequency); diff --git a/BasiliskII/src/MacOSX/misc_macosx.mm b/BasiliskII/src/MacOSX/misc_macosx.mm deleted file mode 100644 index f214261e..00000000 --- a/BasiliskII/src/MacOSX/misc_macosx.mm +++ /dev/null @@ -1,112 +0,0 @@ -/* - * $Id$ - * - * misc_macosx.m - Miscellaneous Mac OS X routines. - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import - -#import "sysdeps.h" // Types used in Basilisk C++ code - -#import - -#define DEBUG 0 -#import - - - -/************************************************************************/ -/* Display Errors and Warnings in a sliding thingy attached to a */ -/* particular window, instead of as a separate window (Panel or Dialog) */ -/************************************************************************/ - -void ErrorSheet (NSString * message, NSWindow * window) -{ - NSLog(message); - NSBeginCriticalAlertSheet(message, nil, nil, nil, window, - nil, nil, nil, NULL, @""); - while ( [window attachedSheet] ) - sleep(1); - //[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow: 1.0]]; -} - -void ErrorSheet (NSString * message1, NSString * message2, - NSString * button, NSWindow * window) -{ - NSLog(message1); - NSLog(message2); - NSBeginCriticalAlertSheet(message1, button, nil, nil, window, - nil, nil, nil, NULL, message2); - while ( [window attachedSheet] ) - sleep(1); - //[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow: 1.0]]; -} - - -void WarningSheet (NSString * message, NSWindow * window) -{ - NSLog(message); - NSBeginAlertSheet(message, nil, nil, nil, window, - nil, nil, nil, NULL, @""); -} - -void WarningSheet (NSString * message1, NSString * message2, - NSString * button, NSWindow * window) -{ - NSLog(message1); - NSLog(message2); - NSBeginAlertSheet(message1, button, nil, nil, window, - nil, nil, nil, NULL, message2); -} - - -void InfoSheet (NSString * message, NSWindow * window) -{ - NSLog(message); - NSBeginInformationalAlertSheet(message, nil, nil, nil, window, - nil, nil, nil, NULL, @""); -} - -void InfoSheet (NSString * message1, NSString * message2, - NSString * button, NSWindow * window) -{ - NSLog(message1); - NSLog(message2); - NSBeginInformationalAlertSheet(message1, nil, nil, nil, window, - nil, nil, nil, NULL, message2); -} - -void EndSheet (NSWindow * window) -{ - [[window attachedSheet] close]; -} - -// Convert a frequency (i.e. updates per second) to a 60hz tick delay, and update prefs -int frequencyToTickDelay (float freq) -{ - if ( freq == 0.0 ) - return 0; - else - { - int delay = (int) (60.0 / freq); - - PrefsReplaceInt32("frameskip", delay); - return delay; - } -} diff --git a/BasiliskII/src/MacOSX/prefs_macosx.cpp b/BasiliskII/src/MacOSX/prefs_macosx.cpp deleted file mode 100644 index 74000fd7..00000000 --- a/BasiliskII/src/MacOSX/prefs_macosx.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * $Id$ - * - * prefs_macosx.cpp - Preferences handling, Mac OS X specific. - * Based on prefs_unix.cpp - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include - -#include -using std::string; - -#include "prefs.h" - - -// Platform-specific preferences items -prefs_desc platform_prefs_items[] = { -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - {"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"}, -#endif - {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, - {NULL, TYPE_END, false, NULL} // End of list -}; - - -// Prefs file name and path -const char PREFS_FILE_NAME[] = ".basilisk_ii_prefs"; -string UserPrefsPath; -static string prefs_path; - - -/* - * Load preferences from settings file - */ - -void LoadPrefs(const char *vmdir) -{ - if (vmdir) { - prefs_path = string(vmdir) + '/' + string("prefs"); - FILE *prefs = fopen(prefs_path.c_str(), "r"); - if (!prefs) { - printf("No file at %s found.\n", prefs_path.c_str()); - exit(1); - } - LoadPrefsFromStream(prefs); - fclose(prefs); - return; - } - - // Construct prefs path - if (UserPrefsPath.empty()) { - char *home = getenv("HOME"); - if (home) - prefs_path = string(home) + '/'; - prefs_path += PREFS_FILE_NAME; - UserPrefsPath = prefs_path; - } else - prefs_path = UserPrefsPath; - - // Read preferences from settings file - FILE *f = fopen(prefs_path.c_str(), "r"); - if (f != NULL) { - - // Prefs file found, load settings - LoadPrefsFromStream(f); - fclose(f); - - } else { - - // No prefs file, save defaults - SavePrefs(); - } - - // Remove Nigel's bad old serial prefs - - const char *str; - int tmp = 0; - - if ( (str = PrefsFindString("seriala") ) != NULL - && strcmp(str, "/dev/ttys0") == 0 ) - { - puts("Deleting invalid prefs item 'seriala /dev/ttys0'"); - PrefsRemoveItem("seriala", 1); - } - - if ( (str = PrefsFindString("serialb") ) != NULL - && strcmp(str, "/dev/ttys1") == 0 ) - { - puts("Deleting invalid prefs item 'serialb /dev/ttys1'"); - PrefsRemoveItem("serialb", 1); - } - - // Floppy & cdrom prefs are always removed - - // we search for them each time the emulator is started - - while ( (str = PrefsFindString("floppy", tmp) ) != NULL ) - PrefsRemoveItem("floppy", tmp); - - while ( (str = PrefsFindString("cdrom", tmp) ) != NULL ) - PrefsRemoveItem("cdrom", tmp); -} - - -/* - * Save preferences to settings file - */ - -void SavePrefs(void) -{ - FILE *f; - if ((f = fopen(prefs_path.c_str(), "w")) != NULL) { - SavePrefsToStream(f); - fclose(f); - } -} - - -/* - * Add defaults of platform-specific prefs items - * You may also override the defaults set in PrefsInit() - */ - -void AddPlatformPrefsDefaults(void) -{ - PrefsReplaceString("extfs", getenv("HOME")); - PrefsReplaceString("screen", "win/512/384/16"); -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - PrefsAddBool("ignoresegv", false); -#endif - PrefsAddBool("idlewait", true); -} diff --git a/BasiliskII/src/MacOSX/utils_macosx.h b/BasiliskII/src/MacOSX/utils_macosx.h deleted file mode 100644 index fc2c83c6..00000000 --- a/BasiliskII/src/MacOSX/utils_macosx.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * utils_macosx.h - Mac OS X utility functions. - * - * Copyright (C) 2011 Alexei Svitkine - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef UTILS_MACOSX_H -#define UTILS_MACOSX_H - -// Invokes the specified function with an NSAutoReleasePool in place. -void NSAutoReleasePool_wrap(void (*fn)(void)); - -#endif diff --git a/BasiliskII/src/MacOSX/utils_macosx.mm b/BasiliskII/src/MacOSX/utils_macosx.mm deleted file mode 100644 index b653638d..00000000 --- a/BasiliskII/src/MacOSX/utils_macosx.mm +++ /dev/null @@ -1,30 +0,0 @@ -/* - * utils_macosx.mm - Mac OS X utility functions. - * - * Copyright (C) 2011 Alexei Svitkine - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include "utils_macosx.h" - -// This is used from video_sdl.cpp. -void NSAutoReleasePool_wrap(void (*fn)(void)) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - fn(); - [pool release]; -} diff --git a/BasiliskII/src/MacOSX/video_macosx.h b/BasiliskII/src/MacOSX/video_macosx.h deleted file mode 100644 index 9cecd9f2..00000000 --- a/BasiliskII/src/MacOSX/video_macosx.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * video_macosx.h - Some video constants and globals - * - * $Id$ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#import - -/* Set the strategy for drawing the bitmap in the Mac OS X window */ -//#define CGDRAWBITMAP -#if defined __i386__ -#define CGIMAGEREF -//#define NSBITMAP -#else -#define CGIMAGEREF -//#define NSBITMAP -#endif - -// Using Core Graphics is fastest when rendering 32bit data. -// Using CGImageRefs allows us to use all the bitmaps that BasiliskII supports. -// When both Basilisk II and OS X are set to 'Thousands', updating a 312x342 -// window happens at over 500fps under 10.2, and over 600fps on 10.3! - -/* When the BasiliskII video driver respects the alpha bits, set this to let us use */ -/* kCGImageAlphaPremultipliedFirst, and to have nice rounded corners on the screen. */ -//#define CG_USE_ALPHA -/* At the moment, it writes in the full 32bits :-( */ - - -#define MIN_WIDTH 512 -#define MIN_HEIGHT 384 -#define MIN_HEIGHTC 342 // For classic emulation - -#define MAX_WIDTH 1240 -#define MAX_HEIGHT 1024 - -// Display types -enum -{ - DISPLAY_OPENGL, - DISPLAY_SCREEN, - DISPLAY_WINDOW -}; - - -extern uint8 display_type, - frame_skip; -extern uint16 init_width, - init_height, - init_depth; - -extern bool parse_screen_prefs (const char *); -extern void resizeWinTo (const uint16, const uint16); - -#import -#import "EmulatorView.h" - -extern NSWindow *the_win; -extern EmulatorView *output; diff --git a/BasiliskII/src/MacOSX/video_macosx.mm b/BasiliskII/src/MacOSX/video_macosx.mm deleted file mode 100644 index d4eff082..00000000 --- a/BasiliskII/src/MacOSX/video_macosx.mm +++ /dev/null @@ -1,1123 +0,0 @@ -/* - * $Id$ - * - * video_macosx.mm - Interface between Basilisk II and Cocoa windowing. - * Based on video_amiga.cpp and video_x.cpp - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "sysdeps.h" - -#ifdef HAVE_PTHREADS -# include -#endif - -#include -#include -#include -#include "macos_util_macosx.h" -#include -#include -#include "video_macosx.h" - -#define DEBUG 0 -#define VERBOSE 0 -#include "debug.h" - -#ifdef NSBITMAP -#import -#endif - -#import // Needed for NSLog(@"") -#import "misc_macosx.h" // WarningSheet() prototype - - - -// Global variables -uint8 display_type = DISPLAY_WINDOW, // These are used by PrefsEditor - frame_skip; -uint16 init_width = MIN_WIDTH, // as well as this code - init_height = MIN_HEIGHT, - init_depth = 32; - - EmulatorView *output = nil; // Set by [EmulatorView init] - NSWindow *the_win = nil; // Set by [Emulator awakeFromNib] - -static BOOL singleDisplay = YES; - -/* - * Utility functions - */ - -static uint8 -bits_from_depth(const video_depth depth) -{ - int bits = 1 << depth; -// if (bits == 16) -// bits = 15; -// else if (bits == 32) -// bits = 24; - return bits; -} - -static const char * -colours_from_depth(const video_depth depth) -{ - switch ( depth ) - { - case VDEPTH_1BIT : return "Monochrome"; - case VDEPTH_2BIT : return "4 colours"; - case VDEPTH_4BIT : return "16 colours"; - case VDEPTH_8BIT : return "256 colours"; - case VDEPTH_16BIT: return "Thousands of colours"; - case VDEPTH_32BIT: return "Millions of colours"; - } - - return "illegal colour depth"; -} - -static const char * -colours_from_depth(const uint16 depth) -{ - return colours_from_depth(DepthModeForPixelDepth(depth) ); -} - -bool -parse_screen_prefs(const char *mode_str) -{ - if ( ! mode_str ) - { - // No screen pref was found. Supply a default: - mode_str = "win/512/384"; - } - - if (sscanf(mode_str, "win/%hd/%hd/%hd", - &init_width, &init_height, &init_depth) == 3) - display_type = DISPLAY_WINDOW; - else if (sscanf(mode_str, "win/%hd/%hd", &init_width, &init_height) == 2) - display_type = DISPLAY_WINDOW; - else if (strcmp(mode_str, "full") == 0) - display_type = DISPLAY_SCREEN; - else if (sscanf(mode_str, "full/%hd/%hd/%hd", - &init_width, &init_height, &init_depth) == 3) - display_type = DISPLAY_SCREEN; - else if (sscanf(mode_str, "full/%hd/%hd", &init_width, &init_height) == 2) - display_type = DISPLAY_SCREEN; - else if (sscanf(mode_str, "opengl/%hd/%hd/%hd", - &init_width, &init_height, &init_depth) == 3) - display_type = DISPLAY_OPENGL; - else if (sscanf(mode_str, "opengl/%hd/%hd", &init_width, &init_height) == 2) - display_type = DISPLAY_OPENGL; - else return false; - - return true; -} - -// Supported video modes -static vector VideoModes; - - -// Add mode to list of supported modes -static void -add_mode(const uint16 width, const uint16 height, - const uint32 resolution_id, const uint32 bytes_per_row, - const uint32 user_data, - const video_depth depth) -{ - vector::const_iterator i, - end = VideoModes.end(); - - for (i = VideoModes.begin(); i != end; ++i) - if ( i->x == width && i->y == height && - i->bytes_per_row == bytes_per_row && i->depth == depth ) - { - D(NSLog(@"Duplicate mode (%hdx%hdx%ld, ID %02x, new ID %02x)\n", - width, height, depth, i->resolution_id, resolution_id)); - return; - } - - video_mode mode; - - mode.x = width; - mode.y = height; - mode.resolution_id = resolution_id; - mode.bytes_per_row = bytes_per_row; - mode.user_data = user_data; - mode.depth = depth; - - D(bug("Added video mode: w=%d h=%d d=%d(%d bits)\n", - width, height, depth, bits_from_depth(depth) )); - - VideoModes.push_back(mode); -} - -// Add standard list of windowed modes for given color depth -static void add_standard_modes(const video_depth depth) -{ - D(bug("add_standard_modes: depth=%d(%d bits)\n", - depth, bits_from_depth(depth) )); - - add_mode(512, 384, 0x80, TrivialBytesPerRow(512, depth), 0, depth); - add_mode(640, 480, 0x81, TrivialBytesPerRow(640, depth), 0, depth); - add_mode(800, 600, 0x82, TrivialBytesPerRow(800, depth), 0, depth); - add_mode(832, 624, 0x83, TrivialBytesPerRow(832, depth), 0, depth); - add_mode(1024, 768, 0x84, TrivialBytesPerRow(1024, depth), 0, depth); - add_mode(1152, 768, 0x85, TrivialBytesPerRow(1152, depth), 0, depth); - add_mode(1152, 870, 0x86, TrivialBytesPerRow(1152, depth), 0, depth); - add_mode(1280, 1024, 0x87, TrivialBytesPerRow(1280, depth), 0, depth); - add_mode(1600, 1200, 0x88, TrivialBytesPerRow(1600, depth), 0, depth); -} - -// Helper function to get a 32bit int from a dictionary -static int32 getCFint32 (CFDictionaryRef dict, CFStringRef key) -{ - CFNumberRef ref = (CFNumberRef) CFDictionaryGetValue(dict, key); - - if ( ref ) - { - int32 val; - - if ( CFNumberGetValue(ref, kCFNumberSInt32Type, &val) ) - return val; - else - NSLog(@"getCFint32() - Failed to get the value %@", key); - } - else - NSLog(@"getCFint32() - Failed to get a 32bit int for %@", key); - - return 0; -} - -// Nasty hack. Under 10.1, CGDisplayAvailableModes() does not provide bytes per row, -// and the emulator doesn't like setting the bytes per row after the screen, -// so we use a lot of magic numbers here. -// This will probably fail on some video hardware. -// I have tested on my G4 PowerBook 400 and G3 PowerBook Series 292 - -static int -CGBytesPerRow(const uint16 width, const video_depth depth) -{ - if ( depth == VDEPTH_8BIT ) - switch ( width ) - { - case 640: - case 720: return 768; - case 800: - case 896: return 1024; - case 1152: return 1280; - } - - if ( width == 720 && depth == VDEPTH_16BIT) return 1536; - if ( width == 720 && depth == VDEPTH_32BIT) return 3072; - if ( width == 800 && depth == VDEPTH_16BIT) return 1792; - if ( width == 800 && depth == VDEPTH_32BIT) return 3328; - - return TrivialBytesPerRow(width, depth); -} - -static bool add_CGDirectDisplay_modes() -{ -#define kMaxDisplays 8 - CGDirectDisplayID displays[kMaxDisplays]; - CGDisplayErr err; - CGDisplayCount n; - int32 oldRes = 0, - res_id = 0x80; - - - err = CGGetActiveDisplayList(kMaxDisplays, displays, &n); - if ( err != CGDisplayNoErr ) - n = 1, displays[n] = kCGDirectMainDisplay; - - if ( n > 1 ) - singleDisplay = NO; - - for ( CGDisplayCount dc = 0; dc < n; ++dc ) - { - CGDirectDisplayID d = displays[dc]; - CFArrayRef m = CGDisplayAvailableModes(d); - - if ( ! m ) // Store the current display mode - add_mode(CGDisplayPixelsWide(d), - CGDisplayPixelsHigh(d), - res_id++, CGDisplayBytesPerRow(d), - (const uint32) d, - DepthModeForPixelDepth(CGDisplayBitsPerPixel(d))); - else - { - CFIndex nModes = CFArrayGetCount(m); - - for ( CFIndex mc = 0; mc < nModes; ++mc ) - { - CFDictionaryRef modeSpec = (CFDictionaryRef) - CFArrayGetValueAtIndex(m, mc); - - int32 bpp = getCFint32(modeSpec, kCGDisplayBitsPerPixel); - int32 height = getCFint32(modeSpec, kCGDisplayHeight); - int32 width = getCFint32(modeSpec, kCGDisplayWidth); -#ifdef MAC_OS_X_VERSION_10_2 - int32 bytes = getCFint32(modeSpec, kCGDisplayBytesPerRow); -#else - int32 bytes = 0; -#endif - video_depth depth = DepthModeForPixelDepth(bpp); - - if ( ! bpp || ! height || ! width ) - { - NSLog(@"Could not get details of mode %d, display %d", - mc, dc); - return false; - } -#if VERBOSE - else - NSLog(@"Display %ld, spec = %@", d, modeSpec); -#endif - - if ( ! bytes ) - { - NSLog(@"Could not get bytes per row, guessing"); - bytes = CGBytesPerRow(width, depth); - } - - if ( ! oldRes ) - oldRes = width * height; - else - if ( oldRes != width * height ) - { - oldRes = width * height; - ++res_id; - } - - add_mode(width, height, res_id, bytes, (const uint32) d, depth); - } - } - } - - return true; -} - -#ifdef CG_USE_ALPHA -// memset() by long instead of byte - -static void memsetl (long *buffer, long pattern, size_t length) -{ - long *buf = (long *) buffer, - *end = buf + length/4; - - while ( ++buf < end ) - *buf = pattern; -} - -// Sets the alpha channel in a image to full on, except for the corners - -static void mask_buffer (void *buffer, size_t width, size_t size) -{ - long *bufl = (long *) buffer; - char *bufc = (char *) buffer; - - - memsetl(bufl, 0xFF000000, size); - - - // Round upper-left corner - *bufl = 0, *bufc+4 = 0; // XXXXX - bufc += width, *bufc++ = 0, *bufc++ = 0, *bufc++ = 0; // XXX - bufc += width, *bufc++ = 0, *bufc = 0; // XX - bufc += width, *bufc = 0; // X - bufc += width, *bufc = 0; // X - - - NSLog(@"Masked buffer"); -} -#endif - -// monitor_desc subclass for Mac OS X displays - -class OSX_monitor : public monitor_desc -{ - public: - OSX_monitor(const vector &available_modes, - video_depth default_depth, - uint32 default_id); - - virtual void set_palette(uint8 *pal, int num); - virtual void switch_to_current_mode(void); - - void set_mac_frame_buffer(const video_mode mode); - - void video_close(void); - bool video_open (const video_mode &mode); - - - private: - bool init_opengl(const video_mode &mode); - bool init_screen( video_mode &mode); - bool init_window(const video_mode &mode); - - -#ifdef CGIMAGEREF - CGColorSpaceRef colourSpace; - uint8 *colourTable; - CGImageRef imageRef; - CGDataProviderRef provider; - short x, y, bpp, depth, bpr; -#endif -#ifdef NSBITMAP - NSBitmapImageRep *bitmap; -#endif - void *the_buffer; - - - // These record changes we made in setting full screen mode, - // so that we can set the display back as it was again. - CGDirectDisplayID theDisplay; - CFDictionaryRef originalMode, - newMode; -}; - - -OSX_monitor :: OSX_monitor (const vector &available_modes, - video_depth default_depth, - uint32 default_id) - : monitor_desc (available_modes, default_depth, default_id) -{ -#ifdef CGIMAGEREF - colourSpace = nil; - colourTable = (uint8 *) malloc(256 * 3); - imageRef = nil; - provider = nil; -#endif -#ifdef NSBITMAP - bitmap = nil; -#endif - newMode = originalMode = nil; - the_buffer = NULL; - theDisplay = nil; -}; - -// Should also have a destructor which does -//#ifdef CGIMAGEREF -// free(colourTable); -//#endif - - -// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) -void -OSX_monitor::set_mac_frame_buffer(const video_mode mode) -{ -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING - switch ( mode.depth ) - { - // case VDEPTH_15BIT: - case VDEPTH_16BIT: MacFrameLayout = FLAYOUT_HOST_555; break; - // case VDEPTH_24BIT: - case VDEPTH_32BIT: MacFrameLayout = FLAYOUT_HOST_888; break; - default : MacFrameLayout = FLAYOUT_DIRECT; - } - set_mac_frame_base(MacFrameBaseMac); - - // Set variables used by UAE memory banking - MacFrameBaseHost = (uint8 *) the_buffer; - MacFrameSize = mode.bytes_per_row * mode.y; - InitFrameBufferMapping(); -#else - set_mac_frame_base((unsigned int)Host2MacAddr((uint8 *)the_buffer)); -#endif - D(bug("mac_frame_base = %08x\n", get_mac_frame_base())); -} - -static void -resizeWinBy(const short deltaX, const short deltaY) -{ - NSRect rect = [the_win frame]; - - D(bug("resizeWinBy(%d,%d) - ", deltaX, deltaY)); - D(bug("old x=%g, y=%g", rect.size.width, rect.size.height)); - - rect.size.width += deltaX; - rect.size.height += deltaY; - - D(bug(", new x=%g, y=%g\n", rect.size.width, rect.size.height)); - - [the_win setFrame: rect display: YES animate: YES]; - [the_win center]; - rect = [the_win frame]; -} - -void resizeWinTo(const uint16 newWidth, const uint16 newHeight) -{ - int deltaX = newWidth - [output width], - deltaY = newHeight - [output height]; - - D(bug("resizeWinTo(%d,%d)\n", newWidth, newHeight)); - - if ( deltaX || deltaY ) - resizeWinBy(deltaX, deltaY); -} - -// Open window -bool -OSX_monitor::init_window(const video_mode &mode) -{ - D(bug("init_window: depth=%d(%d bits)\n", - mode.depth, bits_from_depth(mode.depth) )); - - - // Set absolute mouse mode - ADBSetRelMouseMode(false); - - - // Is the window open? - if ( ! the_win ) - { - ErrorAlert(STR_OPEN_WINDOW_ERR); - return false; - } - resizeWinTo(mode.x, mode.y); - - - // Create frame buffer ("height + 2" for safety) - int the_buffer_size = mode.bytes_per_row * (mode.y + 2); - - the_buffer = calloc(the_buffer_size, 1); - if ( ! the_buffer ) - { - NSLog(@"calloc(%d) failed", the_buffer_size); - ErrorAlert(STR_NO_MEM_ERR); - return false; - } - D(bug("the_buffer = %p\n", the_buffer)); - - - unsigned char *offsetBuffer = (unsigned char *) the_buffer; - offsetBuffer += 1; // OS X NSBitmaps are RGBA, but Basilisk generates ARGB - -#ifdef CGIMAGEREF - switch ( mode.depth ) - { - case VDEPTH_1BIT: bpp = 1; break; - case VDEPTH_2BIT: bpp = 2; break; - case VDEPTH_4BIT: bpp = 4; break; - case VDEPTH_8BIT: bpp = 8; break; - case VDEPTH_16BIT: bpp = 5; break; - case VDEPTH_32BIT: bpp = 8; break; - } - - x = mode.x, y = mode.y, depth = bits_from_depth(mode.depth), bpr = mode.bytes_per_row; - - colourSpace = CGColorSpaceCreateDeviceRGB(); - - if ( mode.depth < VDEPTH_16BIT ) - { - CGColorSpaceRef oldColourSpace = colourSpace; - - colourSpace = CGColorSpaceCreateIndexed(colourSpace, 255, colourTable); - - CGColorSpaceRelease(oldColourSpace); - } - - if ( ! colourSpace ) - { - ErrorAlert("No valid colour space"); - return false; - } - - provider = CGDataProviderCreateWithData(NULL, the_buffer, - the_buffer_size, NULL); - if ( ! provider ) - { - ErrorAlert("Could not create CGDataProvider from buffer data"); - return false; - } - - imageRef = CGImageCreate(x, y, bpp, depth, bpr, colourSpace, - #ifdef CG_USE_ALPHA - kCGImageAlphaPremultipliedFirst, - #else - kCGImageAlphaNoneSkipFirst, - #endif - provider, - NULL, // colourMap translation table - NO, // shouldInterpolate colours? - kCGRenderingIntentDefault); - if ( ! imageRef ) - { - ErrorAlert("Could not create CGImage from CGDataProvider"); - return false; - } - - [output readyToDraw: imageRef - bitmap: offsetBuffer - imageWidth: x - imageHeight: y]; - - - #ifdef CG_USE_ALPHA - mask_buffer(the_buffer, x, the_buffer_size); - -/* Create an image mask with this call? */ -//CG_EXTERN CGImageRef -//CGImageMaskCreate(size_t width, size_t height, size_t bitsPerComponent, -// size_t bitsPerPixel, size_t bytesPerRow, -// CGDataProviderRef provider, const float decode[], bool shouldInterpolate); - #endif - - return true; -#endif - - -#ifndef CGIMAGEREF - short bitsPer, samplesPer; // How big is each Pixel? - - if ( mode.depth == VDEPTH_1BIT ) - bitsPer = 1; - else - bitsPer = 8; - - if ( mode.depth == VDEPTH_32BIT ) - samplesPer = 3; - else - samplesPer = 1; -#endif - - -#ifdef NSBITMAP - bitmap = [NSBitmapImageRep alloc]; - bitmap = [bitmap initWithBitmapDataPlanes: (unsigned char **) &offsetBuffer - pixelsWide: mode.x - pixelsHigh: mode.y - bitsPerSample: bitsPer - samplesPerPixel: samplesPer - hasAlpha: NO - isPlanar: NO - colorSpaceName: NSCalibratedRGBColorSpace - bytesPerRow: mode.bytes_per_row - bitsPerPixel: bits_from_depth(mode.depth)]; - - if ( ! bitmap ) - { - ErrorAlert("Could not allocate an NSBitmapImageRep"); - return false; - } - - [output readyToDraw: bitmap - imageWidth: mode.x - imageHeight: mode.y]; -#endif - -#ifdef CGDRAWBITMAP - [output readyToDraw: offsetBuffer - width: mode.x - height: mode.y - bps: bitsPer - spp: samplesPer - bpp: bits_from_depth(mode.depth) - bpr: mode.bytes_per_row - isPlanar: NO - hasAlpha: NO]; -#endif - - return true; -} - -#import -#import -#import "NNThread.h" - -bool -OSX_monitor::init_screen(video_mode &mode) -{ - // Set absolute mouse mode - ADBSetRelMouseMode(false); - - // Display stored by add_CGDirectDisplay_modes() - theDisplay = (CGDirectDisplayID) mode.user_data; - - originalMode = CGDisplayCurrentMode(theDisplay); - if ( ! originalMode ) - { - ErrorSheet(@"Could not get current mode of display", the_win); - return false; - } - - D(NSLog(@"About to call CGDisplayBestModeForParameters()")); - newMode = CGDisplayBestModeForParameters(theDisplay, - bits_from_depth(mode.depth), - mode.x, mode.y, NULL); - if ( ! newMode ) - { - ErrorSheet(@"Could not find a matching screen mode", the_win); - return false; - } - -// This sometimes takes ages to return after the window is genied, -// so for now we leave it onscreen -// [the_win miniaturize: nil]; - - D(NSLog(@"About to call CGDisplayCapture()")); - if ( CGDisplayCapture(theDisplay) != CGDisplayNoErr ) - { -// [the_win deminiaturize: nil]; - ErrorSheet(@"Could not capture display", the_win); - return false; - } - - D(NSLog(@"About to call CGDisplaySwitchToMode()")); - if ( CGDisplaySwitchToMode(theDisplay, newMode) != CGDisplayNoErr ) - { - CGDisplayRelease(theDisplay); -// [the_win deminiaturize: nil]; - ErrorSheet(@"Could not switch to matching screen mode", the_win); - return false; - } - - the_buffer = CGDisplayBaseAddress(theDisplay); - if ( ! the_buffer ) - { - CGDisplaySwitchToMode(theDisplay, originalMode); - CGDisplayRelease(theDisplay); -// [the_win deminiaturize: nil]; - ErrorSheet(@"Could not get base address of screen", the_win); - return false; - } - - if ( mode.bytes_per_row != CGDisplayBytesPerRow(theDisplay) ) - { - D(bug("Bytes per row (%d) doesn't match current (%ld)\n", - mode.bytes_per_row, CGDisplayBytesPerRow(theDisplay))); - mode.bytes_per_row = CGDisplayBytesPerRow(theDisplay); - } - - [NSMenu setMenuBarVisible:NO]; - - if ( singleDisplay ) - { - CGDisplayHideCursor(theDisplay); - - [output startedFullScreen: theDisplay]; - - // Send emulated mouse to current location - [output fullscreenMouseMove]; - } - else - { - // Should set up something to hide the cursor when it enters theDisplay? - } - - return true; -} - - -bool -OSX_monitor::init_opengl(const video_mode &mode) -{ - ErrorAlert("Sorry. OpenGL mode is not implemented yet"); - return false; -} - -/* - * Initialization - */ -static bool -monitor_init(const video_mode &init_mode) -{ - OSX_monitor *monitor; - BOOL success; - - monitor = new OSX_monitor(VideoModes, init_mode.depth, - init_mode.resolution_id); - success = monitor->video_open(init_mode); - - if ( success ) - { - monitor->set_mac_frame_buffer(init_mode); - VideoMonitors.push_back(monitor); - return YES; - } - - return NO; -} - -bool VideoInit(bool classic) -{ - // Read frame skip prefs - frame_skip = PrefsFindInt32("frameskip"); - if (frame_skip == 0) - frame_skip = 1; - - // Get screen mode from preferences - const char *mode_str; - if (classic) - mode_str = "win/512/342"; - else - mode_str = PrefsFindString("screen"); - - // Determine display_type and init_width, height & depth - parse_screen_prefs(mode_str); - - // Construct list of supported modes - if (classic) - add_mode(512, 342, 0x80, 64, 0, VDEPTH_1BIT); - else - switch ( display_type ) - { - case DISPLAY_SCREEN: - if ( ! add_CGDirectDisplay_modes() ) - { - ErrorAlert("Unable to get list of displays for full screen mode"); - return false; - } - break; - case DISPLAY_OPENGL: - // Same as window depths and sizes? - case DISPLAY_WINDOW: -#ifdef CGIMAGEREF - add_standard_modes(VDEPTH_1BIT); - add_standard_modes(VDEPTH_2BIT); - add_standard_modes(VDEPTH_4BIT); - add_standard_modes(VDEPTH_8BIT); - add_standard_modes(VDEPTH_16BIT); -#endif - add_standard_modes(VDEPTH_32BIT); - break; - } - -// video_init_depth_list(); Now done in monitor_desc constructor? - -#if DEBUG - bug("Available video modes:\n"); - vector::const_iterator i, end = VideoModes.end(); - for (i = VideoModes.begin(); i != end; ++i) - bug(" %dx%d (ID %02x), %s\n", i->x, i->y, i->resolution_id, - colours_from_depth(i->depth)); -#endif - - D(bug("VideoInit: width=%hd height=%hd depth=%d\n", - init_width, init_height, init_depth)); - - // Find requested default mode and open display - if (VideoModes.size() > 0) - { - // Find mode with specified dimensions - std::vector::const_iterator i, end = VideoModes.end(); - for (i = VideoModes.begin(); i != end; ++i) - { - D(bug("VideoInit: w=%d h=%d d=%d\n", - i->x, i->y, bits_from_depth(i->depth))); - if (i->x == init_width && i->y == init_height - && bits_from_depth(i->depth) == init_depth) - return monitor_init(*i); - } - } - - char str[150]; - sprintf(str, "Cannot open selected video mode\r(%hd x %hd, %s).\r%s", - init_width, init_height, - colours_from_depth(init_depth), "Using lowest resolution"); - WarningAlert(str); - - return monitor_init(VideoModes[0]); -} - - -// Open display for specified mode -bool -OSX_monitor::video_open(const video_mode &mode) -{ - D(bug("video_open: width=%d height=%d depth=%d bytes_per_row=%d\n", - mode.x, mode.y, bits_from_depth(mode.depth), mode.bytes_per_row)); - - // Open display - switch ( display_type ) - { - case DISPLAY_WINDOW: return init_window(mode); - case DISPLAY_SCREEN: return init_screen((video_mode &)mode); - case DISPLAY_OPENGL: return init_opengl(mode); - } - - return false; -} - - -void -OSX_monitor::video_close() -{ - D(bug("video_close()\n")); - - switch ( display_type ) { - case DISPLAY_WINDOW: - // Stop redraw thread - [output disableDrawing]; - - // Free frame buffer stuff -#ifdef CGIMAGEREF - CGImageRelease(imageRef); - CGColorSpaceRelease(colourSpace); - CGDataProviderRelease(provider); -#endif -#ifdef NSBITMAP - [bitmap release]; -#endif - free(the_buffer); - - break; - - case DISPLAY_SCREEN: - if ( theDisplay && originalMode ) - { - if ( singleDisplay ) - CGDisplayShowCursor(theDisplay); - [NSMenu setMenuBarVisible:YES]; - CGDisplaySwitchToMode(theDisplay, originalMode); - CGDisplayRelease(theDisplay); - //[the_win deminiaturize: nil]; - } - break; - - case DISPLAY_OPENGL: - break; - } -} - - -/* - * Deinitialization - */ - -void VideoExit(void) -{ - // Close displays - vector::iterator i, end; - - end = VideoMonitors.end(); - - for (i = VideoMonitors.begin(); i != end; ++i) - dynamic_cast(*i)->video_close(); - - VideoMonitors.clear(); - VideoModes.clear(); -} - - -/* - * Set palette - */ - -void -OSX_monitor::set_palette(uint8 *pal, int num) -{ - if ( [output isFullScreen] && CGDisplayCanSetPalette(theDisplay) - && ! IsDirectMode(get_current_mode()) ) - { - CGDirectPaletteRef CGpal; - CGDisplayErr err; - - - CGpal = CGPaletteCreateWithByteSamples((CGDeviceByteColor *)pal, num); - err = CGDisplaySetPalette(theDisplay, CGpal); - if ( err != noErr ) - NSLog(@"Failed to set palette, error = %d", err); - CGPaletteRelease(CGpal); - } - -#ifdef CGIMAGEREF - if ( display_type != DISPLAY_WINDOW ) - return; - - // To change the palette, we have to regenerate - // the CGImageRef with the new colour space. - - CGImageRef oldImageRef = imageRef; - CGColorSpaceRef oldColourSpace = colourSpace; - - colourSpace = CGColorSpaceCreateDeviceRGB(); - - if ( depth < 16 ) - { - CGColorSpaceRef tempColourSpace = colourSpace; - - colourSpace = CGColorSpaceCreateIndexed(colourSpace, 255, pal); - CGColorSpaceRelease(tempColourSpace); - } - - if ( ! colourSpace ) - { - ErrorAlert("No valid colour space"); - return; - } - - imageRef = CGImageCreate(x, y, bpp, depth, bpr, colourSpace, - #ifdef CG_USE_ALPHA - kCGImageAlphaPremultipliedFirst, - #else - kCGImageAlphaNoneSkipFirst, - #endif - provider, - NULL, // colourMap translation table - NO, // shouldInterpolate colours? - kCGRenderingIntentDefault); - if ( ! imageRef ) - { - ErrorAlert("Could not create CGImage from CGDataProvider"); - return; - } - - unsigned char *offsetBuffer = (unsigned char *) the_buffer; - offsetBuffer += 1; // OS X NSBitmaps are RGBA, but Basilisk generates ARGB - - [output readyToDraw: imageRef - bitmap: offsetBuffer - imageWidth: x - imageHeight: y]; - - CGColorSpaceRelease(oldColourSpace); - CGImageRelease(oldImageRef); -#endif -} - - -/* - * Switch video mode - */ - -void -OSX_monitor::switch_to_current_mode(void) -{ - video_mode mode = get_current_mode(); - const char *failure = NULL; - - D(bug("switch_to_current_mode(): width=%d height=%d depth=%d bytes_per_row=%d\n", mode.x, mode.y, bits_from_depth(mode.depth), mode.bytes_per_row)); - - if ( display_type == DISPLAY_SCREEN && originalMode ) - { - D(NSLog(@"About to call CGDisplayBestModeForParameters()")); - newMode = CGDisplayBestModeForParameters(theDisplay, - bits_from_depth(mode.depth), - mode.x, mode.y, NULL); - if ( ! newMode ) - failure = "Could not find a matching screen mode"; - else - { - D(NSLog(@"About to call CGDisplaySwitchToMode()")); - if ( CGDisplaySwitchToMode(theDisplay, newMode) != CGDisplayNoErr ) - failure = "Could not switch to matching screen mode"; - } - - // For mouse event processing: update screen height - [output startedFullScreen: theDisplay]; - - if ( ! failure && - mode.bytes_per_row != CGDisplayBytesPerRow(theDisplay) ) - { - D(bug("Bytes per row (%d) doesn't match current (%ld)\n", - mode.bytes_per_row, CGDisplayBytesPerRow(theDisplay))); - mode.bytes_per_row = CGDisplayBytesPerRow(theDisplay); - } - - if ( ! failure && - ! ( the_buffer = CGDisplayBaseAddress(theDisplay) ) ) - failure = "Could not get base address of screen"; - - } -#ifdef CGIMAGEREF - // Clean up the old CGImageRef stuff - else if ( display_type == DISPLAY_WINDOW && imageRef ) - { - CGImageRef oldImageRef = imageRef; - CGColorSpaceRef oldColourSpace = colourSpace; - CGDataProviderRef oldProvider = provider; - void *oldBuffer = the_buffer; - - if ( video_open(mode) ) - { - CGImageRelease(oldImageRef); - CGColorSpaceRelease(oldColourSpace); - CGDataProviderRelease(oldProvider); - free(oldBuffer); - } - else - failure = "Could not video_open() requested mode"; - } -#endif - else if ( ! video_open(mode) ) - failure = "Could not video_open() requested mode"; - - if ( ! failure && display_type == DISPLAY_SCREEN ) - { - // Whenever we change screen resolution, the MacOS mouse starts - // up in the top left corner. Send real mouse to that location -// if ( CGDisplayMoveCursorToPoint(theDisplay, CGPointMake(15,15)) -// == CGDisplayNoErr ) -// { - // - [output fullscreenMouseMove]; -// } -// else -// failure = "Could move (jump) cursor on screen"; - } - - if ( failure ) - { - NSLog(@"In switch_to_current_mode():"); - NSLog(@"%s.", failure); - video_close(); - if ( display_type == DISPLAY_SCREEN ) - ErrorAlert("Cannot switch screen to selected video mode"); - else - ErrorAlert(STR_OPEN_WINDOW_ERR); - QuitEmulator(); - } - else - set_mac_frame_buffer(mode); -} - -/* - * Close down full-screen mode - * (if bringing up error alerts is unsafe while in full-screen mode) - */ - -void VideoQuitFullScreen(void) -{ -} - - -/* - * Mac VBL interrupt - */ - -void VideoInterrupt(void) -{ -} - - -// This function is called on non-threaded platforms from a timer interrupt -void VideoRefresh(void) -{ -} - - - -// Deal with a memory access signal referring to the screen. -// For now, just ignore -bool Screen_fault_handler(char *a, char *b) -{ -// NSLog(@"Got a screen fault %lx %lx", a, b); -// [output setNeedsDisplay: YES]; - return YES; -} diff --git a/BasiliskII/src/SDL/SDLMain.h b/BasiliskII/src/SDL/SDLMain.h deleted file mode 100644 index c56d90cb..00000000 --- a/BasiliskII/src/SDL/SDLMain.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#ifndef _SDLMain_h_ -#define _SDLMain_h_ - -#import - -@interface SDLMain : NSObject -@end - -#endif /* _SDLMain_h_ */ diff --git a/BasiliskII/src/SDL/SDLMain.m b/BasiliskII/src/SDL/SDLMain.m deleted file mode 100644 index 2434f81a..00000000 --- a/BasiliskII/src/SDL/SDLMain.m +++ /dev/null @@ -1,381 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#include "SDL.h" -#include "SDLMain.h" -#include /* for MAXPATHLEN */ -#include - -/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, - but the method still is there and works. To avoid warnings, we declare - it ourselves here. */ -@interface NSApplication(SDL_Missing_Methods) -- (void)setAppleMenu:(NSMenu *)menu; -@end - -/* Use this flag to determine whether we use SDLMain.nib or not */ -#define SDL_USE_NIB_FILE 0 - -/* Use this flag to determine whether we use CPS (docking) or not */ -#define SDL_USE_CPS 1 -#ifdef SDL_USE_CPS -/* Portions of CPS.h */ -typedef struct CPSProcessSerNum -{ - UInt32 lo; - UInt32 hi; -} CPSProcessSerNum; - -extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); -extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); -extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); - -#endif /* SDL_USE_CPS */ - -static int gArgc; -static char **gArgv; -static BOOL gFinderLaunch; -static BOOL gCalledAppMainline = FALSE; - -static NSString *getApplicationName(void) -{ - const NSDictionary *dict; - NSString *appName = 0; - - /* Determine the application name */ - dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); - if (dict) - appName = [dict objectForKey: @"CFBundleName"]; - - if (![appName length]) - appName = [[NSProcessInfo processInfo] processName]; - - return appName; -} - -#if SDL_USE_NIB_FILE -/* A helper category for NSString */ -@interface NSString (ReplaceSubString) -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; -@end -#endif - -@interface NSApplication (SDLApplication) -@end - -@implementation NSApplication (SDLApplication) -/* Invoked from the Quit menu item */ -- (void)terminate:(id)sender -{ - /* Post a SDL_QUIT event */ - SDL_Event event; - event.type = SDL_QUIT; - SDL_PushEvent(&event); -} -@end - -/* The main class of the application, the application's delegate */ -@implementation SDLMain - -/* Set the working directory to the .app's parent directory */ -- (void) setupWorkingDirectory:(BOOL)shouldChdir -{ - if (shouldChdir) - { - char parentdir[MAXPATHLEN]; - CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); - if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) { - chdir(parentdir); /* chdir to the binary app's parent */ - } - CFRelease(url); - CFRelease(url2); - } -} - -#if SDL_USE_NIB_FILE - -/* Fix menu to contain the real app name instead of "SDL App" */ -- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName -{ - NSRange aRange; - NSEnumerator *enumerator; - NSMenuItem *menuItem; - - aRange = [[aMenu title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; - - enumerator = [[aMenu itemArray] objectEnumerator]; - while ((menuItem = [enumerator nextObject])) - { - aRange = [[menuItem title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; - if ([menuItem hasSubmenu]) - [self fixMenu:[menuItem submenu] withAppName:appName]; - } -} - -#else - -static void setApplicationMenu(void) -{ - /* warning: this code is very odd */ - NSMenu *appleMenu; - NSMenuItem *menuItem; - NSString *title; - NSString *appName; - - appName = getApplicationName(); - appleMenu = [[NSMenu alloc] initWithTitle:@""]; - - /* Add menu items */ - title = [@"About " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; - - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; - - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; - - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; - - /* Finally give up our references to the objects */ - [appleMenu release]; - [menuItem release]; -} - -/* Create a window menu */ -static void setupWindowMenu(void) -{ - NSMenu *windowMenu; - NSMenuItem *windowMenuItem; - NSMenuItem *menuItem; - - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [windowMenuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:windowMenuItem]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - - /* Finally give up our references to the objects */ - [windowMenu release]; - [windowMenuItem release]; -} - -/* Replacement for NSApplicationMain */ -static void CustomApplicationMain (int argc, char **argv) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDLMain *sdlMain; - - /* Ensure the application object is initialised */ - [NSApplication sharedApplication]; - -#ifdef SDL_USE_CPS - { - CPSProcessSerNum PSN; - /* Tell the dock about us */ - if (!CPSGetCurrentProcess(&PSN)) - if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) - if (!CPSSetFrontProcess(&PSN)) - [NSApplication sharedApplication]; - } -#endif /* SDL_USE_CPS */ - - /* Set up the menubar */ - [NSApp setMainMenu:[[NSMenu alloc] init]]; - setApplicationMenu(); - setupWindowMenu(); - - /* Create SDLMain and make it the app delegate */ - sdlMain = [[SDLMain alloc] init]; - [NSApp setDelegate:sdlMain]; - - /* Start the main event loop */ - [NSApp run]; - - [sdlMain release]; - [pool release]; -} - -#endif - - -/* - * Catch document open requests...this lets us notice files when the app - * was launched by double-clicking a document, or when a document was - * dragged/dropped on the app's icon. You need to have a - * CFBundleDocumentsType section in your Info.plist to get this message, - * apparently. - * - * Files are added to gArgv, so to the app, they'll look like command line - * arguments. Previously, apps launched from the finder had nothing but - * an argv[0]. - * - * This message may be received multiple times to open several docs on launch. - * - * This message is ignored once the app's mainline has been called. - */ -- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename -{ - const char *temparg; - size_t arglen; - char *arg; - char **newargv; - - if (!gFinderLaunch) /* MacOS is passing command line args. */ - return FALSE; - - if (gCalledAppMainline) /* app has started, ignore this document. */ - return FALSE; - - temparg = [filename UTF8String]; - arglen = SDL_strlen(temparg) + 1; - arg = (char *) SDL_malloc(arglen); - if (arg == NULL) - return FALSE; - - newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); - if (newargv == NULL) - { - SDL_free(arg); - return FALSE; - } - gArgv = newargv; - - SDL_strlcpy(arg, temparg, arglen); - gArgv[gArgc++] = arg; - gArgv[gArgc] = NULL; - return TRUE; -} - - -/* Called when the internal event loop has just started running */ -- (void) applicationDidFinishLaunching: (NSNotification *) note -{ - int status; - - /* Set the working directory to the .app's parent directory */ - [self setupWorkingDirectory:gFinderLaunch]; - -#if SDL_USE_NIB_FILE - /* Set the main menu to contain the real app name instead of "SDL App" */ - [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; -#endif - - /* Hand off to main application code */ - gCalledAppMainline = TRUE; - status = SDL_main (gArgc, gArgv); - - /* We're done, thank you for playing */ - exit(status); -} -@end - - -@implementation NSString (ReplaceSubString) - -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString -{ - unsigned int bufferSize; - unsigned int selfLen = [self length]; - unsigned int aStringLen = [aString length]; - unichar *buffer; - NSRange localRange; - NSString *result; - - bufferSize = selfLen + aStringLen - aRange.length; - buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar)); - - /* Get first part into buffer */ - localRange.location = 0; - localRange.length = aRange.location; - [self getCharacters:buffer range:localRange]; - - /* Get middle part into buffer */ - localRange.location = 0; - localRange.length = aStringLen; - [aString getCharacters:(buffer+aRange.location) range:localRange]; - - /* Get last part into buffer */ - localRange.location = aRange.location + aRange.length; - localRange.length = selfLen - localRange.location; - [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; - - /* Build output string */ - result = [NSString stringWithCharacters:buffer length:bufferSize]; - - NSDeallocateMemoryPages(buffer, bufferSize); - - return result; -} - -@end - - - -#ifdef main -# undef main -#endif - - -/* Main entry point to executable - should *not* be SDL_main! */ -int main (int argc, char **argv) -{ - /* Copy the arguments into a global variable */ - /* This is passed if we are launched by double-clicking */ - if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { - gArgv = (char **) SDL_malloc(sizeof (char *) * 2); - gArgv[0] = argv[0]; - gArgv[1] = NULL; - gArgc = 1; - gFinderLaunch = YES; - } else { - int i; - gArgc = argc; - gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); - for (i = 0; i <= argc; i++) - gArgv[i] = argv[i]; - gFinderLaunch = NO; - } - -#if SDL_USE_NIB_FILE - NSApplicationMain (argc, argv); -#else - CustomApplicationMain (argc, argv); -#endif - return 0; -} - diff --git a/BasiliskII/src/SDL/audio_sdl.cpp b/BasiliskII/src/SDL/audio_sdl.cpp index 921beb4c..85ad4c8b 100644 --- a/BasiliskII/src/SDL/audio_sdl.cpp +++ b/BasiliskII/src/SDL/audio_sdl.cpp @@ -32,10 +32,6 @@ #define DEBUG 0 #include "debug.h" -#if defined(BINCUE) -#include "bincue_unix.h" -#endif - #define MAC_MAX_VOLUME 0x0100 @@ -100,11 +96,6 @@ static bool open_sdl_audio(void) return false; } -#if defined(BINCUE) - OpenAudio_bincue(audio_spec.freq, audio_spec.format, audio_spec.channels, - audio_spec.silence); -#endif - char driver_name[32]; printf("Using SDL/%s audio output\n", SDL_AudioDriverName(driver_name, sizeof(driver_name) - 1)); silence_byte = audio_spec.silence; @@ -236,9 +227,7 @@ static void stream_func(void *arg, uint8 *stream, int stream_len) // Audio not active, play silence silence: memset(stream, silence_byte, stream_len); } -#if defined(BINCUE) - MixAudio_bincue(stream, stream_len); -#endif + } diff --git a/BasiliskII/src/SDL/video_sdl.cpp b/BasiliskII/src/SDL/video_sdl.cpp index 4ea28b72..9b2855da 100644 --- a/BasiliskII/src/SDL/video_sdl.cpp +++ b/BasiliskII/src/SDL/video_sdl.cpp @@ -48,10 +48,6 @@ #include #include -#ifdef WIN32 -#include /* alloca() */ -#endif - #include "cpu_emulation.h" #include "main.h" #include "adb.h" @@ -86,11 +82,7 @@ static int display_type = DISPLAY_WINDOW; // See enum above #endif // Constants -#ifdef WIN32 -const char KEYCODE_FILE_NAME[] = "BasiliskII_keycodes"; -#else const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes"; -#endif // Global variables @@ -217,43 +209,6 @@ static inline void vm_release_framebuffer(void *fb, uint32 size) } -/* - * Windows message handler - */ - -#ifdef WIN32 -#include -static WNDPROC sdl_window_proc = NULL; // Window proc used by SDL - -extern void SysMediaArrived(void); -extern void SysMediaRemoved(void); -extern HWND GetMainWindowHandle(void); - -static LRESULT CALLBACK windows_message_handler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_DEVICECHANGE: - if (wParam == DBT_DEVICEREMOVECOMPLETE) { - DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; - if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) - SysMediaRemoved(); - } - else if (wParam == DBT_DEVICEARRIVAL) { - DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; - if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) - SysMediaArrived(); - } - return 0; - - default: - if (sdl_window_proc) - return CallWindowProc(sdl_window_proc, hwnd, msg, wParam, lParam); - } - - return DefWindowProc(hwnd, msg, wParam, lParam); -} -#endif - /* * SheepShaver glue @@ -502,26 +457,9 @@ static void add_mode(int type, int width, int height, int resolution_id, int byt // Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth, bool native_byte_order) { -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING - int layout = FLAYOUT_DIRECT; - if (depth == VIDEO_DEPTH_16BIT) - layout = (screen_depth == 15) ? FLAYOUT_HOST_555 : FLAYOUT_HOST_565; - else if (depth == VIDEO_DEPTH_32BIT) - layout = (screen_depth == 24) ? FLAYOUT_HOST_888 : FLAYOUT_DIRECT; - if (native_byte_order) - MacFrameLayout = layout; - else - MacFrameLayout = FLAYOUT_DIRECT; - monitor.set_mac_frame_base(MacFrameBaseMac); - // Set variables used by UAE memory banking - const VIDEO_MODE &mode = monitor.get_current_mode(); - MacFrameBaseHost = the_buffer; - MacFrameSize = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; - InitFrameBufferMapping(); -#else monitor.set_mac_frame_base(Host2MacAddr(the_buffer)); -#endif + D(bug("monitor.mac_frame_base = %08x\n", monitor.get_mac_frame_base())); } @@ -934,13 +872,6 @@ bool SDL_monitor_desc::video_open(void) return false; } -#ifdef WIN32 - // Chain in a new message handler for WM_DEVICECHANGE - HWND the_window = GetMainWindowHandle(); - sdl_window_proc = (WNDPROC)GetWindowLongPtr(the_window, GWLP_WNDPROC); - SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)windows_message_handler); -#endif - // Initialize VideoRefresh function VideoRefreshInit(); @@ -1162,12 +1093,6 @@ void SDL_monitor_desc::video_close(void) { D(bug("video_close()\n")); -#ifdef WIN32 - // Remove message handler for WM_DEVICECHANGE - HWND the_window = GetMainWindowHandle(); - SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)sdl_window_proc); -#endif - // Stop redraw thread #ifndef USE_CPU_EMUL_SERVICES if (redraw_thread_active) { @@ -1489,9 +1414,7 @@ void video_set_cursor(void) // On Mac, if mouse is grabbed, SDL_ShowCursor() recenters the // mouse, we have to put it back. bool move = false; -#ifdef WIN32 - move = true; -#elif defined(__APPLE__) +#if defined(__APPLE__) move = mouse_grabbed; #endif if (move) { @@ -2095,7 +2018,7 @@ static void video_refresh_dga(void) } #ifdef ENABLE_VOSF -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING static void video_refresh_dga_vosf(void) { // Quit DGA mode if requested @@ -2158,7 +2081,7 @@ static void VideoRefreshInit(void) { // TODO: set up specialised 8bpp VideoRefresh handlers ? if (display_type == DISPLAY_SCREEN) { -#if ENABLE_VOSF && (REAL_ADDRESSING || DIRECT_ADDRESSING) +#if ENABLE_VOSF && (DIRECT_ADDRESSING) if (use_vosf) video_refresh = video_refresh_dga_vosf; else diff --git a/BasiliskII/src/MacOSX/sys_darwin.cpp b/BasiliskII/src/Unix/Darwin/sys_darwin.cpp similarity index 100% rename from BasiliskII/src/MacOSX/sys_darwin.cpp rename to BasiliskII/src/Unix/Darwin/sys_darwin.cpp diff --git a/BasiliskII/src/Unix/FreeBSD/scsi_freebsd.cpp b/BasiliskII/src/Unix/FreeBSD/scsi_freebsd.cpp deleted file mode 100644 index 556af295..00000000 --- a/BasiliskII/src/Unix/FreeBSD/scsi_freebsd.cpp +++ /dev/null @@ -1,743 +0,0 @@ -/* - * scsi_freebsd.cpp - SCSI Manager, FreeBSD SCSI Driver implementation - * Copyright (C) 1999 Orlando Bassotto - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * History: - * 29-Jun-1999 Started - * 05-Jul-1999 Changed from array to queue removing the limit of 8 - * devices. - * Implemented old SCSI management for FreeBSD 2.x. - * (Note: This implementation hasn't been tested; - * I don't own anymore a machine with FreeBSD 2.x, - * so if something goes wrong, please mail me to - * future@mediabit.net). - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CAM -#include -#include -#include -#include -#include -#include -#include -#include -#else /* !CAM */ -#include -#include -#endif /* !CAM */ - -#include "sysdeps.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "scsi.h" - -#define DEBUG 0 -#include "debug.h" - - -#undef u_int8_t -#define u_int8_t unsigned char - -typedef struct _SCSIDevice { - int controller; // SCSI Controller - int controller_bus; // SCSI Controller Bus - char controller_name[33]; // SCSI Controller name - int mac_unit; // Macintosh SCSI ID (remapped) - int faked_controller; // "Faked" SCSI Controller (Always 0) - int faked_unit; // "Faked" SCSI ID - int unit; // Real SCSI ID - int lun; // Real SCSI LUN - u_int8_t vendor[16]; // SCSI Vendor - u_int8_t product[48]; // SCSI Product - u_int8_t revision[16]; // SCSI Revision - char device[33]; // SCSI Device -#ifdef CAM - char pass_device[33]; // SCSI Pass Device -#else /* !CAM */ - int dev_fd; // Device File Descriptor -#endif /* !CAM */ - void* dev_ptr; // Pointer to CAM/SCSI structure - bool enabled; // Device enabled ? - struct _SCSIDevice* next; // Pointer to the next device -} SCSIDevice; - -static int nDevices = 0; -static SCSIDevice* Devices = NULL; - -static uint32 buffer_size; -static uint8* buffer = NULL; - -static uint8 the_cmd[12]; -static int the_cmd_len; - -static SCSIDevice* CurrentDevice = NULL; - -inline static SCSIDevice* _GetSCSIDeviceByID(int id) -{ - SCSIDevice* aux = Devices; - while(aux) { - if(aux->faked_unit==id) { - return aux; - } - aux = aux->next; - } - return NULL; -} - -inline static SCSIDevice* _GetSCSIDeviceByIDLUN(int id, int lun) -{ - SCSIDevice* aux = Devices; - while(aux) { - if(aux->faked_unit==id&&aux->lun==lun) { - return aux; - } - aux = aux->next; - } - return NULL; -} - -inline static SCSIDevice* _GetSCSIDeviceByMacID(int id) -{ - SCSIDevice* aux = Devices; - while(aux) { - if(aux->mac_unit==id) { - return aux; - } - aux = aux->next; - } - return NULL; -} - -inline static SCSIDevice* _GetSCSIDeviceByMacIDLUN(int id, int lun) -{ - SCSIDevice* aux = Devices; - while(aux) { - if(aux->mac_unit==id&&aux->lun==lun) { - return aux; - } - aux = aux->next; - } - return NULL; -} - -inline static SCSIDevice* _AllocNewDevice() -{ - SCSIDevice* aux; - - aux = new SCSIDevice; - if(aux==NULL) return NULL; - memset(aux, 0, sizeof(SCSIDevice)); - aux->next = Devices; - Devices = aux; - return aux; -} - -#ifdef CAM -inline static struct cam_device* _GetCurrentSCSIDevice() -{ - if(CurrentDevice==NULL) return NULL; - - return (struct cam_device*)CurrentDevice->dev_ptr; -} -#else /* !CAM */ -inline static struct scsireq* _GetCurrentSCSIDevice() -{ - if(CurrentDevice==NULL) return NULL; - - return (struct scsireq*)CurrentDevice->dev_ptr; -} -#endif /* !CAM */ - -/* - * _Build_SCSI_Controller() - * - * This function builds a virtual SCSI Controller (Controller=0) - * where keeps all the devices found, this is due the fact - * I have two SCSI controllers in my PC. :-) - * Use scsidump in contrib/ to see how is remapped your - * SCSI device (only if you have more than one controller, - * that's for sure :-). - * If you have only one controller, remapping does not take act. - */ - -#define GET_FREE_ID(id) \ - { \ - for(int x=0;x<32;x++) { \ - if(!(busyIDs&(1<<(x+1)))) { \ - id = x; \ - break; \ - } \ - } \ - } - -static void _Build_SCSI_Controller() -{ - unsigned int id = 0; - unsigned long long busyIDs = 0x0ll; - SCSIDevice* aux, * dev; - - // What IDs are busy? - dev = Devices; - while(dev) { - dev->enabled = false; - dev->faked_controller = 0; - dev->faked_unit = dev->unit; - busyIDs |= (1 << (dev->unit+1)); - dev = dev->next; - } - - // Find out the duplicate IDs and remap them - dev = Devices, aux = NULL; - while(dev) { - aux = dev; - while(aux) { - SCSIDevice* dev1, * dev2; - - dev1 = dev, dev2 = aux; - - if(dev1->controller!=dev2->controller&& - dev1->unit==dev2->unit) { - int free_id; - GET_FREE_ID(free_id); - busyIDs |= (1<<(free_id+1)); - dev1->faked_unit = free_id; - } - aux = aux->next; - } - dev = dev->next; - } - - // Now reorder the queue -#if 0 - dev = Devices; - while(dev) { - aux = dev; - while(aux) { - SCSIDevice* dev1, * dev2; - - dev1 = dev, dev2 = aux; - if(dev1->faked_unit>dev2->faked_unit) { - SCSIDevice tmp; - - memcpy(&tmp, dev1, sizeof(SCSIDevice)); - memcpy(dev1, dev2, sizeof(SCSIDevice)); - memcpy(dev2, &tmp, sizeof(SCSIDevice)); - } - aux = aux->next; - } - dev = dev->next; - } -#endif - - // Now open the selected SCSI devices :-) - for(int n=0;n<8;n++) { - char tmp[25]; - - snprintf(tmp, sizeof(tmp), "scsi%d", n); - const char* scsi = PrefsFindString(tmp); - if(scsi) { - int id, lun; - - // The format is: RemappedID (or FakedID)/LUN - sscanf(scsi, "%d/%d", &id, &lun); - - SCSIDevice* dev = _GetSCSIDeviceByIDLUN(id, lun); - if(dev==NULL) continue; - dev->enabled = true; - dev->mac_unit = n; - -#ifdef CAM - struct cam_device* cam; - - cam = cam_open_btl(dev->controller, - dev->unit, - dev->lun, O_RDWR, NULL); - if(cam==NULL) { - fprintf(stderr, "Failed to open %d:%d:%d = %s!!!\n", - dev->controller, dev->unit, dev->lun, - cam_errbuf); - } - dev->dev_ptr = (void*)cam; -#else /* !CAM */ - dev->dev_fd = scsi_open(dev->device, O_RDWR); - if(dev->dev_fd<0) { - perror("Failed to open %d:%d:%d"); - } - else { - dev->dev_ptr = (void*)scsireq_new(); - } -#endif /* !CAM */ - } - } -} - - -/* - * Initialization - */ - -void SCSIInit(void) -{ - // Finds the SCSI hosts in the system filling the SCSIDevices queue. - // "Stolen" from camcontrol.c - // Copyright (C) 1997-99 Kenneth D. Merry - // Old SCSI detection "stolen" from scsi.c - // Copyright (C) 1993 Julian Elischer - // - int bufsize, fd; - int need_close = 0; - int error = 0; - int skip_device = 0; - SCSIDevice* Dev, * dev, * PrevDev = NULL; - - nDevices = 0; - - if(PrefsFindBool("noscsi")) - goto no_scsi; - -#ifdef CAM - union ccb ccb; - if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { - fprintf(stderr, "WARNING: Cannot open CAM device %s (%s)\n", XPT_DEVICE, strerror(errno)); - goto no_scsi; - } - - memset(&(&ccb.ccb_h)[1], 0, sizeof(struct ccb_dev_match)-sizeof(struct ccb_hdr)); - ccb.ccb_h.func_code = XPT_DEV_MATCH; - bufsize = sizeof(struct dev_match_result) * 100; - ccb.cdm.match_buf_len = bufsize; - ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); - ccb.cdm.num_matches = 0; - - ccb.cdm.num_patterns = 0; - ccb.cdm.pattern_buf_len = 0; - - do { - Dev = _AllocNewDevice(); - if(ioctl(fd, CAMIOCOMMAND, &ccb)==-1) { - fprintf(stderr, "Error sending CAMIOCOMMAND ioctl\n"); - return; - } - - if((ccb.ccb_h.status != CAM_REQ_CMP) - || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) - && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { - fprintf(stderr, "Got CAM error %#x, CDM error %d\n", - ccb.ccb_h.status, ccb.cdm.status); - return; - } - - char current_controller_name[33]; - int current_controller = -1; - for(int i=0;ipath_id==-1) break; - Dev->controller = bus_result->path_id; - snprintf(Dev->controller_name, sizeof(Dev->controller_name), "%s%d", - bus_result->dev_name, - bus_result->unit_number); - strncpy(current_controller_name, Dev->controller_name, sizeof(current_controller_name)); - current_controller = Dev->controller; - Dev->controller_bus = bus_result->bus_id; - break; - } - case DEV_MATCH_DEVICE: - { - struct device_match_result* dev_result; - char tmpstr[256]; - - dev_result = &ccb.cdm.matches[i].result.device_result; - if(current_controller==-1||dev_result->target_id==-1) { - skip_device = 1; - break; - } - else skip_device = 0; - - cam_strvis(Dev->vendor, (u_int8_t*)dev_result->inq_data.vendor, - sizeof(dev_result->inq_data.vendor), - sizeof(Dev->vendor)); - cam_strvis(Dev->product, (u_int8_t*)dev_result->inq_data.product, - sizeof(dev_result->inq_data.product), - sizeof(Dev->product)); - cam_strvis(Dev->revision, (u_int8_t*)dev_result->inq_data.revision, - sizeof(dev_result->inq_data.revision), - sizeof(Dev->revision)); - strncpy(Dev->controller_name, current_controller_name, sizeof(Dev->controller_name)); - Dev->controller = current_controller; - Dev->unit = dev_result->target_id; - Dev->lun = dev_result->target_lun; - break; - } - case DEV_MATCH_PERIPH: - { - struct periph_match_result* periph_result; - - periph_result = &ccb.cdm.matches[i].result.periph_result; - - if(skip_device != 0) break; - - if(need_close==1) { - snprintf(Dev->device, sizeof(Dev->device), "%s%d*", - periph_result->periph_name, - periph_result->unit_number); - need_close = 0; - } - else if(need_close==0) { - snprintf(Dev->pass_device, sizeof(Dev->pass_device), "%s%d", - periph_result->periph_name, - periph_result->unit_number); - need_close++; - break; - } - else { - need_close = 0; - } - PrevDev = Dev; - Dev = _AllocNewDevice(); - break; - } - } - } - } while (ccb.ccb_h.status == CAM_REQ_CMP - && ccb.cdm.status == CAM_DEV_MATCH_MORE); - - /* Remove last one (ugly coding) */ - Devices = PrevDev; - delete Dev; -end_loop: - close(fd); -#else /* !CAM */ - /* - * FreeBSD 2.x SCSI management is quiet different and - * unfortunatly not flexible as CAM library in FreeBSD 3.x... - * I probe only the first bus, LUN 0, and the - * first 8 devices only. - */ - u_char* inq_buf; - scsireq_t* scsireq; - struct scsi_addr scsi; - int ssc_fd; - - if((ssc_fd=open("/dev/ssc", O_RDWR))==-1) { - fprintf(stderr, "Cannot open SCSI manager: /dev/ssc\n"); - SCSIReset(); - return; - } - - inq_buf = (u_char*)malloc(96); - if(inq_buf==NULL) { - perror("malloc failed"); - SCSIReset(); - return; - } - - scsireq = scsireq_build((scsireq_t*)dev->dev_ptr, - 96, inq_buf, SCCMD_READ, - "12 0 0 0 v 0", 96); - - addr.scbus = 0; - addr.lun = 0; - - for(int n=0;n<8;n++) { - addr.target = n; - - if(ioctl(ssc_fd, SCIOCADDR, &addr) != -1) { - Dev = _AllocNewDevice(); - Dev->controller = addr.scbus; - Dev->lun = addr.lun; - Dev->unit = addr.target; - - struct scsi_devinfo devInfo; - devInfo.addr = addr; - if(ioctl(ssc_fd, SCIOCGETDEVINFO, &devInfo) != -1) { - strncpy(Dev->device, devInfo.devname, sizeof(Dev->device)); - } - strncpy(Dev->controller_name, "FreeBSD 2.x SCSI Manager", sizeof(Dev->controller_name)); - if(scsireq_enter(ssc_fd, scsireq)!=-1) { - Dev->vendor[sizeof(Dev->vendor)-1] = 0; - Dev->product[sizeof(Dev->product)-1] = 0; - Dev->revision[sizeof(Dev->revision)-1] = 0; - - scsireq_decode(scsireq, "s8 c8 c16 c4", - Dev->vendor, Dev->product, Dev->revision); - } - } - } - free(inq_buf); - close(ssc_fd); -#endif /* !CAM */ - _Build_SCSI_Controller(); - - // Print out the periph with ID:LUNs - fprintf(stderr, "Device RealID FkdID MacID Enabled\n"); - fprintf(stderr, "-------------------------------------------------------------\n"); - // 012345678901234567890123456789012 0:0:0 0/0 0:0 Yes - dev = Devices; - while(dev) { - char tmp[40]; - snprintf(tmp, sizeof(tmp), "%s %s %s", - dev->vendor, - dev->product, - dev->revision); - fprintf(stderr, "%-33s %d:%d:%d %d/%d %d:%d %s\n", - tmp, dev->controller, dev->unit, dev->lun, - dev->faked_unit, dev->lun, - dev->mac_unit, dev->lun, dev->enabled?"Yes":"No"); - dev = dev->next; - } - -no_scsi: - // Reset SCSI bus - SCSIReset(); -} - - -/* - * Deinitialization - */ - -void SCSIExit(void) -{ - SCSIDevice* aux; - while(Devices) { - aux = Devices->next; - if(Devices->dev_ptr!=NULL) { -#ifdef CAM - cam_close_device((struct cam_device*)Devices->dev_ptr); -#else /* !CAM */ - free(Devices->dev_ptr); // Is this right? - close(Devices->dev_fd); // And this one? -#endif /* !CAM */ - } - delete Devices; - Devices = aux; - } - nDevices = 0; -} - - -/* - * Set SCSI command to be sent by scsi_send_cmd() - */ - -void scsi_set_cmd(int cmd_length, uint8 *cmd) -{ - the_cmd_len = cmd_length; - memset(the_cmd, 0, sizeof(the_cmd)); - memcpy(the_cmd, cmd, the_cmd_len); -} - - -/* - * Check for presence of SCSI target - */ - -bool scsi_is_target_present(int id) -{ - return (_GetSCSIDeviceByMacID(id)!=NULL&&_GetSCSIDeviceByMacID(id)->enabled); -} - - -/* - * Set SCSI target (returns false on error) - */ - -bool scsi_set_target(int id, int lun) -{ - SCSIDevice* dev; - - dev = _GetSCSIDeviceByMacIDLUN(id, lun); - if(dev==NULL) return false; - CurrentDevice = dev; - return true; -} - - -/* - * Send SCSI command to active target (scsi_set_command() must have been called), - * read/write data according to S/G table (returns false on error) - */ - -static bool try_buffer(int size) -{ - if(size <= buffer_size) { - return true; - } - - D(bug("Allocating buffer of %d bytes.\n", size)); - uint8* new_buffer = (uint8*)valloc(size); - if(new_buffer==NULL) { - return false; - } - if(buffer!=NULL) free(buffer); - buffer = new_buffer; - buffer_size = size; - return true; -} - -bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr, uint32 *sg_len, uint16 *stat, uint32 timeout) -{ - int value = 0; -#ifdef CAM -#ifdef VERBOSE_CAM_DEBUG - D(bug("Sending command %x (len=%d) to SCSI Device %d:%d:%d\n", the_cmd[0], - the_cmd_len, - CurrentDevice->controller, - CurrentDevice->unit, - CurrentDevice->lun)); - D(bug("DataLength: %d\n", data_length)); - D(bug("Reading: %d\n", reading)); - D(bug("SG Size: %d\n", sg_size)); - D(bug("Timeout: %d\n", timeout)); -#endif /* VERBOSE_CAM_DEBUG */ -#endif /* CAM */ - if(!try_buffer(data_length)) { - char str[256]; - sprintf(str, GetString(STR_SCSI_BUFFER_ERR), data_length); - ErrorAlert(str); - return false; - } - - if(!reading) { - uint8* buffer_ptr = buffer; - for(int i=0;i0) { - dir_flags = reading?CAM_DIR_IN:CAM_DIR_OUT; - } - - ccb.ccb_h.path_id = CurrentDevice->controller; - ccb.ccb_h.target_id = CurrentDevice->unit; - ccb.ccb_h.target_lun = CurrentDevice->lun; - - cam_fill_csio(&ccb.csio, - 0, - NULL, - dir_flags, - MSG_SIMPLE_Q_TAG, - (u_int8_t*)buffer, - data_length, - SSD_FULL_SIZE, - the_cmd_len, - (timeout?timeout:50)*1000); - - ccb.ccb_h.flags |= CAM_DEV_QFRZDIS; - - memcpy(ccb.csio.cdb_io.cdb_bytes, the_cmd, the_cmd_len); - - if(cam_send_ccb(device, &ccb)<0) { - fprintf(stderr, "%d:%d:%d ", CurrentDevice->controller, - CurrentDevice->unit, CurrentDevice->lun); - perror("cam_send_ccb"); - return false; - } - - value = ccb.ccb_h.status; - *stat = ccb.csio.scsi_status; - - if((value & CAM_STATUS_MASK) != CAM_REQ_CMP) { - char tmp[4096]; - if((value & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR) { - scsi_sense_string(device, &ccb.csio, tmp, sizeof(tmp)); - fprintf(stderr, "SCSI Status Error:\n%s\n", tmp); - return false; - } - } -#else /* !CAM */ - struct scsireq* scsireq = _GetCurrentSCSIDevice(); - if(device==NULL) return false; - - int dir_flags = 0x00; - if(data_length>0) dir_flags = reading?SCCMD_READ:SCCMD_WRITE; - - scsireq_reset(scsireq); - scsireq->timeout = (timeout?timeout:50)*1000; - scsireq_build(scsireq, data_length, - (caddr_t)buffer, dir_flags, - "0"); - memcpy(scsireq->cmd, the_cmd, scsireq->cmdlen = the_cmd_len); - - int result = scsi_enter(dev->dev_fd, scsireq); - if(SCSIREQ_ERROR(result)) { - scsi_debug(stderr, result, scsireq); - } - *stat = scsireq->status; -#endif /* !CAM */ - - if(reading) { - uint8* buffer_ptr = buffer; - for(int i=0;i -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CAM -#include -#include -#include -#include -#include -#include -#include -#include -#else /* !CAM */ -#include -#include -#endif /* !CAM */ - -#undef u_int8_t -#define u_int8_t unsigned char - -typedef struct _SCSIDevice { - int controller; // SCSI Controller - int controller_bus; // SCSI Controller Bus - char controller_name[33]; // SCSI Controller name - int mac_unit; // Macintosh SCSI ID (remapped) - int faked_controller; // "Faked" SCSI Controller (Always 0) - int faked_unit; // "Faked" SCSI ID - int unit; // Real SCSI ID - int lun; // Real SCSI LUN - u_int8_t vendor[16]; // SCSI Vendor - u_int8_t product[48]; // SCSI Product - u_int8_t revision[16]; // SCSI Revision - char device[33]; // SCSI Device -#ifdef CAM - char pass_device[33]; // SCSI Pass Device -#else /* !CAM */ - int dev_fd; // Device File Descriptor -#endif /* !CAM */ - void* dev_ptr; // Pointer to CAM/SCSI structure - bool enabled; // Device enabled ? - struct _SCSIDevice* next; // Pointer to the next device -} SCSIDevice; - -static int nDevices = 0; -static SCSIDevice* Devices = NULL; - -inline static SCSIDevice* _GetSCSIDeviceByID(int id) -{ - SCSIDevice* aux = Devices; - while(aux) { - if(aux->faked_unit==id) { - return aux; - } - aux = aux->next; - } - return NULL; -} - -inline static SCSIDevice* _GetSCSIDeviceByIDLUN(int id, int lun) -{ - SCSIDevice* aux = Devices; - while(aux) { - if(aux->faked_unit==id&&aux->lun==lun) { - return aux; - } - aux = aux->next; - } - return NULL; -} - -inline static SCSIDevice* _GetSCSIDeviceByMacID(int id) -{ - SCSIDevice* aux = Devices; - while(aux) { - if(aux->mac_unit==id) { - return aux; - } - aux = aux->next; - } - return NULL; -} - -inline static SCSIDevice* _GetSCSIDeviceByMacIDLUN(int id, int lun) -{ - SCSIDevice* aux = Devices; - while(aux) { - if(aux->mac_unit==id&&aux->lun==lun) { - return aux; - } - aux = aux->next; - } - return NULL; -} - -inline static SCSIDevice* _AllocNewDevice() -{ - SCSIDevice* aux; - - aux = new SCSIDevice; - if(aux==NULL) return NULL; - memset(aux, 0, sizeof(SCSIDevice)); - aux->next = Devices; - Devices = aux; - return aux; -} - -/* - * _Build_SCSI_Controller() - * - * This function builds a virtual SCSI Controller (Controller=0) - * where keeps all the devices found, this is due the fact - * I have two SCSI controllers in my PC. :-) - * Use FreeBSD-SCSIDump in contrib/ to see how is remapped your - * SCSI device (only if you have more than one controller, - * that's for sure :-). - */ - -#define GET_FREE_ID(id) \ - { \ - for(int x=0;x<32;x++) { \ - if(!(busyIDs&(1<<(x+1)))) { \ - id = x; \ - break; \ - } \ - } \ - } - -static void _Build_SCSI_Controller() -{ - unsigned int id = 0; - unsigned long long busyIDs = 0x0ll; - SCSIDevice* aux, * dev; - - // What IDs are busy? - dev = Devices; - while(dev) { - dev->enabled = false; - dev->faked_controller = 0; - dev->faked_unit = dev->unit; - busyIDs |= (1 << (dev->unit+1)); - dev = dev->next; - } - - // Find out the duplicate IDs and change them - dev = Devices, aux = NULL; - while(dev) { - aux = dev; - while(aux) { - SCSIDevice* dev1, * dev2; - - dev1 = dev, dev2 = aux; - - if(dev1->controller!=dev2->controller&& - dev1->unit==dev2->unit) { - int free_id; - GET_FREE_ID(free_id); - busyIDs |= (1<<(free_id+1)); - dev1->faked_unit = free_id; - } - aux = aux->next; - } - dev = dev->next; - } - - // Now reorder the queue - dev = Devices; - while(dev) { - aux = dev; - while(aux) { - SCSIDevice* dev1, * dev2; - - dev1 = dev, dev2 = aux; -/* - if(dev1->faked_unit>dev2->faked_unit) { - SCSIDevice tmp; - - memcpy(&tmp, dev1, sizeof(SCSIDevice)); - memcpy(dev1, dev2, sizeof(SCSIDevice)); - memcpy(dev2, &tmp, sizeof(SCSIDevice)); - } - */ - aux = aux->next; - } - dev = dev->next; - } -} - -#define SCSIReset() - -/* - * Initialization - */ - -void SCSIInit(void) -{ - // Find the SCSI hosts in the system - // Filling out the SCSIDevices queue. - // Stolen from camcontrol.c - int bufsize, fd; - int need_close = 0; - int error = 0; - int skip_device = 0; - SCSIDevice* Dev, * dev, * PrevDev = NULL; - - nDevices = 0; - -#ifdef CAM - union ccb ccb; - - if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { - fprintf(stderr, "Cannot open CAM device: %s\n", XPT_DEVICE); - goto no_scsi; - } - - memset(&(&ccb.ccb_h)[1], 0, sizeof(struct ccb_dev_match)-sizeof(struct ccb_hdr)); - ccb.ccb_h.func_code = XPT_DEV_MATCH; - bufsize = sizeof(struct dev_match_result) * 100; - ccb.cdm.match_buf_len = bufsize; - ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); - ccb.cdm.num_matches = 0; - - ccb.cdm.num_patterns = 0; - ccb.cdm.pattern_buf_len = 0; - - do { - Dev = _AllocNewDevice(); - if(ioctl(fd, CAMIOCOMMAND, &ccb)==-1) { - fprintf(stderr, "Error sending CAMIOCOMMAND ioctl\n"); - return; - } - - if((ccb.ccb_h.status != CAM_REQ_CMP) - || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) - && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { - fprintf(stderr, "Got CAM error %#x, CDM error %d\n", - ccb.ccb_h.status, ccb.cdm.status); - return; - } - - char current_controller_name[33]; - int current_controller = -1; - for(int i=0;ipath_id==-1) break; - Dev->controller = bus_result->path_id; - snprintf(Dev->controller_name, sizeof(Dev->controller_name), "%s%d", - bus_result->dev_name, - bus_result->unit_number); - strncpy(current_controller_name, Dev->controller_name, sizeof(current_controller_name)); - current_controller = Dev->controller; - Dev->controller_bus = bus_result->bus_id; - break; - } - case DEV_MATCH_DEVICE: - { - struct device_match_result* dev_result; - char tmpstr[256]; - - dev_result = &ccb.cdm.matches[i].result.device_result; - if(current_controller==-1||dev_result->target_id==-1) { - skip_device = 1; - break; - } - else skip_device = 0; - - cam_strvis(Dev->vendor, (u_int8_t*)dev_result->inq_data.vendor, - sizeof(dev_result->inq_data.vendor), - sizeof(Dev->vendor)); - cam_strvis(Dev->product, (u_int8_t*)dev_result->inq_data.product, - sizeof(dev_result->inq_data.product), - sizeof(Dev->product)); - cam_strvis(Dev->revision, (u_int8_t*)dev_result->inq_data.revision, - sizeof(dev_result->inq_data.revision), - sizeof(Dev->revision)); - strncpy(Dev->controller_name, current_controller_name, sizeof(Dev->controller_name)); - Dev->controller = current_controller; - Dev->unit = dev_result->target_id; - Dev->lun = dev_result->target_lun; - break; - } - case DEV_MATCH_PERIPH: - { - struct periph_match_result* periph_result; - - periph_result = &ccb.cdm.matches[i].result.periph_result; - - if(skip_device != 0) break; - - if(need_close==1) { - snprintf(Dev->device, sizeof(Dev->device), "%s%d*", - periph_result->periph_name, - periph_result->unit_number); - need_close = 0; - } - else if(need_close==0) { - snprintf(Dev->pass_device, sizeof(Dev->pass_device), "%s%d", - periph_result->periph_name, - periph_result->unit_number); - need_close++; - break; - } - else { - need_close = 0; - } - PrevDev = Dev; - Dev = _AllocNewDevice(); - break; - } - } - } - } while (ccb.ccb_h.status == CAM_REQ_CMP - && ccb.cdm.status == CAM_DEV_MATCH_MORE); - - /* Remove last one (ugly coding) */ - Devices = PrevDev; - delete Dev; -end_loop: - close(fd); -#else /* !CAM */ - /* - * FreeBSD 2.x SCSI management is quiet different and - * unfortunatly not flexible as CAM library in FreeBSD 3.x... - * I only scan for the first bus, LUN 0, and the - * first 8 devices only. - */ - u_char* inq_buf; - scsireq_t* scsireq; - struct scsi_addr scsi; - int ssc_fd; - - if((ssc_fd=open("/dev/ssc", O_RDWR))==-1) { - fprintf(stderr, "Cannot open SCSI manager: /dev/ssc\n"); - SCSIReset(); - return; - } - - inq_buf = (u_char*)malloc(96); - if(inq_buf==NULL) { - perror("malloc failed"); - SCSIReset(); - return; - } - - scsireq = scsireq_build((scsireq_t*)dev->dev_ptr, - 96, inq_buf, SCCMD_READ, - "12 0 0 0 v 0", 96); - - addr.scbus = 0; - addr.lun = 0; - - for(int n=0;n<8;n++) { - addr.target = n; - - if(ioctl(ssc_fd, SCIOCADDR, &addr) != -1) { - Dev = _AllocNewDevice(); - Dev->controller = addr.scbus; - Dev->lun = addr.lun; - Dev->unit = addr.target; - - struct scsi_devinfo devInfo; - devInfo.addr = addr; - if(ioctl(ssc_fd, SCIOCGETDEVINFO, &devInfo) != -1) { - strncpy(Dev->device, devInfo.devname, sizeof(Dev->device)); - } - strncpy(Dev->controller_name, "FreeBSD 2.x SCSI Manager", sizeof(Dev->controller_name)); - if(scsireq_enter(ssc_fd, scsireq)!=-1) { - Dev->vendor[sizeof(Dev->vendor)-1] = 0; - Dev->product[sizeof(Dev->product)-1] = 0; - Dev->revision[sizeof(Dev->revision)-1] = 0; - - scsireq_decode(scsireq, "s8 c8 c16 c4", - Dev->vendor, Dev->product, Dev->revision); - } - } - } - free(inq_buf); - close(ssc_fd); -#endif /* !CAM */ - _Build_SCSI_Controller(); - - // Print out the periph with ID:LUNs - fprintf(stderr, "Device RealID FkdID\n"); - fprintf(stderr, "----------------------------------------------\n"); - // 012345678901234567890123456789012 0:0:0 0/0 - dev = Devices; - while(dev) { - char tmp[40]; - snprintf(tmp, sizeof(tmp), "%s %s %s", - dev->vendor, - dev->product, - dev->revision); - fprintf(stderr, "%-33s %d:%d:%d %d/%d\n", - tmp, dev->controller, dev->unit, dev->lun, - dev->faked_unit, dev->lun); - dev = dev->next; - } - -no_scsi: - // Reset SCSI bus - SCSIReset(); -} - - -/* - * Deinitialization - */ - -void SCSIExit(void) -{ - SCSIDevice* aux; - while(Devices) { - aux = Devices->next; - if(Devices->dev_ptr!=NULL) { -#ifdef CAM - cam_close_device((struct cam_device*)Devices->dev_ptr); -#else /* !CAM */ - free(Devices->dev_ptr); // Is this right? - close(Devices->dev_fd); // And this one? -#endif /* !CAM */ - } - delete Devices; - Devices = aux; - } - nDevices = 0; -} - -int main() -{ - SCSIInit(); - SCSIExit(); - return 0; -} diff --git a/BasiliskII/src/Unix/Irix/README.networking b/BasiliskII/src/Unix/Irix/README.networking deleted file mode 100644 index f6145a71..00000000 --- a/BasiliskII/src/Unix/Irix/README.networking +++ /dev/null @@ -1,110 +0,0 @@ -README file for networking under IRIX -by Brian J. Johnson 7/23/2002 -version 1.0 -================================================== - -BasiliskII does not currently support networking natively on IRIX. -That is, the emulated Ethernet card does not do anything. There's no -reason one couldn't use raw domain sockets and the snoop(7p) facility -to do networking, but so far no one has written the required glue -code. - -However, it is possible to do TCP/IP networking with BasiliskII on -IRIX via PPP, by connecting an emulated serial port to the IRIX PPP -daemon. Here are the steps to set it up: - - -Set up PPP on IRIX ------------------- - -You need root privileges to do this. - -First, make sure you have eoe.sw.ppp and eoe.sw.uucp installed: - - IRIS# versions eoe.sw.ppp eoe.sw.uucp - I = Installed, R = Removed - - Name Date Description - - I eoe 07/22/2002 IRIX Execution Environment, 6.5.17m - I eoe.sw 07/22/2002 IRIX Execution Environment Software - I eoe.sw.ppp 07/22/2002 Point-to-Point Protocol Software - I eoe.sw.uucp 07/22/2002 UUCP Utilities - -If they aren't installed, install them from your distribution CDs. - -Next, pick IP addresses for the IRIX and MacOS sides of the PPP -connection. You may want to ask your local network administrator -about this, but any two unused addresses on your local subnet should -work. - -Edit /etc/ppp.conf and add these three lines: - -_NET_INCOMING - remotehost= - localhost= - -(Replace the angle brackets and the text in them with the appropriate -IP addresses.) - -Next, make a script to set up the environment properly when invoking -pppd from BasiliskII. You can name this whatever you want; I chose -/usr/etc/ppp-b2: - -IRIS# whoami -root -IRIS# cat < /usr/etc/ppp-b2 -#!/bin/sh -export USER=_NET_INCOMING -exec /usr/etc/ppp "$@" -IRIS# chmod 4775 /usr/etc/ppp-b2 - -Rewrite this in perl or python or C or whatever if you don't like -setuid shell scripts. The alternative is to run BasiliskII as root: -pppd _must_ be run as root. - - -Configure BasiliskII to start the PPP daemon --------------------------------------------- - -Start up BasiliskII, and in the serial devices tab, enter: - - |exec /usr/etc/ppp-b2 - -Supply the name you used for the script you created. Be sure to -include the leading pipe symbol ("|"). - -The "exec" causes your PPP startup script to replace the shell -BasiliskII runs to interpret the command. It's not strictly -necessary, but cuts down on the number of extra processes hanging -about. - - -Install a PPP client on MacOS ------------------------------ - -The details of this step will vary depending on your PPP client -software. Set it up for a "direct" connection, with no modem chatting -or login scripting. For instance, with FreePPP I set the "Connect:" -item on the "Edit..." screen under the "Accounts" tab to "Directly". -Be sure to select the correct serial port. The serial port speed -shouldn't matter (BasiliskII ignores it), but I set it to 115200 bps. - -Next, configure MacOS's TCP/IP stack. If you're using Open Transport, -Open the TCP/IP control panel and select "Using PPP Server" under the -"Configure" item. Copy IRIX's DNS client info. from /etc/resolv.conf -to the control panel: the addresses from the "nameserver" lines go in -the "Name server addr.:" box, and the domains from the "search" lines -go in the "Search domains:" box. The steps should be similar for -MacTCP. - -Now fire up PPP. Your PPP client should establish communication with -the IRIX PPP daemon, and you're off and running. - - -Disclaimer ----------- - -I haven't tried this procedure from scratch on a freshly installed -system, so I might have missed a step somewhere. But it should get -you close.... diff --git a/BasiliskII/src/Unix/Irix/audio_irix.cpp b/BasiliskII/src/Unix/Irix/audio_irix.cpp deleted file mode 100644 index ebd8eb69..00000000 --- a/BasiliskII/src/Unix/Irix/audio_irix.cpp +++ /dev/null @@ -1,680 +0,0 @@ -/* - * audio_irix.cpp - Audio support, SGI Irix implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "audio.h" -#include "audio_defs.h" - -#define DEBUG 0 -#include "debug.h" - - -// The currently selected audio parameters (indices in audio_sample_rates[] -// etc. vectors) -static int audio_sample_rate_index = 0; -static int audio_sample_size_index = 0; -static int audio_channel_count_index = 0; - -// Global variables -static int audio_fd = -1; // fd from audio library -static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read -static bool sem_inited = false; // Flag: audio_irq_done_sem initialized -static int sound_buffer_size; // Size of sound buffer in bytes -static int sound_buffer_fill_point; // Fill buffer when this many frames are empty -static uint8 silence_byte = 0; // Byte value to use to fill sound buffers with silence -static pthread_t stream_thread; // Audio streaming thread -static pthread_attr_t stream_thread_attr; // Streaming thread attributes -static bool stream_thread_active = false; // Flag: streaming thread installed -static volatile bool stream_thread_cancel = false; // Flag: cancel streaming thread - -static bool current_main_mute = false; // Flag: output muted -static bool current_speaker_mute = false; // Flag: speaker muted -static uint32 current_main_volume = 0; // Output volume -static uint32 current_speaker_volume = 0; // Speaker volume - -// IRIX libaudio control structures -static ALconfig config; -static ALport port; - - -// Prototypes -static void *stream_func(void *arg); -static uint32 read_volume(void); -static bool read_mute(void); -static void set_mute(bool mute); - - -/* - * Initialization - */ - -// Set AudioStatus to reflect current audio stream format -static void set_audio_status_format(void) -{ - AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index]; - AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index]; - AudioStatus.channels = audio_channel_counts[audio_channel_count_index]; -} - -bool open_audio(void) -{ - ALpv pv[2]; - - printf("Using libaudio audio output\n"); - - // Get supported sample formats - - if (audio_sample_sizes.empty()) { - // All sample sizes are supported - audio_sample_sizes.push_back(8); - audio_sample_sizes.push_back(16); - - // Assume at least two channels are supported. Some IRIX boxes - // can do 4 or more... MacOS only handles up to 2. - audio_channel_counts.push_back(1); - audio_channel_counts.push_back(2); - - if (audio_sample_sizes.empty() || audio_channel_counts.empty()) { - WarningAlert(GetString(STR_AUDIO_FORMAT_WARN)); - alClosePort(port); - audio_fd = -1; - return false; - } - - audio_sample_rates.push_back( 8000 << 16); - audio_sample_rates.push_back(11025 << 16); - audio_sample_rates.push_back(22050 << 16); - audio_sample_rates.push_back(44100 << 16); - - // Default to highest supported values - audio_sample_rate_index = audio_sample_rates.size() - 1; - audio_sample_size_index = audio_sample_sizes.size() - 1; - audio_channel_count_index = audio_channel_counts.size() - 1; - } - - // Set the sample format - - D(bug("Size %d, channels %d, rate %d\n", - audio_sample_sizes[audio_sample_size_index], - audio_channel_counts[audio_channel_count_index], - audio_sample_rates[audio_sample_rate_index] >> 16)); - config = alNewConfig(); - alSetSampFmt(config, AL_SAMPFMT_TWOSCOMP); - if (audio_sample_sizes[audio_sample_size_index] == 8) { - alSetWidth(config, AL_SAMPLE_8); - } - else { - alSetWidth(config, AL_SAMPLE_16); - } - alSetChannels(config, audio_channel_counts[audio_channel_count_index]); - alSetDevice(config, AL_DEFAULT_OUTPUT); // Allow selecting via prefs? - - // Try to open the audio library - - port = alOpenPort("BasiliskII", "w", config); - if (port == NULL) { - fprintf(stderr, "ERROR: Cannot open audio port: %s\n", - alGetErrorString(oserror())); - WarningAlert(GetString(STR_NO_AUDIO_WARN)); - return false; - } - - // Set the sample rate - - pv[0].param = AL_RATE; - pv[0].value.ll = alDoubleToFixed(audio_sample_rates[audio_sample_rate_index] >> 16); - pv[1].param = AL_MASTER_CLOCK; - pv[1].value.i = AL_CRYSTAL_MCLK_TYPE; - if (alSetParams(AL_DEFAULT_OUTPUT, pv, 2) < 0) { - fprintf(stderr, "ERROR: libaudio setparams failed: %s\n", - alGetErrorString(oserror())); - alClosePort(port); - return false; - } - - // Compute sound buffer size and libaudio refill point - - config = alGetConfig(port); - audio_frames_per_block = alGetQueueSize(config); - if (audio_frames_per_block < 0) { - fprintf(stderr, "ERROR: couldn't get queue size: %s\n", - alGetErrorString(oserror())); - alClosePort(port); - return false; - } - D(bug("alGetQueueSize %d, width %d, channels %d\n", - audio_frames_per_block, - alGetWidth(config), - alGetChannels(config))); - - // Put a limit on the Mac sound buffer size, to decrease delay -#define AUDIO_BUFFER_MSEC 50 // milliseconds of sound to buffer - int target_frames_per_block = - (audio_sample_rates[audio_sample_rate_index] >> 16) * - AUDIO_BUFFER_MSEC / 1000; - if (audio_frames_per_block > target_frames_per_block) - audio_frames_per_block = target_frames_per_block; - D(bug("frames per block %d\n", audio_frames_per_block)); - - alZeroFrames(port, audio_frames_per_block); // so we don't underflow - - // Try to keep the buffer pretty full - sound_buffer_fill_point = alGetQueueSize(config) - - 2 * audio_frames_per_block; - if (sound_buffer_fill_point < 0) - sound_buffer_fill_point = alGetQueueSize(config) / 3; - D(bug("fill point %d\n", sound_buffer_fill_point)); - - sound_buffer_size = (audio_sample_sizes[audio_sample_size_index] >> 3) * - audio_channel_counts[audio_channel_count_index] * - audio_frames_per_block; - set_audio_status_format(); - - // Get a file descriptor we can select() on - - audio_fd = alGetFD(port); - if (audio_fd < 0) { - fprintf(stderr, "ERROR: couldn't get libaudio file descriptor: %s\n", - alGetErrorString(oserror())); - alClosePort(port); - return false; - } - - // Initialize volume, mute settings - current_main_volume = current_speaker_volume = read_volume(); - current_main_mute = current_speaker_mute = read_mute(); - - - // Start streaming thread - Set_pthread_attr(&stream_thread_attr, 0); - stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0); - - // Everything went fine - audio_open = true; - return true; -} - -void AudioInit(void) -{ - // Init audio status (reasonable defaults) and feature flags - AudioStatus.sample_rate = 44100 << 16; - AudioStatus.sample_size = 16; - AudioStatus.channels = 2; - AudioStatus.mixer = 0; - AudioStatus.num_sources = 0; - audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; - - // Sound disabled in prefs? Then do nothing - if (PrefsFindBool("nosound")) - return; - - // Init semaphore - if (sem_init(&audio_irq_done_sem, 0, 0) < 0) - return; - sem_inited = true; - - // Open and initialize audio device - open_audio(); -} - - -/* - * Deinitialization - */ - -static void close_audio(void) -{ - // Stop stream and delete semaphore - if (stream_thread_active) { - stream_thread_cancel = true; -#ifdef HAVE_PTHREAD_CANCEL - pthread_cancel(stream_thread); -#endif - pthread_join(stream_thread, NULL); - stream_thread_active = false; - stream_thread_cancel = false; - } - - // Close audio library - alClosePort(port); - - audio_open = false; -} - -void AudioExit(void) -{ - // Close audio device - close_audio(); - - // Delete semaphore - if (sem_inited) { - sem_destroy(&audio_irq_done_sem); - sem_inited = false; - } -} - - -/* - * First source added, start audio stream - */ - -void audio_enter_stream() -{ - // Streaming thread is always running to avoid clicking noises -} - - -/* - * Last source removed, stop audio stream - */ - -void audio_exit_stream() -{ - // Streaming thread is always running to avoid clicking noises -} - - -/* - * Streaming function - */ - -static void *stream_func(void *arg) -{ - int32 *last_buffer = new int32[sound_buffer_size / 4]; - fd_set audio_fdset; - int numfds, was_error; - - numfds = audio_fd + 1; - FD_ZERO(&audio_fdset); - - while (!stream_thread_cancel) { - if (AudioStatus.num_sources) { - - // Trigger audio interrupt to get new buffer - D(bug("stream: triggering irq\n")); - SetInterruptFlag(INTFLAG_AUDIO); - TriggerInterrupt(); - D(bug("stream: waiting for ack\n")); - sem_wait(&audio_irq_done_sem); - D(bug("stream: ack received\n")); - - // Get size of audio data - uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (!current_main_mute && - !current_speaker_mute && - apple_stream_info) { - int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels; - D(bug("stream: work_size %d\n", work_size)); - if (work_size > sound_buffer_size) - work_size = sound_buffer_size; - if (work_size == 0) - goto silence; - - // Send data to audio library. Convert 8-bit data - // unsigned->signed, using same algorithm as audio_amiga.cpp. - // It works fine for 8-bit mono, but not stereo. - if (AudioStatus.sample_size == 8) { - uint32 *p = (uint32 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)); - uint32 *q = (uint32 *)last_buffer; - int r = work_size >> 2; - // XXX not quite right.... - while (r--) - *q++ = *p++ ^ 0x80808080; - if (work_size != sound_buffer_size) - memset((uint8 *)last_buffer + work_size, silence_byte, sound_buffer_size - work_size); - alWriteFrames(port, last_buffer, audio_frames_per_block); - } - else if (work_size == sound_buffer_size) - alWriteFrames(port, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), audio_frames_per_block); - else { - // Last buffer - Mac2Host_memcpy(last_buffer, ReadMacInt32(apple_stream_info + scd_buffer), work_size); - memset((uint8 *)last_buffer + work_size, silence_byte, sound_buffer_size - work_size); - alWriteFrames(port, last_buffer, audio_frames_per_block); - } - D(bug("stream: data written\n")); - } else - goto silence; - - } else { - - // Audio not active, play silence - silence: // D(bug("stream: silence\n")); - alZeroFrames(port, audio_frames_per_block); - } - - // Wait for fill point to be reached (may be immediate) - - if (alSetFillPoint(port, sound_buffer_fill_point) < 0) { - fprintf(stderr, "ERROR: alSetFillPoint failed: %s\n", - alGetErrorString(oserror())); - // Should stop the audio here.... - } - - do { - errno = 0; - FD_SET(audio_fd, &audio_fdset); - was_error = select(numfds, NULL, &audio_fdset, NULL, NULL); - } while(was_error < 0 && (errno == EINTR)); - if (was_error < 0) { - fprintf(stderr, "ERROR: select returned %d, errno %d\n", - was_error, errno); - // Should stop audio here.... - } - } - delete[] last_buffer; - return NULL; -} - - -/* - * Read or set the current output volume using the audio library - */ - -static uint32 read_volume(void) -{ - ALpv x[2]; - ALfixed gain[8]; - double maxgain, mingain; - ALparamInfo pi; - uint32 ret = 0x01000100; // default, maximum value - int dev = alGetDevice(config); - - // Fetch the maximum and minimum gain settings - - alGetParamInfo(dev, AL_GAIN, &pi); - maxgain = alFixedToDouble(pi.max.ll); - mingain = alFixedToDouble(pi.min.ll); -// printf("maxgain = %lf dB, mingain = %lf dB\n", maxgain, mingain); - - // Get the current gain values - - x[0].param = AL_GAIN; - x[0].value.ptr = gain; - x[0].sizeIn = sizeof(gain) / sizeof(gain[0]); - x[1].param = AL_CHANNELS; - if (alGetParams(dev, x, 2) < 0) { - printf("alGetParams failed: %s\n", alGetErrorString(oserror())); - } - else { - if (x[0].sizeOut < 0) { - printf("AL_GAIN was an unrecognized parameter\n"); - } - else { - double v; - uint32 left, right; - - // Left - v = alFixedToDouble(gain[0]); - if (v < mingain) - v = mingain; // handle gain == -inf - v = (v - mingain) / (maxgain - mingain); // scale to 0..1 - left = (uint32)(v * (double)256); // convert to 8.8 fixed point - - // Right - if (x[0].sizeOut <= 1) { // handle a mono interface - right = left; - } - else { - v = alFixedToDouble(gain[1]); - if (v < mingain) - v = mingain; // handle gain == -inf - v = (v - mingain) / (maxgain - mingain); // scale to 0..1 - right = (uint32)(v * (double)256); // convert to 8.8 fixed point - } - - ret = (left << 16) | right; - } - } - - return ret; -} - -static void set_volume(uint32 vol) -{ - ALpv x[1]; - ALfixed gain[2]; // left and right - double maxgain, mingain; - ALparamInfo pi; - int dev = alGetDevice(config); - - // Fetch the maximum and minimum gain settings - - alGetParamInfo(dev, AL_GAIN, &pi); - maxgain = alFixedToDouble(pi.max.ll); - mingain = alFixedToDouble(pi.min.ll); - - // Set the new gain values - - x[0].param = AL_GAIN; - x[0].value.ptr = gain; - x[0].sizeIn = sizeof(gain) / sizeof(gain[0]); - - uint32 left = vol >> 16; - uint32 right = vol & 0xffff; - double lv, rv; - - if (left == 0 && pi.specialVals & AL_NEG_INFINITY_BIT) { - lv = AL_NEG_INFINITY; - } - else { - lv = ((double)left / 256) * (maxgain - mingain) + mingain; - } - - if (right == 0 && pi.specialVals & AL_NEG_INFINITY_BIT) { - rv = AL_NEG_INFINITY; - } - else { - rv = ((double)right / 256) * (maxgain - mingain) + mingain; - } - - D(bug("set_volume: left=%lf dB, right=%lf dB\n", lv, rv)); - - gain[0] = alDoubleToFixed(lv); - gain[1] = alDoubleToFixed(rv); - - if (alSetParams(dev, x, 1) < 0) { - printf("alSetParams failed: %s\n", alGetErrorString(oserror())); - } -} - - -/* - * Read or set the mute setting using the audio library - */ - -static bool read_mute(void) -{ - bool ret; - int dev = alGetDevice(config); - ALpv x; - x.param = AL_MUTE; - - if (alGetParams(dev, &x, 1) < 0) { - printf("alSetParams failed: %s\n", alGetErrorString(oserror())); - return current_main_mute; // Or just return false? - } - - ret = x.value.i; - - D(bug("read_mute: mute=%d\n", ret)); - return ret; -} - -static void set_mute(bool mute) -{ - D(bug("set_mute: mute=%ld\n", mute)); - - int dev = alGetDevice(config); - ALpv x; - x.param = AL_MUTE; - x.value.i = mute; - - if (alSetParams(dev, &x, 1) < 0) { - printf("alSetParams failed: %s\n", alGetErrorString(oserror())); - } -} - - - -/* - * MacOS audio interrupt, read next data block - */ - -void AudioInterrupt(void) -{ - D(bug("AudioInterrupt\n")); - - // Get data from apple mixer - if (AudioStatus.mixer) { - M68kRegisters r; - r.a[0] = audio_data + adatStreamInfo; - r.a[1] = AudioStatus.mixer; - Execute68k(audio_data + adatGetSourceData, &r); - D(bug(" GetSourceData() returns %08lx\n", r.d[0])); - } else - WriteMacInt32(audio_data + adatStreamInfo, 0); - - // Signal stream function - sem_post(&audio_irq_done_sem); - D(bug("AudioInterrupt done\n")); -} - - -/* - * Set sampling parameters - * "index" is an index into the audio_sample_rates[] etc. vectors - * It is guaranteed that AudioStatus.num_sources == 0 - */ - -bool audio_set_sample_rate(int index) -{ - close_audio(); - audio_sample_rate_index = index; - return open_audio(); -} - -bool audio_set_sample_size(int index) -{ - close_audio(); - audio_sample_size_index = index; - return open_audio(); -} - -bool audio_set_channels(int index) -{ - close_audio(); - audio_channel_count_index = index; - return open_audio(); -} - - -/* - * Get/set volume controls (volume values received/returned have the left channel - * volume in the upper 16 bits and the right channel volume in the lower 16 bits; - * both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume")) - */ - -bool audio_get_main_mute(void) -{ - D(bug("audio_get_main_mute: mute=%ld\n", current_main_mute)); - - return current_main_mute; -} - -uint32 audio_get_main_volume(void) -{ - uint32 ret = current_main_volume; - - D(bug("audio_get_main_volume: vol=0x%x\n", ret)); - - return ret; -} - -bool audio_get_speaker_mute(void) -{ - D(bug("audio_get_speaker_mute: mute=%ld\n", current_speaker_mute)); - - return current_speaker_mute; -} - -uint32 audio_get_speaker_volume(void) -{ - uint32 ret = current_speaker_volume; - - D(bug("audio_get_speaker_volume: vol=0x%x\n", ret)); - - return ret; -} - -void audio_set_main_mute(bool mute) -{ - D(bug("audio_set_main_mute: mute=%ld\n", mute)); - - if (mute != current_main_mute) { - current_main_mute = mute; - } - - set_mute(current_main_mute); -} - -void audio_set_main_volume(uint32 vol) -{ - - D(bug("audio_set_main_volume: vol=%x\n", vol)); - - current_main_volume = vol; - - set_volume(vol); -} - -void audio_set_speaker_mute(bool mute) -{ - D(bug("audio_set_speaker_mute: mute=%ld\n", mute)); - - if (mute != current_speaker_mute) { - current_speaker_mute = mute; - } - - set_mute(current_speaker_mute); -} - -void audio_set_speaker_volume(uint32 vol) -{ - D(bug("audio_set_speaker_volume: vol=%x\n", vol)); - - current_speaker_volume = vol; - - set_volume(vol); -} diff --git a/BasiliskII/src/Unix/Irix/unaligned.c b/BasiliskII/src/Unix/Irix/unaligned.c deleted file mode 100644 index 9f4befb8..00000000 --- a/BasiliskII/src/Unix/Irix/unaligned.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Irix/unaligned.c - Optimized unaligned access for Irix - * - * Basilisk II (C) 1997-2005 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef sgi -#include "sysdeps.h" - -/* Tell the compiler to pack data on 1-byte boundaries - * (i.e. arbitrary alignment). Requires SGI MIPSPro compilers. */ -#pragma pack(1) - -typedef struct _ual32 { - uae_u32 v; -} ual32_t; - -typedef struct _ual16 { - uae_u16 v; -} ual16_t; - -#pragma pack(0) - -/* The compiler is smart enough to inline these when you build with "-ipa" */ -uae_u32 do_get_mem_long(uae_u32 *a) {return ((ual32_t *)a)->v;} -uae_u32 do_get_mem_word(uae_u16 *a) {return ((ual16_t *)a)->v;} -void do_put_mem_long(uae_u32 *a, uae_u32 v) {((ual32_t *)a)->v = v;} -void do_put_mem_word(uae_u16 *a, uae_u32 v) {((ual16_t *)a)->v = v;} - -#endif /* sgi */ diff --git a/BasiliskII/src/Unix/Linux/NetDriver/Makefile b/BasiliskII/src/Unix/Linux/NetDriver/Makefile deleted file mode 100644 index 50a1d238..00000000 --- a/BasiliskII/src/Unix/Linux/NetDriver/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# Linux makefile for sheep_net driver -KERNEL_DIR = /lib/modules/$(shell uname -r) -KERNEL_SOURCE = $(KERNEL_DIR)/build -LV := $(shell test -f $(KERNEL_SOURCE)/Rules.make && echo 24 || echo 26) -MP := $(shell test -f $(KERNEL_SOURCE)/Rules.make && echo "o" || echo "ko") - -ifeq ($(LV),26) -# Kernel 2.6 - -KERNEL_DRIVER = $(KERNEL_DIR)/kernel/drivers -obj-m = sheep_net.o - -sheep_net.ko: sheep_net.c - $(MAKE) -C $(KERNEL_SOURCE) M=$$PWD modules - -clean: - $(MAKE) -C $(KERNEL_SOURCE) M=$$PWD clean - -else -# Kernel 2.4 - -## System specific configuration -CPPFLAGS = -I. -I$(KERNEL_SOURCE)/include -CFLAGS = -O2 -Wall -D__KERNEL__ -DMODULE -D_LOOSE_KERNEL_NAMES -ASFLAGS = -LDFLAGS = -LIBS = - -## Files -KERNEL_DRIVER = $(KERNEL_DIR) -OBJS = sheep_net.o - -## Rules -sheep_net.o: sheep_net.c - $(CC) -c $(CPPFLAGS) $(CFLAGS) sheep_net.c - -clean: - -rm $(OBJS) - -dep depend: - makedepend $(CPPFLAGS) -Y *.c - -endif - -dev: - mknod /dev/sheep_net c 10 198 - -install: sheep_net.$(MP) - install -d $(KERNEL_DRIVER)/misc - install -m 644 sheep_net.$(MP) $(KERNEL_DRIVER)/misc - depmod -a - -# DO NOT DELETE diff --git a/BasiliskII/src/Unix/Linux/NetDriver/config.h b/BasiliskII/src/Unix/Linux/NetDriver/config.h deleted file mode 120000 index fc383f11..00000000 --- a/BasiliskII/src/Unix/Linux/NetDriver/config.h +++ /dev/null @@ -1 +0,0 @@ -../../../../../SheepShaver/src/Unix/config.h \ No newline at end of file diff --git a/BasiliskII/src/Unix/Linux/NetDriver/sheep_net.c b/BasiliskII/src/Unix/Linux/NetDriver/sheep_net.c deleted file mode 100644 index b02153f0..00000000 --- a/BasiliskII/src/Unix/Linux/NetDriver/sheep_net.c +++ /dev/null @@ -1,770 +0,0 @@ -/* - * sheep_net.c - Linux driver for SheepShaver/Basilisk II networking (access to raw Ethernet packets) - * - * sheep_net (C) 1999-2004 Mar"c" Hellwig and Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -/* modversions.h redefines kernel symbols. Now include other headers */ -#include -#include -#include -#include - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0) -#define LINUX_3_15 -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) -#define LINUX_26_35 -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) -#define LINUX_26_36 -#endif - -/* Compatibility glue */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) -#define LINUX_26_30 - -#else - -/* determine whether to use checksummed versions of kernel symbols */ -/*** -#include -***/ -#include "config.h" -#include - -#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) -#define MODVERSIONS -#endif - -#if defined(MODVERSIONS) -#include -#endif - -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Christian Bauer"); -MODULE_DESCRIPTION("Pseudo ethernet device for emulators"); - -/* Compatibility glue */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -#define LINUX_26 -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -#define LINUX_24 -#else -#define net_device device -typedef struct wait_queue *wait_queue_head_t; -#define init_waitqueue_head(x) *(x)=NULL -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) -#define eth_hdr(skb) (skb)->mac.ethernet -#define skb_mac_header(skb) (skb)->mac.raw -#define ipip_hdr(skb) (skb)->h.ipiph -#endif - -#ifdef LINUX_26 -#define skt_set_dead(skt) do {} while(0) -#define wmem_alloc sk_wmem_alloc -#else -#define skt_set_dead(skt) (skt)->dead = 1 -#endif - -#define DEBUG 0 - -#define bug printk -#if DEBUG -#define D(x) (x); -#else -#define D(x) ; -#endif - - -/* Constants */ -#define SHEEP_NET_MINOR 198 /* Driver minor number */ -#define MAX_QUEUE 32 /* Maximum number of packets in queue */ -#define PROT_MAGIC 1520 /* Our "magic" protocol type */ - -#define ETH_ADDR_MULTICAST 0x1 -#define ETH_ADDR_LOCALLY_DEFINED 0x02 - -#define SIOC_MOL_GET_IPFILTER SIOCDEVPRIVATE -#define SIOC_MOL_SET_IPFILTER (SIOCDEVPRIVATE + 1) - -/* Prototypes */ -static int sheep_net_open(struct inode *inode, struct file *f); -static int sheep_net_release(struct inode *inode, struct file *f); -static ssize_t sheep_net_read(struct file *f, char *buf, size_t count, loff_t *off); -static ssize_t sheep_net_write(struct file *f, const char *buf, size_t count, loff_t *off); -static unsigned int sheep_net_poll(struct file *f, struct poll_table_struct *wait); -#ifdef LINUX_26_36 -static long sheep_net_ioctl(struct file *f, unsigned int code, unsigned long arg); -#else -static int sheep_net_ioctl(struct inode *inode, struct file *f, unsigned int code, unsigned long arg); -#endif -#ifdef LINUX_26 -static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *foo); -#else -static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt); -#endif - -/* - * Driver private variables - */ - -struct SheepVars { - /* IMPORTANT: the packet_type struct must go first. It no longer - (2.6) contains * a data field so we typecast to get the SheepVars - struct */ - struct packet_type pt; /* Receiver packet type */ - struct net_device *ether; /* The Ethernet device we're attached to */ - struct sock *skt; /* Socket for communication with Ethernet card */ - struct sk_buff_head queue; /* Receiver packet queue */ - wait_queue_head_t wait; /* Wait queue for blocking read operations */ - u32 ipfilter; /* Only receive IP packets destined for this address (host byte order) */ - char eth_addr[6]; /* Hardware address of the Ethernet card */ - char fake_addr[6]; /* Local faked hardware address (what SheepShaver sees) */ -#ifdef LINUX_3_15 - atomic_t got_packet; -#endif -}; - - -/* - * file_operations structure - has function pointers to the - * various entry points for device operations - */ - -static struct file_operations sheep_net_fops = { - .owner = THIS_MODULE, - .read = sheep_net_read, - .write = sheep_net_write, - .poll = sheep_net_poll, -#ifdef LINUX_26_36 - .unlocked_ioctl = sheep_net_ioctl, -#else - .ioctl = sheep_net_ioctl, -#endif - .open = sheep_net_open, - .release = sheep_net_release, -}; - - -/* - * miscdevice structure for driver initialization - */ - -static struct miscdevice sheep_net_device = { - .minor = SHEEP_NET_MINOR, /* minor number */ - .name = "sheep_net", /* name */ - .fops = &sheep_net_fops -}; - - -/* - * fake protocol to use a common socket - */ -static struct proto sheep_proto = { - .name = "SHEEP", - .owner = THIS_MODULE, - .obj_size = sizeof(struct sock), -}; - - -/* - * Initialize module - */ - -int init_module(void) -{ - int ret; - - /* Register driver */ - ret = misc_register(&sheep_net_device); - D(bug("Sheep net driver installed\n")); - return ret; -} - - -/* - * Deinitialize module - */ - -void cleanup_module(void) -{ - /* Unregister driver */ - misc_deregister(&sheep_net_device); - D(bug("Sheep net driver removed\n")); -} - - -/* - * Driver open() function - */ - -static int sheep_net_open(struct inode *inode, struct file *f) -{ - struct SheepVars *v; - D(bug("sheep_net: open\n")); - - /* Must be opened with read permissions */ - if ((f->f_flags & O_ACCMODE) == O_WRONLY) - return -EPERM; - - /* Allocate private variables */ - v = (struct SheepVars *)kmalloc(sizeof(struct SheepVars), GFP_USER); - if (v == NULL) - return -ENOMEM; - -#ifndef LINUX_26_30 - lock_kernel(); -#endif - memset(v, 0, sizeof(struct SheepVars)); - skb_queue_head_init(&v->queue); - init_waitqueue_head(&v->wait); - v->fake_addr[0] = 'v'; /* "SheepShaver" */ - v->fake_addr[1] = 'r'; /* ^ ^ */ - get_random_bytes(&v->fake_addr[2], 4); - - /* Put our stuff where we will be able to find it later */ - f->private_data = (void *)v; - - /* Yes, we're open */ -#ifndef LINUX_26 - MOD_INC_USE_COUNT; -#endif -#ifndef LINUX_26_30 - unlock_kernel(); -#endif - return 0; -} - - -/* - * Driver release() function - */ - -static int sheep_net_release(struct inode *inode, struct file *f) -{ - struct SheepVars *v = (struct SheepVars *)f->private_data; - struct sk_buff *skb; - D(bug("sheep_net: close\n")); - - /* Detach from Ethernet card */ - if (v->ether) { - dev_remove_pack(&v->pt); - sk_free(v->skt); - v->skt = NULL; -#ifdef LINUX_24 - dev_put( v->ether ); -#endif - v->ether = NULL; - } - - /* Empty packet queue */ - while ((skb = skb_dequeue(&v->queue)) != NULL) - dev_kfree_skb(skb); - - /* Free private variables */ - kfree(v); - - /* Sorry, we're closed */ -#ifndef LINUX_26 - MOD_DEC_USE_COUNT; -#endif - return 0; -} - - -/* - * Check whether an Ethernet address is the local (attached) one or - * the fake one - */ - -static inline int is_local_addr(struct SheepVars *v, void *a) -{ - return memcmp(a, v->eth_addr, 6) == 0; -} - -static inline int is_fake_addr(struct SheepVars *v, void *a) -{ - return memcmp(a, v->fake_addr, 6) == 0; -} - - -/* - * Outgoing packet. Replace the fake enet addr with the real local one. - */ - -static inline void do_demasq(struct SheepVars *v, u8 *p) -{ - memcpy(p, v->eth_addr, 6); -} - -static void demasquerade(struct SheepVars *v, struct sk_buff *skb) -{ - u8 *p = skb_mac_header(skb); - int proto = (p[12] << 8) | p[13]; - - do_demasq(v, p + 6); /* source address */ - - /* Need to fix ARP packets */ - if (proto == ETH_P_ARP) { - if (is_fake_addr(v, p + 14 + 8)) /* sender HW-addr */ - do_demasq(v, p + 14 + 8); - } - - /* ...and AARPs (snap code: 0x00,0x00,0x00,0x80,0xF3) */ - if (p[17] == 0 && p[18] == 0 && p[19] == 0 && p[20] == 0x80 && p[21] == 0xf3) { - /* XXX: we should perhaps look for the 802 frame too */ - if (is_fake_addr(v, p + 30)) - do_demasq(v, p + 30); /* sender HW-addr */ - } -} - - -/* - * Incoming packet. Replace the local enet addr with the fake one. - */ - -static inline void do_masq(struct SheepVars *v, u8 *p) -{ - memcpy(p, v->fake_addr, 6); -} - -static void masquerade(struct SheepVars *v, struct sk_buff *skb) -{ - u8 *p = skb_mac_header(skb); - if (!(p[0] & ETH_ADDR_MULTICAST)) - do_masq(v, p); /* destination address */ - - /* XXX: reverse ARP might need to be fixed */ -} - - -/* - * Driver read() function - */ - -static ssize_t sheep_net_read(struct file *f, char *buf, size_t count, loff_t *off) -{ - struct SheepVars *v = (struct SheepVars *)f->private_data; - struct sk_buff *skb; - - D(bug("sheep_net: read\n")); - - for (;;) { - - /* Get next packet from queue */ - skb = skb_dequeue(&v->queue); - if (skb != NULL || (f->f_flags & O_NONBLOCK)) - break; - - /* No packet in queue and in blocking mode, so block */ -#ifdef LINUX_3_15 - atomic_set(&v->got_packet, 0); - wait_event_interruptible(v->wait, atomic_read(&v->got_packet)); -#else - interruptible_sleep_on(&v->wait); -#endif - - /* Signal received? Then bail out */ - if (signal_pending(current)) - return -EINTR; - } - if (skb == NULL) - return -EAGAIN; - - /* Pass packet to caller */ - if (count > skb->len) - count = skb->len; - if (copy_to_user(buf, skb->data, count)) - count = -EFAULT; - dev_kfree_skb(skb); - return count; -} - - -/* - * Driver write() function - */ - -static inline void do_nothing(struct sk_buff *skb) -{ - return; -} - -static ssize_t sheep_net_write(struct file *f, const char *buf, size_t count, loff_t *off) -{ - struct SheepVars *v = (struct SheepVars *)f->private_data; - struct sk_buff *skb; - char *p; - D(bug("sheep_net: write\n")); - - /* Check packet size */ - if (count < sizeof(struct ethhdr)) - return -EINVAL; - if (count > 1514) { - printk("sheep_net_write: packet size %ld > 1514\n", count); - count = 1514; - } - - /* Interface active? */ - if (v->ether == NULL) - return count; - - /* Allocate buffer for packet */ - skb = dev_alloc_skb(count); - if (skb == NULL) - return -ENOBUFS; - - /* Stuff packet in buffer */ - p = skb_put(skb, count); - if (copy_from_user(p, buf, count)) { - kfree_skb(skb); - return -EFAULT; - } - - /* Transmit packet */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) - atomic_add(skb->truesize, &v->skt->wmem_alloc); -#endif - skb->sk = v->skt; - skb->dev = v->ether; - skb->priority = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) - skb->nh.raw = skb->h.raw = skb->data + v->ether->hard_header_len; - skb->mac.raw = skb->data; -#else - skb_reset_mac_header(skb); - skb_set_transport_header(skb, v->ether->hard_header_len); - skb_set_network_header(skb, v->ether->hard_header_len); -#endif - - /* Base the IP-filtering on the IP address in any outgoing ARP packets */ - if (eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) { - u8 *p = &skb->data[14+14]; /* source IP address */ - u32 ip = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; - if (ip != v->ipfilter) { - v->ipfilter = ip; - printk("sheep_net: ipfilter set to %d.%d.%d.%d\n", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); - } - } - - /* Is this packet addressed solely to the local host? */ - if (is_local_addr(v, skb->data) && !(skb->data[0] & ETH_ADDR_MULTICAST)) { - skb->destructor = do_nothing; - skb->protocol = eth_type_trans(skb, v->ether); - netif_rx(skb); - return count; - } - if (skb->data[0] & ETH_ADDR_MULTICAST) { - /* We can't clone the skb since we will manipulate the data below */ - struct sk_buff *lskb = skb_copy(skb, GFP_ATOMIC); - if (lskb) { - lskb->protocol = eth_type_trans(lskb, v->ether); - netif_rx(lskb); - } - } - - /* Outgoing packet (will be on the net) */ - demasquerade(v, skb); - - skb->destructor = do_nothing; - skb->protocol = PROT_MAGIC; /* Magic value (we can recognize the packet in sheep_net_receiver) */ - dev_queue_xmit(skb); - return count; -} - - -/* - * Driver poll() function - */ - -static unsigned int sheep_net_poll(struct file *f, struct poll_table_struct *wait) -{ - struct SheepVars *v = (struct SheepVars *)f->private_data; - D(bug("sheep_net: poll\n")); - - /* Packets in queue? Then return */ - if (!skb_queue_empty(&v->queue)) - return POLLIN | POLLRDNORM; - - /* Otherwise wait for packet */ - poll_wait(f, &v->wait, wait); - if (!skb_queue_empty(&v->queue)) - return POLLIN | POLLRDNORM; - else - return 0; -} - - -/* - * Driver ioctl() function - */ - -#ifdef LINUX_26_36 -static long sheep_net_ioctl(struct file *f, unsigned int code, unsigned long arg) -#else -static int sheep_net_ioctl(struct inode *inode, struct file *f, unsigned int code, unsigned long arg) -#endif -{ - struct SheepVars *v = (struct SheepVars *)f->private_data; - D(bug("sheep_net: ioctl %04x\n", code)); - - switch (code) { - - /* Attach to Ethernet card - arg: pointer to name of Ethernet device (char[20]) */ - case SIOCSIFLINK: { - char name[20]; - int err; - - /* Already attached? */ - if (v->ether) - return -EBUSY; - - /* Get Ethernet card name */ - if (copy_from_user(name, (void *)arg, 20)) - return -EFAULT; - name[19] = 0; - - /* Find card */ -#ifdef LINUX_26 - v->ether = dev_get_by_name(&init_net, name); -#elif defined(LINUX_24) - v->ether = dev_get_by_name(name); -#else - dev_lock_list(); - v->ether = dev_get(name); -#endif - if (v->ether == NULL) { - err = -ENODEV; - goto error; - } - - /* Is it Ethernet? */ - if (v->ether->type != ARPHRD_ETHER) { - err = -EINVAL; - goto error; - } - - /* Remember the card's hardware address */ - memcpy(v->eth_addr, v->ether->dev_addr, 6); - - /* Allocate socket */ -#ifdef LINUX_26 - v->skt = sk_alloc(dev_net(v->ether), GFP_USER, 1, &sheep_proto); -#else - v->skt = sk_alloc(0, GFP_USER, 1); -#endif - if (v->skt == NULL) { - err = -ENOMEM; - goto error; - } - skt_set_dead(v->skt); - - /* Attach packet handler */ - v->pt.type = htons(ETH_P_ALL); - v->pt.dev = v->ether; - v->pt.func = sheep_net_receiver; - dev_add_pack(&v->pt); -#ifndef LINUX_24 - dev_unlock_list(); -#endif - return 0; - -error: -#ifdef LINUX_24 - if (v->ether) - dev_put(v->ether); -#else - dev_unlock_list(); -#endif - v->ether = NULL; - return err; - } - - /* Get hardware address of the sheep_net module - arg: pointer to buffer (6 bytes) to store address */ - case SIOCGIFADDR: - if (copy_to_user((void *)arg, v->fake_addr, 6)) - return -EFAULT; - return 0; - - /* Set the hardware address of the sheep_net module - arg: pointer to new address (6 bytes) */ - case SIOCSIFADDR: - if (copy_from_user(v->fake_addr, (void*)arg, 6)) - return -EFAULT; - return 0; - - /* Add multicast address - arg: pointer to address (6 bytes) */ - case SIOCADDMULTI: { - char addr[6]; - if (v->ether == NULL) - return -ENODEV; - if (copy_from_user(addr, (void *)arg, 6)) - return -EFAULT; - #ifdef LINUX_26_35 - return dev_mc_add(v->ether, addr); - #else - return dev_mc_add(v->ether, addr, 6, 0); - #endif - } - - /* Remove multicast address - arg: pointer to address (6 bytes) */ - case SIOCDELMULTI: { - char addr[6]; - if (v->ether == NULL) - return -ENODEV; - if (copy_from_user(addr, (void *)arg, 6)) - return -EFAULT; - #ifdef LINUX_26_35 - return dev_mc_del(v->ether, addr); - #else - return dev_mc_delete(v->ether, addr, 6, 0); - #endif - } - - /* Return size of first packet in queue */ - case FIONREAD: { - int count = 0; - struct sk_buff *skb; -#ifdef LINUX_24 - unsigned long flags; - spin_lock_irqsave(&v->queue.lock, flags); -#else - cli(); -#endif - skb = skb_peek(&v->queue); - if (skb) - count = skb->len; -#ifdef LINUX_24 - spin_unlock_irqrestore(&v->queue.lock, flags); -#else - sti(); -#endif - return put_user(count, (int *)arg); - } - - case SIOC_MOL_GET_IPFILTER: - return put_user(v->ipfilter, (int *)arg); - - case SIOC_MOL_SET_IPFILTER: - v->ipfilter = arg; - return 0; - - default: - return -ENOIOCTLCMD; - } -} - - -/* - * Packet receiver function - */ - -#ifdef LINUX_26 -static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *foo) -#else -static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) -#endif -{ - struct SheepVars *v = (struct SheepVars *)pt; - struct sk_buff *skb2; - int fake; - int multicast; - D(bug("sheep_net: packet received\n")); - - multicast = (eth_hdr(skb)->h_dest[0] & ETH_ADDR_MULTICAST); - fake = is_fake_addr(v, ð_hdr(skb)->h_dest); - - /* Packet sent by us? Then discard */ - if (is_fake_addr(v, ð_hdr(skb)->h_source) || skb->protocol == PROT_MAGIC) - goto drop; - - /* If the packet is not meant for this host, discard it */ - if (!is_local_addr(v, ð_hdr(skb)->h_dest) && !multicast && !fake) - goto drop; - - /* Discard packets if queue gets too full */ - if (skb_queue_len(&v->queue) > MAX_QUEUE) - goto drop; - - /* Apply any filters here (if fake is true, then we *know* we want this packet) */ - if (!fake) { - if ((skb->protocol == htons(ETH_P_IP)) - && (!v->ipfilter || (ntohl(ipip_hdr(skb)->daddr) != v->ipfilter && !multicast))) - goto drop; - } - - /* Masquerade (we are typically a clone - best to make a real copy) */ - skb2 = skb_copy(skb, GFP_ATOMIC); - if (!skb2) - goto drop; - kfree_skb(skb); - skb = skb2; - masquerade(v, skb); - - /* We also want the Ethernet header */ - skb_push(skb, skb->data - skb_mac_header(skb)); - - /* Enqueue packet */ - skb_queue_tail(&v->queue, skb); - - /* Unblock blocked read */ -#ifdef LINUX_3_15 - - atomic_set(&v->got_packet, 1); - - wake_up_interruptible(&v->wait); - -#else - - wake_up(&v->wait); - -#endif - return 0; - -drop: - kfree_skb(skb); - return 0; -} - -MODULE_LICENSE("GPL"); diff --git a/BasiliskII/src/Unix/Linux/scsi_linux.cpp b/BasiliskII/src/Unix/Linux/scsi_linux.cpp deleted file mode 100644 index d6365277..00000000 --- a/BasiliskII/src/Unix/Linux/scsi_linux.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* - * scsi_linux.cpp - SCSI Manager, Linux specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include // workaround for broken RedHat 6.0 /usr/include/scsi -#include -#include - -#define DRIVER_SENSE 0x08 - -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "scsi.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static int fds[8]; // fd's for 8 units -static int fd; // Active fd (selected target) - -static uint32 buffer_size; // Size of data buffer -static uint8 *buffer = NULL; // Pointer to data buffer - -static uint8 the_cmd[12]; // Active SCSI command -static int the_cmd_len; - - -/* - * Initialization - */ - -void SCSIInit(void) -{ - int id; - - // Allocate buffer - buffer = (uint8 *)malloc(buffer_size = 0x10000); - - // Open generic SCSI driver for all 8 units - for (id=0; id<8; id++) { - char prefs_name[16]; - sprintf(prefs_name, "scsi%d", id); - const char *str = PrefsFindString(prefs_name); - if (str) { - int fd = fds[id] = open(str, O_RDWR | O_EXCL); - if (fd > 0) { - // Is it really a Generic SCSI device? - int timeout = ioctl(fd, SG_GET_TIMEOUT); - if (timeout < 0) { - // Error with SG_GET_TIMEOUT, doesn't seem to be a Generic SCSI device - char msg[256]; - sprintf(msg, GetString(STR_SCSI_DEVICE_NOT_SCSI_WARN), str); - WarningAlert(msg); - close(fd); - fds[id] = -1; - } else { - // Flush unwanted garbage from previous use of device - uint8 reply[256]; - int old_fl = fcntl(fd, F_GETFL); - fcntl(fd, F_SETFL, old_fl | O_NONBLOCK); - while (read(fd, reply, sizeof(reply)) != -1 || errno != EAGAIN) ; - fcntl(fd, F_SETFL, old_fl); - } - } else { - char msg[256]; - sprintf(msg, GetString(STR_SCSI_DEVICE_OPEN_WARN), str, strerror(errno)); - WarningAlert(msg); - } - } - } - - // Reset SCSI bus - SCSIReset(); -} - - -/* - * Deinitialization - */ - -void SCSIExit(void) -{ - // Close all devices - for (int i=0; i<8; i++) { - int fd = fds[i]; - if (fd > 0) - close(fd); - } - - // Free buffer - if (buffer) { - free(buffer); - buffer = NULL; - } -} - - -/* - * Check if requested data size fits into buffer, allocate new buffer if needed - */ - -static bool try_buffer(uint32 size) -{ - size += sizeof(sg_header) + 12; - if (size <= buffer_size) - return true; - - uint8 *new_buffer = (uint8 *)malloc(size); - if (new_buffer == NULL) - return false; - free(buffer); - buffer = new_buffer; - buffer_size = size; - return true; -} - - -/* - * Set SCSI command to be sent by scsi_send_cmd() - */ - -void scsi_set_cmd(int cmd_length, uint8 *cmd) -{ - memcpy(the_cmd, cmd, the_cmd_len = cmd_length); -} - - -/* - * Check for presence of SCSI target - */ - -bool scsi_is_target_present(int id) -{ - return fds[id] > 0; -} - - -/* - * Set SCSI target (returns false on error) - */ - -bool scsi_set_target(int id, int lun) -{ - int new_fd = fds[id]; - if (new_fd < 0) - return false; - if (new_fd != fd) { - // New target, clear autosense data - sg_header *h = (sg_header *)buffer; - h->driver_status &= ~DRIVER_SENSE; - } - fd = new_fd; - return true; -} - - -/* - * Send SCSI command to active target (scsi_set_command() must have been called), - * read/write data according to S/G table (returns false on error); timeout is in 1/60 sec - */ - -bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr, uint32 *sg_len, uint16 *stat, uint32 timeout) -{ - static int pack_id = 0; - - // Check if buffer is large enough, allocate new buffer if needed - if (!try_buffer(data_length)) { - char str[256]; - sprintf(str, GetString(STR_SCSI_BUFFER_ERR), data_length); - ErrorAlert(str); - return false; - } - - // Process S/G table when writing - if (!reading) { - D(bug(" writing to buffer\n")); - uint8 *buffer_ptr = buffer + sizeof(sg_header) + the_cmd_len; - for (int i=0; itarget_status & DRIVER_SENSE)) { - - // Yes, fake command - D(bug(" autosense\n")); - memcpy(buffer + sizeof(sg_header), h->sense_buffer, 16); - h->target_status &= ~DRIVER_SENSE; - res = 0; - *stat = 0; - - } else { - - // No, send regular command - if (timeout) { - int to = timeout * HZ / 60; - ioctl(fd, SG_SET_TIMEOUT, &to); - } - ioctl(fd, SG_NEXT_CMD_LEN, &the_cmd_len); - - D(bug(" sending command, length %d\n", data_length)); - - int request_size, reply_size; - if (reading) { - h->pack_len = request_size = sizeof(sg_header) + the_cmd_len; - h->reply_len = reply_size = sizeof(sg_header) + data_length; - } else { - h->pack_len = request_size = sizeof(sg_header) + the_cmd_len + data_length; - h->reply_len = reply_size = sizeof(sg_header); - } - h->pack_id = pack_id++; - h->result = 0; - h->twelve_byte = (the_cmd_len == 12); - h->target_status = 0; - h->host_status = 0; - h->driver_status = 0; - h->other_flags = 0; - memcpy(buffer + sizeof(sg_header), the_cmd, the_cmd_len); - - res = write(fd, buffer, request_size); - D(bug(" request sent, actual %d, result %d\n", res, h->result)); - if (res >= 0) { - res = read(fd, buffer, reply_size); - D(bug(" reply read, actual %d, result %d, status %02x\n", res, h->result, h->target_status << 1)); - } - - *stat = h->target_status << 1; - } - - // Process S/G table when reading - if (reading && h->result == 0) { - D(bug(" reading from buffer\n")); - uint8 *buffer_ptr = buffer + sizeof(sg_header); - for (int i=0; i= 0; -} diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index 8ce51385..389e8eed 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -21,7 +21,7 @@ CFLAGS = @CFLAGS@ CXXFLAGS = @CXXFLAGS@ CPUINCLUDES_FLAGS=@CPUINCLUDES@ CPUINCLUDES_FLAGS:=$(CPUINCLUDES_FLAGS:-I%=-I@top_srcdir@/%) -CPPFLAGS = @CPPFLAGS@ -I@top_srcdir@/../include -I@top_srcdir@/. -I. -I@top_srcdir@/../CrossPlatform $(CPUINCLUDES_FLAGS) -I@top_srcdir@/../slirp +CPPFLAGS = @CPPFLAGS@ -I@top_srcdir@/../include -I@top_srcdir@/. -I. -I@top_srcdir@/../CrossPlatform $(CPUINCLUDES_FLAGS) DEFS = @DEFS@ @DEFINES@ -D_REENTRANT -DDATADIR=\"$(datadir)/$(APP)\" LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ @@ -33,16 +33,6 @@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ -SLIRP_CFLAGS = @SLIRP_CFLAGS@ -SLIRP_SRCS = @SLIRP_SRCS@ -SLIRP_OBJS = $(SLIRP_SRCS:../slirp/%.c=obj/%.o) - -STANDALONE_GUI = @STANDALONE_GUI@ -GUI_CFLAGS = @GUI_CFLAGS@ -GUI_LIBS = @GUI_LIBS@ -GUI_SRCS = ../prefs.cpp prefs_unix.cpp prefs_editor_gtk.cpp ../prefs_items.cpp \ - ../user_strings.cpp user_strings_unix.cpp xpram_unix.cpp sys_unix.cpp rpc_unix.cpp - XPLAT_SRCS = ../CrossPlatform/vm_alloc.cpp ../CrossPlatform/sigsegv.cpp ../CrossPlatform/video_blit.cpp ## Files @@ -51,10 +41,9 @@ SRCS = ../main.cpp ../prefs.cpp ../prefs_items.cpp \ ../emul_op.cpp ../macos_util.cpp ../xpram.cpp xpram_unix.cpp ../timer.cpp \ timer_unix.cpp ../adb.cpp ../serial.cpp ../ether.cpp \ ../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp ../video.cpp \ - ../audio.cpp ../extfs.cpp disk_sparsebundle.cpp \ - tinyxml2.cpp \ - ../user_strings.cpp user_strings_unix.cpp sshpty.c strlcpy.c rpc_unix.cpp \ - $(XPLAT_SRCS) $(SYSSRCS) $(CPUSRCS) $(SLIRP_SRCS) + ../audio.cpp ../extfs.cpp \ + ../user_strings.cpp user_strings_unix.cpp rpc_unix.cpp \ + $(XPLAT_SRCS) $(SYSSRCS) $(CPUSRCS) APP_FLAVOR ?= ifneq ($(APP_FLAVOR),) CURR_APP_FLAVOR := -$(APP_FLAVOR) @@ -63,20 +52,11 @@ else endif APP_BASENAME = BasiliskII APP = $(APP_BASENAME)$(CURR_APP_FLAVOR) -APP_APP = $(APP).app PROGS = $(APP)$(EXEEXT) -ifeq ($(STANDALONE_GUI),yes) -GUI_APP = BasiliskIIGUI -GUI_APP_APP = $(GUI_APP).app -PROGS += $(GUI_APP)$(EXEEXT) -else -CXXFLAGS += $(GUI_CFLAGS) -LIBS += $(GUI_LIBS) -endif ## Rules -.PHONY: modules install installdirs uninstall mostlyclean clean distclean depend dep +.PHONY: install installdirs uninstall mostlyclean clean distclean depend dep .SUFFIXES: .SUFFIXES: .c .cpp .s .o .h @@ -93,60 +73,18 @@ endef OBJS := $(SRCS_LIST_TO_OBJS) SRCS := $(SRCS:%=@top_srcdir@/%) -define GUI_SRCS_LIST_TO_OBJS - $(addprefix $(OBJ_DIR)/, $(addsuffix .guio, $(foreach file, $(GUI_SRCS), \ - $(basename $(notdir $(file)))))) -endef -GUI_OBJS = $(GUI_SRCS_LIST_TO_OBJS) -GUI_SRCS := $(GUI_SRCS:%=@top_srcdir@/%) - SRC_PATHS += $(sort $(foreach file, $(SRCS), $(dir $(file)))) VPATH := VPATH += $(addprefix :, $(subst ,:, $(filter-out $($(subst, :, ,$(VPATH))), $(SRC_PATHS)))) ## Documentation files -OSX_DOCS = ../MacOSX/Credits.html ../MacOSX/ToDo.html ../MacOSX/HowTo.html ../MacOSX/Versions.html $(APP)$(EXEEXT): $(OBJ_DIR) $(OBJS) $(CXX) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) $(BLESS) $(APP)$(EXEEXT) -$(GUI_APP)$(EXEEXT): $(OBJ_DIR) $(GUI_OBJS) - $(CXX) -o $@ $(LDFLAGS) $(GUI_OBJS) $(GUI_LIBS) - -$(APP)_app: $(APP) $(OSX_DOCS) ../../README ../MacOSX/Info.plist ../MacOSX/$(APP).icns - rm -rf $(APP_APP)/Contents - mkdir -p $(APP_APP)/Contents - ./cpr.sh ../MacOSX/Info.plist $(APP_APP)/Contents/ - echo -n 'APPL????' > $(APP_APP)/Contents/PkgInfo - mkdir -p $(APP_APP)/Contents/MacOS - ./cpr.sh $(APP) $(APP_APP)/Contents/MacOS/ - strip -x $(APP_APP)/Contents/MacOS/$(APP) - mkdir -p $(APP_APP)/Contents/Resources - ./cpr.sh ../MacOSX/$(APP).icns $(APP_APP)/Contents/Resources/ - ./cpr.sh ../MacOSX/English.lproj $(APP_APP)/Contents/Resources/ - cp -f $(OSX_DOCS) $(APP_APP)/Contents/Resources/ - cp -f ../../README $(APP_APP)/Contents/Resources/README.txt - -$(GUI_APP)_app: $(GUI_APP) ../MacOSX/Info.plist ../MacOSX/$(APP).icns - rm -rf $(GUI_APP_APP)/Contents - mkdir -p $(GUI_APP_APP)/Contents - sed -e "s/$(APP)/$(GUI_APP)/" < ../MacOSX/Info.plist > $(GUI_APP_APP)/Contents/Info.plist - echo -n 'APPL????' > $(GUI_APP_APP)/Contents/PkgInfo - mkdir -p $(GUI_APP_APP)/Contents/MacOS - ./cpr.sh $(GUI_APP) $(GUI_APP_APP)/Contents/MacOS/ - strip -x $(GUI_APP_APP)/Contents/MacOS/$(GUI_APP) - mkdir -p $(GUI_APP_APP)/Contents/Resources - ./cpr.sh ../MacOSX/$(APP).icns $(GUI_APP_APP)/Contents/Resources/$(GUI_APP).icns - -modules: - cd Linux/NetDriver; make - install: $(PROGS) installdirs $(INSTALL_PROGRAM) $(APP)$(EXEEXT) $(DESTDIR)$(bindir)/$(APP)$(EXEEXT) - if test -f "$(GUI_APP)$(EXEEXT)"; then \ - $(INSTALL_PROGRAM) $(GUI_APP)$(EXEEXT) $(DESTDIR)$(bindir)/$(GUI_APP)$(EXEEXT); \ - fi -$(INSTALL_DATA) @top_srcdir@/$(APP_BASENAME).1 $(DESTDIR)$(man1dir)/$(APP).1 $(INSTALL_DATA) @top_srcdir@/$(KEYCODES) $(DESTDIR)$(datadir)/$(APP)/keycodes $(INSTALL_DATA) @top_srcdir@/fbdevices $(DESTDIR)$(datadir)/$(APP)/fbdevices @@ -157,7 +95,6 @@ installdirs: uninstall: rm -f $(DESTDIR)$(bindir)/$(APP)$(EXEEXT) - rm -f $(DESTDIR)$(bindir)/$(GUI_APP)$(EXEEXT) rm -f $(DESTDIR)$(man1dir)/$(APP).1 rm -f $(DESTDIR)$(datadir)/$(APP)/keycodes rm -f $(DESTDIR)$(datadir)/$(APP)/fbdevices @@ -168,7 +105,7 @@ mostlyclean: rm -f $(PROGS) $(OBJ_DIR)/* core* *.core *~ *.bak clean: mostlyclean - rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h + rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h distclean: clean rm -rf $(OBJ_DIR) @@ -180,10 +117,6 @@ distclean: clean depend dep: makedepend $(CPPFLAGS) -Y. $(SRCS) 2>/dev/null -$(OBJ_DIR)/SDLMain.o : SDLMain.m - $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@ -$(OBJ_DIR)/%.o : @top_srcdir@/../slirp/%.c - $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(SLIRP_CFLAGS) -c $< -o $@ $(OBJ_DIR)/%.o : %.c $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@ $(OBJ_DIR)/%.o : %.cpp @@ -194,90 +127,19 @@ $(OBJ_DIR)/%.o : %.mm $(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@ $(OBJ_DIR)/%.o : %.s $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@ -$(OBJ_DIR)/%.guio : %.cpp - $(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) $(GUI_CFLAGS) -DSTANDALONE_GUI -c $< -o $@ - -# Windows resources -$(OBJ_DIR)/%.o: %.rc - windres --include-dir ../Windows -i $< -o $@ $(OBJ_DIR)/build68k$(EXEEXT): $(OBJ_DIR)/build68k.o $(CC) $(LDFLAGS) -o $(OBJ_DIR)/build68k$(EXEEXT) $(OBJ_DIR)/build68k.o $(OBJ_DIR)/gencpu$(EXEEXT): $(OBJ_DIR)/gencpu.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o $(CXX) $(LDFLAGS) -o $(OBJ_DIR)/gencpu$(EXEEXT) $(OBJ_DIR)/gencpu.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o -$(OBJ_DIR)/gencomp$(EXEEXT): $(OBJ_DIR)/gencomp.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o - $(CXX) $(LDFLAGS) -o $(OBJ_DIR)/gencomp$(EXEEXT) $(OBJ_DIR)/gencomp.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o cpudefs.cpp: $(OBJ_DIR)/build68k$(EXEEXT) @top_srcdir@/../uae_cpu/table68k $(OBJ_DIR)/build68k$(EXEEXT) <@top_srcdir@/../uae_cpu/table68k >cpudefs.cpp cpustbl.cpp: cpuemu.cpp -cpustbl_nf.cpp: cpustbl.cpp -compstbl.cpp: compemu.cpp cputbl.h: cpuemu.cpp -comptbl.h: compemu.cpp cpuemu.cpp: $(OBJ_DIR)/gencpu$(EXEEXT) $(OBJ_DIR)/gencpu$(EXEEXT) -compemu.cpp: $(OBJ_DIR)/gencomp$(EXEEXT) - $(OBJ_DIR)/gencomp$(EXEEXT) - -$(OBJ_DIR)/cpustbl_nf.o: cpustbl.cpp - $(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -DNOFLAGS -c $< -o $@ - -$(OBJ_DIR)/compemu_support.o: compemu_support.cpp comptbl.h - $(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@ - -$(OBJ_DIR)/cpuemu1.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_1 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu2.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_2 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu3.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_3 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu4.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_4 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu5.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_5 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu6.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_6 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu7.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_7 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu8.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_8 $(CXXFLAGS) -c $< -o $@ - -$(OBJ_DIR)/cpuemu1_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_1 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu2_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_2 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu3_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_3 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu4_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_4 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu5_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_5 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu6_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_6 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu7_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_7 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu8_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_8 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ - -$(OBJ_DIR)/compemu1.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_1 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu2.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_2 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu3.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_3 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu4.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_4 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu5.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_5 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu6.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_6 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu7.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_7 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu8.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_8 $(CXXFLAGS) -c $< -o $@ - #------------------------------------------------------------------------- # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/BasiliskII/src/Unix/Solaris/audio_solaris.cpp b/BasiliskII/src/Unix/Solaris/audio_solaris.cpp deleted file mode 100644 index d4b7e0df..00000000 --- a/BasiliskII/src/Unix/Solaris/audio_solaris.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/* - * audio_solaris.cpp - Audio support, Solaris implementation - * - * Adapted from Frodo's Solaris sound routines by Marc Chabanas - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include -#include - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "audio.h" -#include "audio_defs.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static int fd = -1; // fd of /dev/audio -static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read -static pthread_t stream_thread; // Audio streaming thread -static pthread_attr_t stream_thread_attr; // Streaming thread attributes -static bool stream_thread_active = false; -static int sound_buffer_size; // Size of sound buffer in bytes - -// Prototypes -static void *stream_func(void *arg); - - -/* - * Initialization - */ - -// Set AudioStatus to reflect current audio stream format -static void set_audio_status_format(void) -{ - AudioStatus.sample_rate = audio_sample_rates[0]; - AudioStatus.sample_size = audio_sample_sizes[0]; - AudioStatus.channels = audio_channel_counts[0]; -} - -void AudioInit(void) -{ - char str[256]; - - // Init audio status and feature flags - audio_sample_rates.push_back(44100 << 16); - audio_sample_sizes.push_back(16); - audio_channel_counts.push_back(2); - set_audio_status_format(); - AudioStatus.mixer = 0; - AudioStatus.num_sources = 0; - audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; - - // Sound disabled in prefs? Then do nothing - if (PrefsFindBool("nosound")) - return; - - // Init semaphore - if (sem_init(&audio_irq_done_sem, 0, 0) < 0) - return; - - // Open /dev/audio - fd = open("/dev/audio", O_WRONLY | O_NDELAY); - if (fd < 0) { - sprintf(str, GetString(STR_NO_AUDIO_DEV_WARN), "/dev/audio", strerror(errno)); - WarningAlert(str); - sem_destroy(&audio_irq_done_sem); - return; - } - - // Set audio parameters - struct audio_info info; - AUDIO_INITINFO(&info); - info.play.sample_rate = AudioStatus.sample_rate >> 16; - info.play.channels = AudioStatus.channels; - info.play.precision = AudioStatus.sample_size; - info.play.encoding = AUDIO_ENCODING_LINEAR; - info.play.port = AUDIO_SPEAKER; - if (ioctl(fd, AUDIO_SETINFO, &info)) { - WarningAlert(GetString(STR_AUDIO_FORMAT_WARN)); - close(fd); - fd = -1; - sem_destroy(&audio_irq_done_sem); - return; - } - - // 2048 frames per buffer - audio_frames_per_block = 2048; - sound_buffer_size = (AudioStatus.sample_size>>3) * AudioStatus.channels * audio_frames_per_block; - - // Start audio thread - Set_pthread_attr(&stream_thread_attr, 0); - stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0); - - // Everything OK - audio_open = true; -} - - -/* - * Deinitialization - */ - -void AudioExit(void) -{ - // Stop audio thread - if (stream_thread_active) { - pthread_cancel(stream_thread); - pthread_join(stream_thread, NULL); - sem_destroy(&audio_irq_done_sem); - stream_thread_active = false; - } - - // Close /dev/audio - if (fd > 0) { - ioctl(fd, AUDIO_DRAIN); - close(fd); - } -} - - -/* - * First source added, start audio stream - */ - -void audio_enter_stream() -{ -} - - -/* - * Last source removed, stop audio stream - */ - -void audio_exit_stream() -{ -} - - -/* - * Streaming function - */ - -static uint32 apple_stream_info; // Mac address of SoundComponentData struct describing next buffer - -static void *stream_func(void *arg) -{ - int16 *silent_buffer = new int16[sound_buffer_size / 2]; - int16 *last_buffer = new int16[sound_buffer_size / 2]; - memset(silent_buffer, 0, sound_buffer_size); - - uint_t sent = 0, delta; - struct audio_info status; - - for (;;) { - if (AudioStatus.num_sources) { - - // Trigger audio interrupt to get new buffer - D(bug("stream: triggering irq\n")); - SetInterruptFlag(INTFLAG_AUDIO); - TriggerInterrupt(); - D(bug("stream: waiting for ack\n")); - sem_wait(&audio_irq_done_sem); - D(bug("stream: ack received\n")); - - // Get size of audio data - uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (apple_stream_info) { - int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels; - D(bug("stream: work_size %d\n", work_size)); - if (work_size > sound_buffer_size) - work_size = sound_buffer_size; - if (work_size == 0) - goto silence; - - // Send data to audio port - if (work_size == sound_buffer_size) - write(fd, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), sound_buffer_size); - else { - // Last buffer - Mac2Host_memcpy(last_buffer, ReadMacInt32(apple_stream_info + scd_buffer), work_size); - memset((uint8 *)last_buffer + work_size, 0, sound_buffer_size - work_size); - write(fd, last_buffer, sound_buffer_size); - } - D(bug("stream: data written\n")); - } else - goto silence; - - } else { - - // Audio not active, play silence -silence: write(fd, silent_buffer, sound_buffer_size); - } - - // We allow a maximum of three buffers to be sent - sent += audio_frames_per_block; - ioctl(fd, AUDIO_GETINFO, &status); - while ((delta = sent - status.play.samples) > (audio_frames_per_block * 3)) { - unsigned int sl = 1000000 * (delta - audio_frames_per_block * 3) / (AudioStatus.sample_rate >> 16); - usleep(sl); - ioctl(fd, AUDIO_GETINFO, &status); - } - } - return NULL; -} - - -/* - * MacOS audio interrupt, read next data block - */ - -void AudioInterrupt(void) -{ - D(bug("AudioInterrupt\n")); - - // Get data from apple mixer - if (AudioStatus.mixer) { - M68kRegisters r; - r.a[0] = audio_data + adatStreamInfo; - r.a[1] = AudioStatus.mixer; - Execute68k(audio_data + adatGetSourceData, &r); - D(bug(" GetSourceData() returns %08lx\n", r.d[0])); - } else - WriteMacInt32(audio_data + adatStreamInfo, 0); - - // Signal stream function - sem_post(&audio_irq_done_sem); - D(bug("AudioInterrupt done\n")); -} - - -/* - * Set sampling parameters - * "index" is an index into the audio_sample_rates[] etc. arrays - * It is guaranteed that AudioStatus.num_sources == 0 - */ - -bool audio_set_sample_rate(int index) -{ - return true; -} - -bool audio_set_sample_size(int index) -{ - return true; -} - -bool audio_set_channels(int index) -{ - return true; -} - - -/* - * Get/set volume controls (volume values received/returned have the left channel - * volume in the upper 16 bits and the right channel volume in the lower 16 bits; - * both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume")) - */ - -bool audio_get_main_mute(void) -{ - return false; -} - -uint32 audio_get_main_volume(void) -{ - return 0x01000100; -} - -bool audio_get_speaker_mute(void) -{ - return false; -} - -uint32 audio_get_speaker_volume(void) -{ - return 0x01000100; -} - -void audio_set_main_mute(bool mute) -{ -} - -void audio_set_main_volume(uint32 vol) -{ -} - -void audio_set_speaker_mute(bool mute) -{ -} - -void audio_set_speaker_volume(uint32 vol) -{ -} diff --git a/BasiliskII/src/Unix/Solaris/which_sparc b/BasiliskII/src/Unix/Solaris/which_sparc deleted file mode 100755 index b6824fd0..00000000 --- a/BasiliskII/src/Unix/Solaris/which_sparc +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/sh - -# which_sparc -# -# This script generates a program that tests for a SPARC processor class -# Program returns: -# 0 unknown SPARC processor -# 8 SPARC V8 `compliant' processor (umul instruction is legal) -# 9 SPARC V9 `compliant' processor (popc instruction is legal) -# -# The script prints: -# "unknown SPARC architecture" -# SPARC_V8 -# SPARC_V9 -# -# I hope this works for other machines and OS. Tested machines are: -# Sun Ultra 10 (Solaris 7), SPARC Station 5 (Solaris 2.5.1) -# -# Gwenole Beauchesne -# gb@dial.oleane.com - -CC=gcc -PROG=./conftest -SOURCE=./conftest.c - -if [ ! -x $PROG ]; then -cat > $SOURCE << EOF -#include -#include - -typedef unsigned int uint32; -typedef uint32 (*sparc_code_func)(void); - -#define SPARC_UNKNOWN 0 -#define SPARC_V8 8 -#define SPARC_V9 9 - -#define MAX_CODE_SIZE 16 -struct sparc_code_struct { - int version; - uint32 code[MAX_CODE_SIZE]; - struct sparc_code_struct * next; -}; -typedef struct sparc_code_struct sparc_code_struct; - -static sparc_code_struct *current_test_code; - -static sparc_code_struct unknown_sparc_code = -{ - SPARC_UNKNOWN, - { - 0x81C3E008, /* retl */ - 0x01000000 /* nop */ - } -}; - -static sparc_code_struct sparc_v9_code = -{ - SPARC_V9, - { - 0x81C3E008, /* retl */ - 0x81702007 /* popc 7, %g0 */ - } -}; - -static sparc_code_struct sparc_v8_code = -{ - SPARC_V8, - { - 0x90102002, /* mov 2, %o0 */ - 0x81C3E008, /* retl */ - 0x90520008 /* umul %o0, %o0, %o0 */ - } -}; - -static void test_sparc_code(int unused_int) -{ - sparc_code_struct *tested_code = current_test_code; - - if (current_test_code == NULL) - exit(SPARC_UNKNOWN); - - signal(SIGILL, test_sparc_code); - current_test_code = current_test_code->next; - (void) ((sparc_code_func)(tested_code->code))(); - exit(tested_code->version); -} - -int main(void) -{ - sparc_v9_code.next = &sparc_v8_code; - sparc_v8_code.next = &unknown_sparc_code; - unknown_sparc_code.next = NULL; - - signal(SIGILL, test_sparc_code); - current_test_code = &sparc_v9_code; - raise(SIGILL); - - return 0; -} -EOF - -$CC -o $PROG $SOURCE -if [ $? -ne 0 ]; then - echo "Error: could not compile the test program" - exit 1 -fi - -fi - -$PROG -case $? in - 0) echo "unknown SPARC architecture";; - 8) echo "SPARC_V8";; - 9) echo "SPARC_V9";; -esac - -rm -f $PROG -rm -f $SOURCE - -exit 0 diff --git a/BasiliskII/src/Unix/asm_support.s b/BasiliskII/src/Unix/asm_support.s deleted file mode 100644 index ba7b0ba1..00000000 --- a/BasiliskII/src/Unix/asm_support.s +++ /dev/null @@ -1,180 +0,0 @@ -/* - * asm_support.s - Utility functions in assembly language (for native 68k support) - * - * Basilisk II (C) 1997-2005 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - .file "asm_support.s" - .text - - .globl _m68k_sync_icache - .globl _Start680x0__Fv - .globl _SetInterruptFlag__FUi - .globl _ClearInterruptFlag__FUi - .globl _Execute68k - .globl _Execute68kTrap - .globl _EmulOpTrampoline - - .globl _RAMBaseHost - .globl _ROMBaseHost - .globl _EmulOp__FUsP13M68kRegisters - .globl _EmulatedSR - .globl _InterruptFlags - .globl _TriggerInterrupt__Fv - - -/* - * Call m68k_sync_icache() (NetBSD, the version in libm68k is broken) - */ - - .type _m68k_sync_icache,@function -_m68k_sync_icache: - movl sp@(8),d1 - movl sp@(4),a1 - movl #0x80000004,d0 - trap #12 - rts - - -/* - * Jump to Mac ROM, start emulation - */ - - .type _Start680x0__Fv,@function -_Start680x0__Fv: - movl _RAMBaseHost,a0 - addl #0x8000,a0 - movl a0,sp - movl _ROMBaseHost,a0 - lea a0@(0x2a),a0 - jmp a0@ - - -/* - * Set/clear interrupt flag (atomically) - */ - - .type _SetInterruptFlag__FUi,@function -_SetInterruptFlag__FUi: - movl sp@(4),d0 - orl d0,_InterruptFlags - rts - - .type _ClearInterruptFlag__FUi,@function -_ClearInterruptFlag__FUi: - movl sp@(4),d0 - notl d0 - andl d0,_InterruptFlags - rts - - -/* - * Execute 68k subroutine (must be ended with rts) - * r->a[7] and r->sr are unused! - */ - -/* void Execute68k(uint32 addr, M68kRegisters *r); */ - .type _Execute68k,@function -_Execute68k: movl sp@(4),d0 |Get arguments - movl sp@(8),a0 - - movml d2-d7/a2-a6,sp@- |Save registers - - movl a0,sp@- |Push pointer to M68kRegisters on stack - pea exec68kret |Push return address on stack - movl d0,sp@- |Push pointer to 68k routine on stack - movml a0@,d0-d7/a0-a6 |Load registers from M68kRegisters - - rts |Jump into 68k routine - -exec68kret: movl a6,sp@- |Save a6 - movl sp@(4),a6 |Get pointer to M68kRegisters - movml d0-d7/a0-a5,a6@ |Save d0-d7/a0-a5 to M68kRegisters - movl sp@+,a6@(56) |Save a6 to M68kRegisters - addql #4,sp |Remove pointer from stack - - movml sp@+,d2-d7/a2-a6 |Restore registers - rts - - -/* - * Execute MacOS 68k trap - * r->a[7] and r->sr are unused! - */ - -/* void Execute68kTrap(uint16 trap, M68kRegisters *r); */ - .type _Execute68kTrap,@function -_Execute68kTrap: - movl sp@(4),d0 |Get arguments - movl sp@(8),a0 - - movml d2-d7/a2-a6,sp@- |Save registers - - movl a0,sp@- |Push pointer to M68kRegisters on stack - movw d0,sp@- |Push trap word on stack - subql #8,sp |Create fake A-Line exception frame - movml a0@,d0-d7/a0-a6 |Load registers from M68kRegisters - - movl a2,sp@- |Save a2 and d2 - movl d2,sp@- - lea exectrapret,a2 |a2 points to return address - movw sp@(16),d2 |Load trap word into d2 - - jmp zpc@(0x28:w)@(10) |Jump into MacOS A-Line handler - -exectrapret: movl a6,sp@- |Save a6 - movl sp@(6),a6 |Get pointer to M68kRegisters - movml d0-d7/a0-a5,a6@ |Save d0-d7/a0-a5 to M68kRegisters - movl sp@+,a6@(56) |Save a6 to M68kRegisters - addql #6,sp |Remove pointer and trap word from stack - - movml sp@+,d2-d7/a2-a6 |Restore registers - rts - - -/* - * Call EmulOp() after return from SIGILL handler, registers are pushed on stack - */ - - .type _EmulOpTrampoline,@function -_EmulOpTrampoline: - movl sp,a0 |Get pointer to registers - - movw _EmulatedSR,d0 |Save EmulatedSR, disable interrupts - movw d0,sp@- - oriw #0x0700,d0 - movw d0,_EmulatedSR - - movl a0,sp@- |Push pointer to registers - movl a0@(66),a1 |Get saved PC - addql #2,a0@(66) |Skip EMUL_OP opcode - movw a1@,sp@- |Push opcode word - clrw sp@- - jbsr _EmulOp__FUsP13M68kRegisters - addql #8,sp - - movw sp@+,d0 |Restore interrupts, trigger pending interrupt - movw d0,_EmulatedSR - andiw #0x0700,d0 - bne eot1 - tstl _InterruptFlags - beq eot1 - jbsr _TriggerInterrupt__Fv - -eot1: moveml sp@+,d0-d7/a0-a6 |Restore registers - addql #4,sp |Skip saved SP - rtr diff --git a/BasiliskII/src/Unix/audio_oss_esd.cpp b/BasiliskII/src/Unix/audio_oss_esd.cpp deleted file mode 100644 index 203a5ac7..00000000 --- a/BasiliskII/src/Unix/audio_oss_esd.cpp +++ /dev/null @@ -1,558 +0,0 @@ -/* - * audio_oss_esd.cpp - Audio support, implementation for OSS and ESD (Linux and FreeBSD) - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include - -#ifdef __linux__ -#include -#endif - -#ifdef __FreeBSD__ -#include -#endif - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "audio.h" -#include "audio_defs.h" - -#ifdef ENABLE_ESD -#include -#endif - -#define DEBUG 0 -#include "debug.h" - - -// The currently selected audio parameters (indices in audio_sample_rates[] etc. vectors) -static int audio_sample_rate_index = 0; -static int audio_sample_size_index = 0; -static int audio_channel_count_index = 0; - -// Global variables -static bool is_dsp_audio = false; // Flag: is DSP audio -static int audio_fd = -1; // fd of dsp or ESD -static int mixer_fd = -1; // fd of mixer -static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read -static bool sem_inited = false; // Flag: audio_irq_done_sem initialized -static int sound_buffer_size; // Size of sound buffer in bytes -static bool little_endian = false; // Flag: DSP accepts only little-endian 16-bit sound data -static uint8 silence_byte; // Byte value to use to fill sound buffers with silence -static pthread_t stream_thread; // Audio streaming thread -static pthread_attr_t stream_thread_attr; // Streaming thread attributes -static bool stream_thread_active = false; // Flag: streaming thread installed -static volatile bool stream_thread_cancel = false; // Flag: cancel streaming thread - -// Prototypes -static void *stream_func(void *arg); - - -/* - * Initialization - */ - -// Set AudioStatus to reflect current audio stream format -static void set_audio_status_format(void) -{ - AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index]; - AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index]; - AudioStatus.channels = audio_channel_counts[audio_channel_count_index]; -} - -// Init using the dsp device, returns false on error -static bool open_dsp(void) -{ - // Open the device - const char *dsp = PrefsFindString("dsp"); - audio_fd = open(dsp, O_WRONLY); - if (audio_fd < 0) { - fprintf(stderr, "WARNING: Cannot open %s (%s)\n", dsp, strerror(errno)); - return false; - } - - printf("Using %s audio output\n", dsp); - is_dsp_audio = true; - - // Get supported sample formats - if (audio_sample_sizes.empty()) { - unsigned long format; - ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &format); - if (format & AFMT_U8) - audio_sample_sizes.push_back(8); - if (format & (AFMT_S16_BE | AFMT_S16_LE)) - audio_sample_sizes.push_back(16); - - int stereo = 0; - if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == 0 && stereo == 0) - audio_channel_counts.push_back(1); - stereo = 1; - if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == 0 && stereo == 1) - audio_channel_counts.push_back(2); - - if (audio_sample_sizes.empty() || audio_channel_counts.empty()) { - WarningAlert(GetString(STR_AUDIO_FORMAT_WARN)); - close(audio_fd); - audio_fd = -1; - return false; - } - - audio_sample_rates.push_back(11025 << 16); - audio_sample_rates.push_back(22050 << 16); - int rate = 44100; - ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate); - if (rate > 22050) - audio_sample_rates.push_back(rate << 16); - - // Default to highest supported values - audio_sample_rate_index = audio_sample_rates.size() - 1; - audio_sample_size_index = audio_sample_sizes.size() - 1; - audio_channel_count_index = audio_channel_counts.size() - 1; - } - - // Set DSP parameters - unsigned long format; - if (audio_sample_sizes[audio_sample_size_index] == 8) { - format = AFMT_U8; - little_endian = false; - silence_byte = 0x80; - } else { - unsigned long sup_format; - ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &sup_format); - if (sup_format & AFMT_S16_BE) { - little_endian = false; - format = AFMT_S16_BE; - } else { - little_endian = true; - format = AFMT_S16_LE; - } - silence_byte = 0; - } - ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format); - int frag = 0x0004000c; // Block size: 4096 frames - ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag); - int stereo = (audio_channel_counts[audio_channel_count_index] == 2); - ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo); - int rate = audio_sample_rates[audio_sample_rate_index] >> 16; - ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate); - - // Get sound buffer size - ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &audio_frames_per_block); - D(bug("DSP_GETBLKSIZE %d\n", audio_frames_per_block)); - return true; -} - -// Init using ESD, returns false on error -static bool open_esd(void) -{ -#ifdef ENABLE_ESD - int rate; - esd_format_t format = ESD_STREAM | ESD_PLAY; - - if (audio_sample_sizes.empty()) { - - // Default values - rate = 44100; - format |= (ESD_BITS16 | ESD_STEREO); - - } else { - - rate = audio_sample_rates[audio_sample_rate_index] >> 16; - if (audio_sample_sizes[audio_sample_size_index] == 8) - format |= ESD_BITS8; - else - format |= ESD_BITS16; - if (audio_channel_counts[audio_channel_count_index] == 1) - format |= ESD_MONO; - else - format |= ESD_STEREO; - } - -#if WORDS_BIGENDIAN - little_endian = false; -#else - little_endian = true; -#endif - silence_byte = 0; // Is this correct for 8-bit mode? - - // Open connection to ESD server - audio_fd = esd_play_stream(format, rate, NULL, NULL); - if (audio_fd < 0) { - fprintf(stderr, "WARNING: Cannot open ESD connection\n"); - return false; - } - - printf("Using ESD audio output\n"); - - // ESD supports a variety of twisted little audio formats, all different - if (audio_sample_sizes.empty()) { - - // The reason we do this here is that we don't want to add sample - // rates etc. unless the ESD server connection could be opened - // (if ESD fails, dsp might be tried next) - audio_sample_rates.push_back(11025 << 16); - audio_sample_rates.push_back(22050 << 16); - audio_sample_rates.push_back(44100 << 16); - audio_sample_sizes.push_back(8); - audio_sample_sizes.push_back(16); - audio_channel_counts.push_back(1); - audio_channel_counts.push_back(2); - - // Default to highest supported values - audio_sample_rate_index = audio_sample_rates.size() - 1; - audio_sample_size_index = audio_sample_sizes.size() - 1; - audio_channel_count_index = audio_channel_counts.size() - 1; - } - - // Sound buffer size = 4096 frames - audio_frames_per_block = 4096; - return true; -#else - // ESD is not enabled, shut up the compiler - return false; -#endif -} - -static bool open_audio(void) -{ -#ifdef ENABLE_ESD - // If ESPEAKER is set, the user probably wants to use ESD, so try that first - if (getenv("ESPEAKER")) - if (open_esd()) - goto dev_opened; -#endif - - // Try to open dsp - if (open_dsp()) - goto dev_opened; - -#ifdef ENABLE_ESD - // Hm, dsp failed so we try ESD again if ESPEAKER wasn't set - if (!getenv("ESPEAKER")) - if (open_esd()) - goto dev_opened; -#endif - - // No audio device succeeded - WarningAlert(GetString(STR_NO_AUDIO_WARN)); - return false; - - // Device opened, set AudioStatus -dev_opened: - sound_buffer_size = (audio_sample_sizes[audio_sample_size_index] >> 3) * audio_channel_counts[audio_channel_count_index] * audio_frames_per_block; - set_audio_status_format(); - - // Start streaming thread - Set_pthread_attr(&stream_thread_attr, 0); - stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0); - - // Everything went fine - audio_open = true; - return true; -} - -void AudioInit(void) -{ - // Init audio status (reasonable defaults) and feature flags - AudioStatus.sample_rate = 44100 << 16; - AudioStatus.sample_size = 16; - AudioStatus.channels = 2; - AudioStatus.mixer = 0; - AudioStatus.num_sources = 0; - audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; - - // Sound disabled in prefs? Then do nothing - if (PrefsFindBool("nosound")) - return; - - // Init semaphore - if (sem_init(&audio_irq_done_sem, 0, 0) < 0) - return; - sem_inited = true; - - // Try to open the mixer device - const char *mixer = PrefsFindString("mixer"); - mixer_fd = open(mixer, O_RDWR); - if (mixer_fd < 0) - printf("WARNING: Cannot open %s (%s)\n", mixer, strerror(errno)); - - // Open and initialize audio device - open_audio(); -} - - -/* - * Deinitialization - */ - -static void close_audio(void) -{ - // Stop stream and delete semaphore - if (stream_thread_active) { - stream_thread_cancel = true; -#ifdef HAVE_PTHREAD_CANCEL - pthread_cancel(stream_thread); -#endif - pthread_join(stream_thread, NULL); - stream_thread_active = false; - } - - // Close dsp or ESD socket - if (audio_fd >= 0) { - close(audio_fd); - audio_fd = -1; - } - - audio_open = false; -} - -void AudioExit(void) -{ - // Stop the device immediately. Otherwise, close() sends - // SNDCTL_DSP_SYNC, which may hang - if (is_dsp_audio) - ioctl(audio_fd, SNDCTL_DSP_RESET, 0); - - // Close audio device - close_audio(); - - // Delete semaphore - if (sem_inited) { - sem_destroy(&audio_irq_done_sem); - sem_inited = false; - } - - // Close mixer device - if (mixer_fd >= 0) { - close(mixer_fd); - mixer_fd = -1; - } -} - - -/* - * First source added, start audio stream - */ - -void audio_enter_stream() -{ - // Streaming thread is always running to avoid clicking noises -} - - -/* - * Last source removed, stop audio stream - */ - -void audio_exit_stream() -{ - // Streaming thread is always running to avoid clicking noises -} - - -/* - * Streaming function - */ - -static void *stream_func(void *arg) -{ - int16 *silent_buffer = new int16[sound_buffer_size / 2]; - int16 *last_buffer = new int16[sound_buffer_size / 2]; - memset(silent_buffer, silence_byte, sound_buffer_size); - - while (!stream_thread_cancel) { - if (AudioStatus.num_sources) { - - // Trigger audio interrupt to get new buffer - D(bug("stream: triggering irq\n")); - SetInterruptFlag(INTFLAG_AUDIO); - TriggerInterrupt(); - D(bug("stream: waiting for ack\n")); - sem_wait(&audio_irq_done_sem); - D(bug("stream: ack received\n")); - - // Get size of audio data - uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (apple_stream_info) { - int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels; - D(bug("stream: work_size %d\n", work_size)); - if (work_size > sound_buffer_size) - work_size = sound_buffer_size; - if (work_size == 0) - goto silence; - - // Send data to DSP - if (work_size == sound_buffer_size && !little_endian) - write(audio_fd, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), sound_buffer_size); - else { - // Last buffer or little-endian DSP - if (little_endian) { - int16 *p = (int16 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)); - for (int i=0; i= 0) { - int vol; - if (ioctl(mixer_fd, SOUND_MIXER_READ_PCM, &vol) == 0) { - int left = vol >> 8; - int right = vol & 0xff; - return ((left * 256 / 100) << 16) | (right * 256 / 100); - } - } - return 0x01000100; -} - -bool audio_get_speaker_mute(void) -{ - return false; -} - -uint32 audio_get_speaker_volume(void) -{ - if (mixer_fd >= 0) { - int vol; - if (ioctl(mixer_fd, SOUND_MIXER_READ_VOLUME, &vol) == 0) { - int left = vol >> 8; - int right = vol & 0xff; - return ((left * 256 / 100) << 16) | (right * 256 / 100); - } - } - return 0x01000100; -} - -void audio_set_main_mute(bool mute) -{ -} - -void audio_set_main_volume(uint32 vol) -{ - if (mixer_fd >= 0) { - int left = vol >> 16; - int right = vol & 0xffff; - int p = ((left * 100 / 256) << 8) | (right * 100 / 256); - ioctl(mixer_fd, SOUND_MIXER_WRITE_PCM, &p); - } -} - -void audio_set_speaker_mute(bool mute) -{ -} - -void audio_set_speaker_volume(uint32 vol) -{ - if (mixer_fd >= 0) { - int left = vol >> 16; - int right = vol & 0xffff; - int p = ((left * 100 / 256) << 8) | (right * 100 / 256); - ioctl(mixer_fd, SOUND_MIXER_WRITE_VOLUME, &p); - } -} diff --git a/BasiliskII/src/Unix/bincue_unix.cpp b/BasiliskII/src/Unix/bincue_unix.cpp deleted file mode 100644 index 11c93548..00000000 --- a/BasiliskII/src/Unix/bincue_unix.cpp +++ /dev/null @@ -1,834 +0,0 @@ -/* - * Copyright (C) 2002-2010 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Geoffrey Brown 2010 - * Includes ideas from dosbox src/dos/cdrom_image.cpp - * - * Limitations: 1) cue files must reference single bin file - * 2) only supports raw mode1 data and audio - * 3) no support for audio flags - * 4) requires SDL audio or OS X core audio - * 5) limited cue file keyword support - * - * Creating cue/bin files: - * cdrdao read-cd --read-raw --paranoia 3 foo.toc - * toc2cue foo.toc - */ - -#include "sysdeps.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef OSX_CORE_AUDIO -#include "../MacOSX/MacOSX_sound_if.h" -static int bincue_core_audio_callback(void); -#endif - -#ifdef USE_SDL_AUDIO -#include -#include -#endif - -#include "bincue_unix.h" -#define DEBUG 0 -#include "debug.h" - -#define MAXTRACK 100 -#define MAXLINE 512 -#define CD_FRAMES 75 -#define RAW_SECTOR_SIZE 2352 -#define COOKED_SECTOR_SIZE 2048 - -// Bits of Track Control Field -- These are standard for scsi cd players - -#define PREMPHASIS 0x1 -#define COPY 0x2 -#define DATA 0x4 -#define AUDIO 0 -#define FOURTRACK 0x8 - -// Audio status -- These are standard for scsi cd players - -#define CDROM_AUDIO_INVALID 0x00 -#define CDROM_AUDIO_PLAY 0x11 -#define CDROM_AUDIO_PAUSED 0x12 -#define CDROM_AUDIO_COMPLETED 0x13 -#define CDROM_AUDIO_ERROR 0x14 -#define CDROM_AUDIO_NO_STATUS 0x15 - -typedef unsigned char uint8; - -// cuefiles can be challenging as some information is -// implied. For example, there may a pregap (also postgap) -// of silence that must be generated. Here we implement -// only the pregap. - -typedef struct { - int number; - unsigned int start; // Track start in frames - unsigned int length; // Track length in frames - loff_t fileoffset; // Track frame start within file - unsigned int pregap; // Silence in frames to generate - unsigned char tcf; // Track control field -} Track; - -typedef struct { - char *binfile; // Binary file name - unsigned int length; // file length in frames - int binfh; // binary file handle - int tcnt; // number of tracks - Track tracks[MAXTRACK]; -} CueSheet; - -typedef struct { - CueSheet *cs; // cue sheet to play from - int audiofh; // file handle for audio data - unsigned int audioposition; // current position from audiostart (bytes) - unsigned int audiostart; // start position if playing (frame) - unsigned int audioend; // end position if playing (frames) - unsigned int silence; // pregap (silence) bytes - unsigned char audiostatus; // See defines above for status - loff_t fileoffset; // offset from file beginning to audiostart -#ifdef OSX_CORE_AUDIO - OSXsoundOutput soundoutput; -#endif -} CDPlayer; - -// Minute,Second,Frame data type - -typedef struct { - int m, s, f; // note size matters since we scan for %d ! -} MSF; - -// Parser State - -static unsigned int totalPregap; -static unsigned int prestart; - -// Audio System State - -static bool audio_enabled = false; -static uint8 silence_byte; - - -// CD Player state. Note only one player is supported ! - -static CDPlayer player; - -static void FramesToMSF(unsigned int frames, MSF *msf) -{ - msf->m = frames/(60 * CD_FRAMES); - frames = frames%(60 * CD_FRAMES); - msf->s = frames/CD_FRAMES; - msf->f = frames%CD_FRAMES; -} - -static int MSFToFrames(MSF msf) -{ - return (msf.m * 60 * CD_FRAMES) + (msf.s * CD_FRAMES) + msf.f; -} - - -static int PositionToTrack(CueSheet *cs, unsigned int position) -{ - int i; - MSF msf; - - FramesToMSF(position, &msf); - - for (i = 0; i < cs->tcnt; i++) { - if ((position >= cs->tracks[i].start) && - (position <= (cs->tracks[i].start + cs->tracks[i].length))) - break; - } - return i; -} - -static bool AddTrack(CueSheet *cs) -{ - int skip = prestart; - Track *prev; - Track *curr = &(cs->tracks[cs->tcnt]); - - prestart = 0; - - if (skip > 0) { - if (skip > curr->start) { - D(bug("AddTrack: prestart > start\n")); - return false; - } - } - - curr->fileoffset = curr->start * RAW_SECTOR_SIZE; - - // now we patch up the indicated time - - curr->start += totalPregap; - - // curr->pregap is supposed to be part of this track, but it - // must be generated as silence - - totalPregap += curr->pregap; - - if (cs->tcnt == 0) { - if (curr->number != 1) { - D(bug("AddTrack: number != 1\n")); - return false; - } - cs->tcnt++; - return true; - } - - prev = &(cs->tracks[cs->tcnt - 1]); - - if (prev->start < skip) - prev->length = skip - prev->start - curr->pregap; - else - prev->length = curr->start - prev->start - curr->pregap; - - // error checks - - if (curr->number <= 1) { - D(bug("Bad track number %d\n", curr->number)); - return false; - } - if ((prev->number + 1 != curr->number) && (curr->number != 0xAA)) { - D(bug("Bad track number %d\n", curr->number)); - return false; - } - if (curr->start < prev->start + prev->length) { - D(bug("unexpected start %d\n", curr->start)); - return false; - } - - cs->tcnt++; - return true; -} - -static bool ParseCueSheet(FILE *fh, CueSheet *cs, const char *cuefile) -{ - bool seen1st = false; - char line[MAXLINE]; - unsigned int i_line=0; - char *keyword; - - totalPregap = 0; - prestart = 0; - - while (fgets(line, MAXLINE, fh) != NULL) { - Track *curr = &cs->tracks[cs->tcnt]; - - // check for CUE file - - if (!i_line && (strncmp("FILE", line, 4) != 0)) { - return false; - } - i_line++; - - // extract keyword - - if (NULL != (keyword = strtok(line, " \t\n\t"))) { - if (!strcmp("FILE", keyword)) { - char *filename; - char *filetype; - - if (i_line > 1) { - D(bug("More than one FILE token\n")); - goto fail; - } - filename = strtok(NULL, "\"\t\n\r"); - filetype = strtok(NULL, " \"\t\n\r"); - if (strcmp("BINARY", filetype)) { - D(bug("Not binary file %s", filetype)); - goto fail; - } - else { - char *tmp = strdup(cuefile); - char *b = dirname(tmp); - cs->binfile = (char *) malloc(strlen(b) + strlen(filename) + 2); - sprintf(cs->binfile, "%s/%s", b, filename); - free(tmp); - } - } else if (!strcmp("TRACK", keyword)) { - char *field; - int i_track; - - if (seen1st) { - if (!AddTrack(cs)){ - D(bug("AddTrack failed \n")); - goto fail; - } - curr = &cs->tracks[cs->tcnt]; - } - - seen1st = true; - - // parse track number - - field = strtok(NULL, " \t\n\r"); - if (1 != sscanf(field, "%d", &i_track)) { - D(bug("Expected track number\n")); - goto fail; - } - curr->number = i_track; - - // parse track type - - field = strtok(NULL, " \t\n\r"); - if (!strcmp("MODE1/2352", field)) { - curr->tcf = DATA; - } else if (!strcmp("AUDIO", field)) { - curr->tcf = AUDIO; - } else { - D(bug("Unexpected track type %s", field)); - goto fail; - } - - } else if (!strcmp("INDEX", keyword)) { - char *field; - int i_index; - MSF msf; - - // parse INDEX number - - field = strtok(NULL, " \t\n\r"); - if (1 != sscanf(field, "%d", &i_index)) { - D(bug("Expected index number")); - goto fail; - } - - // parse INDEX start - - field = strtok(NULL, " \t\n\r"); - if (3 != sscanf(field, "%d:%d:%d", - &msf.m, &msf.s, &msf.f)) { - D(bug("Expected index start frame\n")); - goto fail; - } - - if (i_index == 1) - curr->start = MSFToFrames(msf); - else if (i_index == 0) - prestart = MSFToFrames(msf); - } else if (!strcmp("PREGAP", keyword)) { - MSF msf; - char *field = strtok(NULL, " \t\n\r"); - if (3 != sscanf(field, "%d:%d:%d", - &msf.m, &msf.s, &msf.f)) { - D(bug("Expected pregap frame\n")); - goto fail; - } - curr->pregap = MSFToFrames(msf); - - // Ignored directives - - } else if (!strcmp("TITLE", keyword)) { - } else if (!strcmp("PERFORMER", keyword)) { - } else if (!strcmp("REM", keyword)) { - } else if (!strcmp("ISRC", keyword)) { - } else if (!strcmp("SONGWRITER", keyword)) { - } else { - D(bug("Unexpected keyword %s\n", keyword)); - goto fail; - } - } - } - - AddTrack(cs); // add final track - return true; - fail: - return false; -} - -static bool LoadCueSheet(const char *cuefile, CueSheet *cs) -{ - FILE *fh = NULL; - int binfh = -1; - struct stat buf; - Track *tlast = NULL; - - if (cs) { - bzero(cs, sizeof(*cs)); - if (!(fh = fopen(cuefile, "r"))) - return false; - - if (!ParseCueSheet(fh, cs, cuefile)) goto fail; - - // Open bin file and find length - - if ((binfh = open(cs->binfile,O_RDONLY)) < 0) { - D(bug("Can't read bin file %s\n", cs->binfile)); - goto fail; - } - - if (fstat(binfh, &buf)) { - D(bug("fstat returned error\n")); - goto fail; - } - - // compute length of final track - - - tlast = &cs->tracks[cs->tcnt - 1]; - tlast->length = buf.st_size/RAW_SECTOR_SIZE - - tlast->start + totalPregap; - - if (tlast->length < 0) { - D(bug("Binary file too short \n")); - goto fail; - } - - // save bin file length and pointer - - cs->length = buf.st_size/RAW_SECTOR_SIZE; - cs->binfh = binfh; - - fclose(fh); - return true; - - fail: - if (binfh >= 0) - close(binfh); - fclose(fh); - free(cs->binfile); - return false; - - } - return false; -} - - - -void *open_bincue(const char *name) -{ - CueSheet *cs; - - if (player.cs == NULL) { - cs = (CueSheet *) malloc(sizeof(CueSheet)); - if (!cs) { - D(bug("malloc failed\n")); - return NULL; - } - - if (LoadCueSheet(name, cs)) { - player.cs = cs; -#ifdef OSX_CORE_AUDIO - audio_enabled = true; -#endif - if (audio_enabled) - player.audiostatus = CDROM_AUDIO_NO_STATUS; - else - player.audiostatus = CDROM_AUDIO_INVALID; - player.audiofh = dup(cs->binfh); - return cs; - } - else - free(cs); - } - return NULL; -} - -void close_bincue(void *fh) -{ - - -} - -/* - * File read (cooked) - * Data are stored in raw sectors of which only COOKED_SECTOR_SIZE - * bytes are valid -- the remaining include 16 bytes at the beginning - * of each raw sector and RAW_SECTOR_SIZE - COOKED_SECTOR_SIZE - bytes - * at the end - * - * We assume that a read request can land in the middle of - * sector. We compute the byte address of that sector (sec) - * and the offset of the first byte we want within that sector (secoff) - * - * Reading is performed one raw sector at a time, extracting as many - * valid bytes as possible from that raw sector (available) - */ - -size_t read_bincue(void *fh, void *b, loff_t offset, size_t len) -{ - size_t bytes_read = 0; // bytes read so far - unsigned char *buf = (unsigned char *) b; // target buffer - unsigned char secbuf[RAW_SECTOR_SIZE]; // temporary buffer - - off_t sec = ((offset/COOKED_SECTOR_SIZE) * RAW_SECTOR_SIZE); - off_t secoff = offset % COOKED_SECTOR_SIZE; - - // sec contains location (in bytes) of next raw sector to read - // secoff contains offset within that sector at which to start - // reading since we can request a read that starts in the middle - // of a sector - - CueSheet *cs = (CueSheet *) fh; - - if (cs == NULL || lseek(cs->binfh, sec, SEEK_SET) < 0) { - return -1; - } - while (len) { - - // bytes available in next raw sector or len (bytes) - // we want whichever is less - - size_t available = COOKED_SECTOR_SIZE - secoff; - available = (available > len) ? len : available; - - // read the next raw sector - - if (read(cs->binfh, secbuf, RAW_SECTOR_SIZE) != RAW_SECTOR_SIZE) { - return bytes_read; - } - - // copy cooked sector bytes (skip first 16) - // we want out of those available - - bcopy(&secbuf[16+secoff], &buf[bytes_read], available); - - // next sector we start at the beginning - - secoff = 0; - - // increment running count decrement request - - bytes_read += available; - len -= available; - } - return bytes_read; -} - -loff_t size_bincue(void *fh) -{ - if (fh) { - return ((CueSheet *)fh)->length * COOKED_SECTOR_SIZE; - } -} - -bool readtoc_bincue(void *fh, unsigned char *toc) -{ - CueSheet *cs = (CueSheet *) fh; - if (cs) { - - MSF msf; - unsigned char *p = toc + 2; - *p++ = cs->tracks[0].number; - *p++ = cs->tracks[cs->tcnt - 1].number; - for (int i = 0; i < cs->tcnt; i++) { - - FramesToMSF(cs->tracks[i].start, &msf); - *p++ = 0; - *p++ = 0x10 | cs->tracks[i].tcf; - *p++ = cs->tracks[i].number; - *p++ = 0; - *p++ = 0; - *p++ = msf.m; - *p++ = msf.s; - *p++ = msf.f; - } - FramesToMSF(cs->length, &msf); - *p++ = 0; - *p++ = 0x14; - *p++ = 0xAA; - *p++ = 0; - *p++ = 0; - *p++ = msf.m; - *p++ = msf.s; - *p++ = msf.f; - - int toc_size = p - toc; - *toc++ = toc_size >> 8; - *toc++ = toc_size & 0xff; - return true; - } -} - -bool GetPosition_bincue(void *fh, uint8 *pos) -{ - CueSheet *cs = (CueSheet *) fh; - if (cs && player.cs == cs) { - MSF abs, rel; - int fpos = player.audioposition / RAW_SECTOR_SIZE + player.audiostart; - int trackno = PositionToTrack(cs, fpos); - - if (!audio_enabled) - return false; - - FramesToMSF(fpos, &abs); - if (trackno < cs->tcnt) { - // compute position relative to start of frame - - unsigned int position = player.audioposition/RAW_SECTOR_SIZE + - player.audiostart - player.cs->tracks[trackno].start; - - FramesToMSF(position, &rel); - } - else - FramesToMSF(0, &rel); - - *pos++ = 0; - *pos++ = player.audiostatus; - *pos++ = 0; - *pos++ = 12; // Sub-Q data length - *pos++ = 0; - if (trackno < cs->tcnt) - *pos++ = 0x10 | cs->tracks[trackno].tcf; - *pos++ = (trackno < cs->tcnt) ? cs->tracks[trackno].number : 0xAA; - *pos++ = 1; // track index - *pos++ = 0; - *pos++ = abs.m; - *pos++ = abs.s; - *pos++ = abs.f; - *pos++ = 0; - *pos++ = rel.m; - *pos++ = rel.s; - *pos++ = rel.f; - *pos++ = 0; -// D(bug("CDROM position %02d:%02d:%02d track %02d\n", abs.m, abs.s, abs.f, trackno)); - return true; - } - else - return false; -} - -bool CDPause_bincue(void *fh) -{ - CueSheet *cs = (CueSheet *) fh; - if (cs && cs == player.cs) { - if (player.audiostatus == CDROM_AUDIO_PLAY) { - player.audiostatus = CDROM_AUDIO_PAUSED; - return true; - } - } - return false; -} - -bool CDStop_bincue(void *fh) -{ - CueSheet *cs = (CueSheet *) fh; - - if (cs && cs == player.cs) { -#ifdef OSX_CORE_AUDIO - player.soundoutput.stop(); -#endif - if (player.audiostatus != CDROM_AUDIO_INVALID) - player.audiostatus = CDROM_AUDIO_NO_STATUS; - return true; - } - return false; -} - -bool CDResume_bincue(void *fh) -{ - CueSheet *cs = (CueSheet *) fh; - if (cs && cs == player.cs) { - if (player.audiostatus == CDROM_AUDIO_PAUSED) { - player.audiostatus = CDROM_AUDIO_PLAY; - return true; - } - } - return false; -} - -bool CDPlay_bincue(void *fh, uint8 start_m, uint8 start_s, uint8 start_f, - uint8 end_m, uint8 end_s, uint8 end_f) -{ - CueSheet *cs = (CueSheet *)fh; - if (cs && cs == player.cs) { - int track; - MSF msf; - -#ifdef USE_SDL_AUDIO - SDL_LockAudio(); -#endif - - player.audiostatus = CDROM_AUDIO_NO_STATUS; - - player.audiostart = (start_m * 60 * CD_FRAMES) + - (start_s * CD_FRAMES) + start_f; - player.audioend = (end_m * 60 * CD_FRAMES) + (end_s * CD_FRAMES) + end_f; - - track = PositionToTrack(player.cs, player.audiostart); - - if (track < player.cs->tcnt) { - player.audioposition = 0; - - // here we need to compute silence - - if (player.audiostart - player.cs->tracks[track].start > - player.cs->tracks[track].pregap) - player.silence = 0; - else - player.silence = (player.cs->tracks[track].pregap - - player.audiostart + - player.cs->tracks[track].start) * RAW_SECTOR_SIZE; - - player.fileoffset = player.cs->tracks[track].fileoffset; - - D(bug("file offset %d\n", (unsigned int) player.fileoffset)); - - // fix up file offset if beyond the silence bytes - - if (!player.silence) // not at the beginning - player.fileoffset += (player.audiostart - - player.cs->tracks[track].start - - player.cs->tracks[track].pregap) * RAW_SECTOR_SIZE; - - FramesToMSF(player.cs->tracks[track].start, &msf); - D(bug("CDPlay_bincue track %02d start %02d:%02d:%02d silence %d", - player.cs->tracks[track].number, msf.m, msf.s, msf.f, - player.silence/RAW_SECTOR_SIZE)); - D(bug(" Stop %02u:%02u:%02u\n", end_m, end_s, end_f)); - } - else - D(bug("CDPlay_bincue: play beyond last track !\n")); - -#ifdef USE_SDL_AUDIO - SDL_UnlockAudio(); -#endif - - if (audio_enabled) { - player.audiostatus = CDROM_AUDIO_PLAY; -#ifdef OSX_CORE_AUDIO - D(bug("starting os x sound")); - player.soundoutput.setCallback(bincue_core_audio_callback); - // should be from current track ! - player.soundoutput.start(16, 2, 44100); -#endif - return true; - } - } - return false; -} - -static uint8 *fill_buffer(int stream_len) -{ - static uint8 *buf = 0; - static int bufsize = 0; - int offset = 0; - - if (bufsize < stream_len) { - free(buf); - buf = (uint8 *) malloc(stream_len); - if (buf) { - bufsize = stream_len; - } - else { - D(bug("malloc failed \n")); - return NULL; - } - } - - memset(buf, silence_byte, stream_len); - - if (player.audiostatus == CDROM_AUDIO_PLAY) { - int remaining_silence = player.silence - player.audioposition; - - if (player.audiostart + player.audioposition/RAW_SECTOR_SIZE - >= player.audioend) { - player.audiostatus = CDROM_AUDIO_COMPLETED; - return buf; - } - - if (remaining_silence >= stream_len) { - player.audioposition += stream_len; - return buf; - } - - if (remaining_silence > 0) { - offset += remaining_silence; - player.audioposition += remaining_silence; - } - - int ret = 0; - int available = ((player.audioend - player.audiostart) * - RAW_SECTOR_SIZE) - player.audioposition; - if (available > (stream_len - offset)) - available = stream_len - offset; - - if (lseek(player.audiofh, - player.fileoffset + player.audioposition - player.silence, - SEEK_SET) < 0) - return NULL; - - if (available < 0) { - player.audioposition += available; // correct end !; - available = 0; - } - - if ((ret = read(player.audiofh, &buf[offset], available)) >= 0) { - player.audioposition += ret; - offset += ret; - available -= ret; - } - - while (offset < stream_len) { - buf[offset++] = silence_byte; - if (available-- > 0){ - player.audioposition++; - } - } - } - return buf; -} - - -#ifdef USE_SDL_AUDIO -void MixAudio_bincue(uint8 *stream, int stream_len) -{ - uint8 *buf; - if (audio_enabled && (player.audiostatus == CDROM_AUDIO_PLAY)) { - if (buf = fill_buffer(stream_len)) - SDL_MixAudio(stream, buf, stream_len, SDL_MIX_MAXVOLUME); - } -} - -void OpenAudio_bincue(int freq, int format, int channels, uint8 silence) -{ - if (freq == 44100 && format == AUDIO_S16MSB && channels == 2) { - audio_enabled = true; - silence_byte = silence; - } - else { - D(bug("unexpected frequency %d , format %d, or channels %d\n", - freq, format, channels)); - } -} -#endif - -#ifdef OSX_CORE_AUDIO -static int bincue_core_audio_callback(void) -{ - int frames = player.soundoutput.bufferSizeFrames(); - uint8 *buf = fill_buffer(frames*4); - - // D(bug("Audio request %d\n", stream_len)); - - player.soundoutput.sendAudioBuffer((void *) buf, (buf ? frames : 0)); - - return 1; -} -#endif diff --git a/BasiliskII/src/Unix/bincue_unix.h b/BasiliskII/src/Unix/bincue_unix.h deleted file mode 100644 index dbf5d8b5..00000000 --- a/BasiliskII/src/Unix/bincue_unix.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * bincue_unix.h -- support for cdrom image files in bin/cue format - * - * (C) 2010 Geoffrey Brown - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef BINCUE_H -#define BINCUE_H - -extern void *open_bincue(const char *name); -extern bool readtoc_bincue(void *, uint8 *); -extern size_t read_bincue(void *, void *, loff_t, size_t); -extern loff_t size_bincue(void *); -extern void close_bincue(void *); - -extern bool GetPosition_bincue(void *, uint8 *); - -extern bool CDPlay_bincue(void *, uint8, uint8, - uint8, uint8, uint8, uint8); -extern bool CDPause_bincue(void *); -extern bool CDResume_bincue(void *); -extern bool CDStop_bincue(void *); - -#ifdef USE_SDL_AUDIO -extern void OpenAudio_bincue(int, int, int, uint8); -extern void MixAudio_bincue(uint8 *, int); -#endif - -#endif diff --git a/BasiliskII/src/Unix/clip_unix.cpp b/BasiliskII/src/Unix/clip_unix.cpp deleted file mode 100644 index e2a5edfb..00000000 --- a/BasiliskII/src/Unix/clip_unix.cpp +++ /dev/null @@ -1,691 +0,0 @@ -/* - * clip_unix.cpp - Clipboard handling, Unix implementation - * - * SheepShaver (C) Christian Bauer and Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * NOTES: - * - * We must have (fast) X11 display locking routines. Otherwise, we - * can corrupt the X11 event queue from the emulator thread whereas - * the redraw thread is expected to handle them. - * - * Two functions are exported to video_x.cpp: - * - ClipboardSelectionClear() - * called when we lose the selection ownership - * - ClipboardSelectionRequest() - * called when another client wants our clipboard data - * The display is locked by the redraw thread during their execution. - * - * On PutScrap (Mac application wrote to clipboard), we always cache - * the Mac clipboard to a local structure (clip_data). Then, the - * selection ownership is grabbed until ClipboardSelectionClear() - * occurs. In that case, contents in cache becomes invalid. - * - * On GetScrap (Mac application reads clipboard), we always fetch - * data from the X11 clipboard and immediately put it back to Mac - * side. Local cache does not need to be updated. If the selection - * owner supports the TIMESTAMP target, we can avoid useless copies. - * - * For safety purposes, we lock the X11 display in the emulator - * thread during the whole GetScrap/PutScrap execution. Of course, we - * temporarily release the lock when waiting for SelectioNotify. - * - * TODO: - * - handle 'PICT' to image/png, image/ppm, PIXMAP (prefs order) - * - handle 'styl' to text/richtext (OOo Writer) - * - patch ZeroScrap so that we know when cached 'styl' is stale? - */ - -#include "sysdeps.h" - -#include -#include -#include -#include - -#include "macos_util.h" -#include "clip.h" -#include "prefs.h" -#include "cpu_emulation.h" -#include "main.h" -#include "emul_op.h" - -#define DEBUG 0 -#include "debug.h" - -#ifndef NO_STD_NAMESPACE -using std::vector; -#endif - - -// Do we want GetScrap() to check for TIMESTAMP and optimize out clipboard syncs? -#define GETSCRAP_REQUESTS_TIMESTAMP 0 - -// Do we want GetScrap() to first check for TARGETS available from the clipboard? -#define GETSCRAP_REQUESTS_TARGETS 0 - - -// From main_linux.cpp -extern Display *x_display; - - -// Conversion tables -static const uint8 mac2iso[0x80] = { - 0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1, - 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8, - 0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3, - 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc, - 0x2b, 0xb0, 0xa2, 0xa3, 0xa7, 0xb7, 0xb6, 0xdf, - 0xae, 0xa9, 0x20, 0xb4, 0xa8, 0x23, 0xc6, 0xd8, - 0x20, 0xb1, 0x3c, 0x3e, 0xa5, 0xb5, 0xf0, 0x53, - 0x50, 0x70, 0x2f, 0xaa, 0xba, 0x4f, 0xe6, 0xf8, - 0xbf, 0xa1, 0xac, 0x2f, 0x66, 0x7e, 0x44, 0xab, - 0xbb, 0x2e, 0x20, 0xc0, 0xc3, 0xd5, 0x4f, 0x6f, - 0x2d, 0x2d, 0x22, 0x22, 0x60, 0x27, 0xf7, 0x20, - 0xff, 0x59, 0x2f, 0xa4, 0x3c, 0x3e, 0x66, 0x66, - 0x23, 0xb7, 0x2c, 0x22, 0x25, 0xc2, 0xca, 0xc1, - 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4, - 0x20, 0xd2, 0xda, 0xdb, 0xd9, 0x69, 0x5e, 0x7e, - 0xaf, 0x20, 0xb7, 0xb0, 0xb8, 0x22, 0xb8, 0x20 -}; - -static const uint8 iso2mac[0x80] = { - 0xad, 0xb0, 0xe2, 0xc4, 0xe3, 0xc9, 0xa0, 0xe0, - 0xf6, 0xe4, 0xde, 0xdc, 0xce, 0xb2, 0xb3, 0xb6, - 0xb7, 0xd4, 0xd5, 0xd2, 0xd3, 0xa5, 0xd0, 0xd1, - 0xf7, 0xaa, 0xdf, 0xdd, 0xcf, 0xba, 0xfd, 0xd9, - 0xca, 0xc1, 0xa2, 0xa3, 0xdb, 0xb4, 0xbd, 0xa4, - 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0xf0, 0xa8, 0xf8, - 0xa1, 0xb1, 0xc3, 0xc5, 0xab, 0xb5, 0xa6, 0xe1, - 0xfc, 0xc6, 0xbc, 0xc8, 0xf9, 0xda, 0xd7, 0xc0, - 0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, - 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, - 0xf5, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0xfb, - 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0xfa, 0xb8, 0xa7, - 0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, - 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, - 0xfe, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, - 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0xff, 0xb9, 0xd8 -}; - -// Flag: Don't convert clipboard text -static bool no_clip_conversion; - -// Flag for PutScrap(): the data was put by GetScrap(), don't bounce it back to the Unix side -static bool we_put_this_data = false; - -// X11 variables -static int screen; // Screen number -static Window rootwin, clip_win; // Root window and the clipboard window -static Atom xa_clipboard; -static Atom xa_targets; -static Atom xa_multiple; -static Atom xa_timestamp; -static Atom xa_atom_pair; - -// Define a byte array (rewrite if it's a bottleneck) -struct ByteArray : public vector { - void resize(int size) { reserve(size); vector::resize(size); } - uint8 *data() { return &(*this)[0]; } -}; - -// Clipboard data for requestors -struct ClipboardData { - Time time; - Atom type; - ByteArray data; -}; -static ClipboardData clip_data; - -// Prototypes -static void do_putscrap(uint32 type, void *scrap, int32 length); -static void do_getscrap(void **handle, uint32 type, int32 offset); - - -/* - * Read an X11 property (hack from QT 3.1.2) - */ - -static inline int max_selection_incr(Display *dpy) -{ - int max_request_size = 4 * XMaxRequestSize(dpy); - if (max_request_size > 4 * 65536) - max_request_size = 4 * 65536; - else if ((max_request_size -= 100) < 0) - max_request_size = 100; - return max_request_size; -} - -static bool read_property(Display *dpy, Window win, - Atom property, bool deleteProperty, - ByteArray & buffer, int *size, Atom *type, - int *format, bool nullterm) -{ - int maxsize = max_selection_incr(dpy); - unsigned long bytes_left; - unsigned long length; - unsigned char *data; - Atom dummy_type; - int dummy_format; - - if (!type) - type = &dummy_type; - if (!format) - format = &dummy_format; - - // Don't read anything but get the size of the property data - if (XGetWindowProperty(dpy, win, property, 0, 0, False, - AnyPropertyType, type, format, &length, &bytes_left, &data) != Success) { - buffer.clear(); - return false; - } - XFree(data); - - int offset = 0, buffer_offset = 0, format_inc = 1, proplen = bytes_left; - - switch (*format) { - case 16: - format_inc = sizeof(short) / 2; - proplen *= format_inc; - break; - case 32: - format_inc = sizeof(long) / 4; - proplen *= format_inc; - break; - } - - buffer.resize(proplen + (nullterm ? 1 : 0)); - while (bytes_left) { - if (XGetWindowProperty(dpy, win, property, offset, maxsize / 4, - False, AnyPropertyType, type, format, - &length, &bytes_left, &data) != Success) - break; - - offset += length / (32 / *format); - length *= format_inc * (*format / 8); - - memcpy(buffer.data() + buffer_offset, data, length); - buffer_offset += length; - XFree(data); - } - - if (nullterm) - buffer[buffer_offset] = '\0'; - - if (size) - *size = buffer_offset; - - if (deleteProperty) - XDeleteProperty(dpy, win, property); - - XFlush(dpy); - return true; -} - - -/* - * Timed wait for a SelectionNotify event - */ - -static const uint64 SELECTION_MAX_WAIT = 500000; // 500 ms - -static bool wait_for_selection_notify_event(Display *dpy, Window win, XEvent *event, int timeout) -{ - uint64 start = GetTicks_usec(); - - do { - // Wait - XDisplayUnlock(); - Delay_usec(5000); - XDisplayLock(); - - // Check for SelectionNotify event - if (XCheckTypedWindowEvent(dpy, win, SelectionNotify, event)) - return true; - - } while ((GetTicks_usec() - start) < timeout); - - return false; -} - - -/* - * Initialization - */ - -void ClipInit(void) -{ - no_clip_conversion = PrefsFindBool("noclipconversion"); - - // Find screen and root window - screen = XDefaultScreen(x_display); - rootwin = XRootWindow(x_display, screen); - - // Create fake window to receive selection events - clip_win = XCreateSimpleWindow(x_display, rootwin, 0, 0, 1, 1, 0, 0, 0); - - // Initialize X11 atoms - xa_clipboard = XInternAtom(x_display, "CLIPBOARD", False); - xa_targets = XInternAtom(x_display, "TARGETS", False); - xa_multiple = XInternAtom(x_display, "MULTIPLE", False); - xa_timestamp = XInternAtom(x_display, "TIMESTAMP", False); - xa_atom_pair = XInternAtom(x_display, "ATOM_PAIR", False); -} - - -/* - * Deinitialization - */ - -void ClipExit(void) -{ - // Close window - if (clip_win) - XDestroyWindow(x_display, clip_win); -} - - -/* - * Mac application wrote to clipboard - */ - -void PutScrap(uint32 type, void *scrap, int32 length) -{ - D(bug("PutScrap type %08lx, data %p, length %ld\n", type, scrap, length)); - if (we_put_this_data) { - we_put_this_data = false; - return; - } - if (length <= 0) - return; - - XDisplayLock(); - do_putscrap(type, scrap, length); - XDisplayUnlock(); -} - -static void do_putscrap(uint32 type, void *scrap, int32 length) -{ - clip_data.type = None; - switch (type) { - case FOURCC('T','E','X','T'): { - D(bug(" clipping TEXT\n")); - clip_data.type = XA_STRING; - clip_data.data.clear(); - clip_data.data.reserve(length); - - // Convert text from Mac charset to ISO-Latin1 - uint8 *p = (uint8 *)scrap; - for (int i=0; i LF - c = 10; - } else if (!no_clip_conversion) - c = mac2iso[c & 0x7f]; - clip_data.data.push_back(c); - } - break; - } - - case FOURCC('s','t','y','l'): { - D(bug(" clipping styl\n")); - uint16 *p = (uint16 *)scrap; - uint16 n = ntohs(*p++); - D(bug(" %d styles (%d bytes)\n", n, length)); - for (int i = 0; i < n; i++) { - uint32 offset = ntohl(*(uint32 *)p); p += 2; - uint16 line_height = ntohs(*p++); - uint16 font_ascent = ntohs(*p++); - uint16 font_family = ntohs(*p++); - uint16 style_code = ntohs(*p++); - uint16 char_size = ntohs(*p++); - uint16 r = ntohs(*p++); - uint16 g = ntohs(*p++); - uint16 b = ntohs(*p++); - D(bug(" offset=%d, height=%d, font ascent=%d, id=%d, style=%x, size=%d, RGB=%x/%x/%x\n", - offset, line_height, font_ascent, font_family, style_code, char_size, r, g, b)); - } - break; - } - } - - // Acquire selection ownership - if (clip_data.type != None) { - clip_data.time = CurrentTime; - while (XGetSelectionOwner(x_display, xa_clipboard) != clip_win) - XSetSelectionOwner(x_display, xa_clipboard, clip_win, clip_data.time); - } -} - -/* - * Mac application zeroes clipboard - */ - -void ZeroScrap() -{ - -} - -/* - * Mac application reads clipboard - */ - -void GetScrap(void **handle, uint32 type, int32 offset) -{ - D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset)); - - XDisplayLock(); - do_getscrap(handle, type, offset); - XDisplayUnlock(); -} - -static void do_getscrap(void **handle, uint32 type, int32 offset) -{ - ByteArray data; - XEvent event; - - // If we own the selection, the data is already available on MacOS side - if (XGetSelectionOwner(x_display, xa_clipboard) == clip_win) - return; - - // Check TIMESTAMP -#if GETSCRAP_REQUESTS_TIMESTAMP - static Time last_timestamp = 0; - XConvertSelection(x_display, xa_clipboard, xa_timestamp, xa_clipboard, clip_win, CurrentTime); - if (wait_for_selection_notify_event(x_display, clip_win, &event, SELECTION_MAX_WAIT) && - event.xselection.property != None && - read_property(x_display, - event.xselection.requestor, event.xselection.property, - true, data, 0, 0, 0, false)) { - Time timestamp = ((long *)data.data())[0]; - if (timestamp <= last_timestamp) - return; - } - last_timestamp = CurrentTime; -#endif - - // Get TARGETS available -#if GETSCRAP_REQUESTS_TARGETS - XConvertSelection(x_display, xa_clipboard, xa_targets, xa_clipboard, clip_win, CurrentTime); - if (!wait_for_selection_notify_event(x_display, clip_win, &event, SELECTION_MAX_WAIT) || - event.xselection.property == None || - !read_property(x_display, - event.xselection.requestor, event.xselection.property, - true, data, 0, 0, 0, false)) - return; -#endif - - // Get appropriate format for requested data - Atom format = None; -#if GETSCRAP_REQUESTS_TARGETS - int n_atoms = data.size() / sizeof(long); - long *atoms = (long *)data.data(); - for (int i = 0; i < n_atoms; i++) { - Atom target = atoms[i]; - D(bug(" target %08x (%s)\n", target, XGetAtomName(x_display, target))); - switch (type) { - case FOURCC('T','E','X','T'): - D(bug(" clipping TEXT\n")); - if (target == XA_STRING) - format = target; - break; - case FOURCC('P','I','C','T'): - break; - } - } -#else - switch (type) { - case FOURCC('T','E','X','T'): - D(bug(" clipping TEXT\n")); - format = XA_STRING; - break; - case FOURCC('P','I','C','T'): - break; - } -#endif - if (format == None) - return; - - // Get the native clipboard data - XConvertSelection(x_display, xa_clipboard, format, xa_clipboard, clip_win, CurrentTime); - if (!wait_for_selection_notify_event(x_display, clip_win, &event, SELECTION_MAX_WAIT) || - event.xselection.property == None || - !read_property(x_display, - event.xselection.requestor, event.xselection.property, - false, data, 0, 0, 0, format == XA_STRING)) - return; - - // Allocate space for new scrap in MacOS side - M68kRegisters r; - r.d[0] = data.size(); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32 scrap_area = r.a[0]; - - if (scrap_area) { - switch (type) { - case FOURCC('T','E','X','T'): - // Convert text from ISO-Latin1 to Mac charset - uint8 *p = Mac2HostAddr(scrap_area); - for (int i = 0; i < data.size(); i++) { - uint8 c = data[i]; - if (c < 0x80) { - if (c == 10) // LF -> CR - c = 13; - } else if (!no_clip_conversion) - c = iso2mac[c & 0x7f]; - *p++ = c; - } - break; - } - - // Add new data to clipboard - static uint8 proc[] = { - 0x59, 0x8f, // subq.l #4,sp - 0xa9, 0xfc, // ZeroScrap() - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #length,-(sp) - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #type,-(sp) - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #outbuf,-(sp) - 0xa9, 0xfe, // PutScrap() - 0x58, 0x8f, // addq.l #4,sp - M68K_RTS >> 8, M68K_RTS & 0xff - }; - r.d[0] = sizeof(proc); - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32 proc_area = r.a[0]; - - // The procedure is run-time generated because it must lays in - // Mac address space. This is mandatory for "33-bit" address - // space optimization on 64-bit platforms because the static - // proc[] array is not remapped - Host2Mac_memcpy(proc_area, proc, sizeof(proc)); - WriteMacInt32(proc_area + 6, data.size()); - WriteMacInt32(proc_area + 12, type); - WriteMacInt32(proc_area + 18, scrap_area); - we_put_this_data = true; - Execute68k(proc_area, &r); - - // We are done with scratch memory - r.a[0] = proc_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - r.a[0] = scrap_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - } -} - - -/* - * Handle X11 selection events - */ - -void ClipboardSelectionClear(XSelectionClearEvent *xev) -{ - if (xev->selection != xa_clipboard) - return; - - D(bug("Selection cleared, lost clipboard ownership\n")); - clip_data.type = None; - clip_data.data.clear(); -} - -// Top level selection handler -static bool handle_selection(XSelectionRequestEvent *req, bool is_multiple); - -static bool handle_selection_TIMESTAMP(XSelectionRequestEvent *req) -{ - // 32-bit integer values are always passed as a long whatever is its size - long timestamp = clip_data.time; - - // Change requestor property - XChangeProperty(x_display, req->requestor, req->property, - XA_INTEGER, 32, - PropModeReplace, (uint8 *)×tamp, 1); - - return true; -} - -static bool handle_selection_TARGETS(XSelectionRequestEvent *req) -{ - // Default supported targets - vector targets; - targets.push_back(xa_targets); - targets.push_back(xa_multiple); - targets.push_back(xa_timestamp); - - // Extra targets matchin current clipboard data - if (clip_data.type != None) - targets.push_back(clip_data.type); - - // Change requestor property - XChangeProperty(x_display, req->requestor, req->property, - xa_targets, 32, - PropModeReplace, (uint8 *)&targets[0], targets.size()); - - return true; -} - -static bool handle_selection_STRING(XSelectionRequestEvent *req) -{ - // Make sure we have valid data to send though ICCCM compliant - // clients should have first requested TARGETS to identify - // this possibility. - if (clip_data.type != XA_STRING) - return false; - - // Send the string, it's already encoded as ISO-8859-1 - XChangeProperty(x_display, req->requestor, req->property, - XA_STRING, 8, - PropModeReplace, (uint8 *)clip_data.data.data(), clip_data.data.size()); - - return true; -} - -static bool handle_selection_MULTIPLE(XSelectionRequestEvent *req) -{ - Atom rtype; - int rformat; - ByteArray data; - - if (!read_property(x_display, req->requestor, req->property, - false, data, 0, &rtype, &rformat, 0)) - return false; - - // rtype should be ATOM_PAIR but some clients don't honour that - if (rformat != 32) - return false; - - struct AtomPair { long target; long property; }; - AtomPair *atom_pairs = (AtomPair *)data.data(); - int n_atom_pairs = data.size() / sizeof(AtomPair); - - bool handled = true; - if (n_atom_pairs) { - // Setup a new XSelectionRequestEvent when servicing individual requests - XSelectionRequestEvent event; - memcpy(&event, req, sizeof(event)); - - for (int i = 0; i < n_atom_pairs; i++) { - Atom target = atom_pairs[i].target; - Atom property = atom_pairs[i].property; - - // None is not a valid property - if (property == None) - continue; - - // Service this request - event.target = target; - event.property = property; - if (!handle_selection(&event, true)) { - /* FIXME: ICCCM 2.6.2: - - If the owner fails to convert the target named by an - atom in the MULTIPLE property, it should replace that - atom in the property with None. - */ - handled = false; - } - } - } - - return handled; -} - -static bool handle_selection(XSelectionRequestEvent *req, bool is_multiple) -{ - bool handled =false; - - if (req->target == xa_timestamp) { - handled = handle_selection_TIMESTAMP(req); - } else if (req->target == xa_targets) { - handled = handle_selection_TARGETS(req); - } else if (req->target == XA_STRING) { - handled = handle_selection_STRING(req); - } else if (req->target == xa_multiple) { - handled = handle_selection_MULTIPLE(req); - } - - // Notify requestor only when we are done with his request - if (handled && !is_multiple) { - XEvent out_event; - out_event.xselection.type = SelectionNotify; - out_event.xselection.requestor = req->requestor; - out_event.xselection.selection = req->selection; - out_event.xselection.target = req->target; - out_event.xselection.property = req->property; - out_event.xselection.time = req->time; - XSendEvent(x_display, req->requestor, False, 0, &out_event); - } - - return handled; -} - -void ClipboardSelectionRequest(XSelectionRequestEvent *req) -{ - if (req->requestor == clip_win || req->selection != xa_clipboard) - return; - - D(bug("Selection requested from 0x%lx to 0x%lx (%s) 0x%lx (%s)\n", - req->requestor, - req->selection, - XGetAtomName(req->display, req->selection), - req->target, - XGetAtomName(req->display, req->target))); - - handle_selection(req, false); -} diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index b8aa82c8..ffba2f41 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -16,40 +16,20 @@ dnl Some systems do not put corefiles in the currect directory, avoid saving dnl cores for the configure tests since some are intended to dump core. ulimit -c 0 -AC_ARG_ENABLE(standalone-gui,[ --enable-standalone-gui enable a standalone GUI prefs editor [default=no]], [WANT_STANDALONE_GUI=$enableval], [WANT_STANDALONE_GUI=no]) - -dnl Mac OS X GUI. -AC_ARG_ENABLE(macosx-gui, [ --enable-macosx-gui enable Mac OS X GUI [default=no]], [WANT_MACOSX_GUI=$enableval], [WANT_MACOSX_GUI=no]) - -dnl Mac OS X Sound -AC_ARG_ENABLE(macosx-sound, [ --enable-macosx-sound enable Mac OS X Sound [default=no]], [WANT_MACOSX_SOUND=$enableval], [WANT_MACOSX_SOUND=no]) - dnl Video options. -AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes]) -AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode extension [default=yes]], [WANT_XF86_VIDMODE=$enableval], [WANT_XF86_VIDMODE=yes]) -AC_ARG_ENABLE(fbdev-dga, [ --enable-fbdev-dga use direct frame buffer access via /dev/fb [default=yes]], [WANT_FBDEV_DGA=$enableval], [WANT_FBDEV_DGA=yes]) AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=yes]], [WANT_VOSF=$enableval], [WANT_VOSF=yes]) dnl SDL options. AC_ARG_ENABLE(sdl-static, [ --enable-sdl-static use SDL static libraries for linking [default=no]], [WANT_SDL_STATIC=$enableval], [WANT_SDL_STATIC=no]) AC_ARG_ENABLE(sdl-video, [ --enable-sdl-video use SDL for video graphics [default=no]], [WANT_SDL_VIDEO=$enableval], [WANT_SDL_VIDEO=no]) AC_ARG_ENABLE(sdl-audio, [ --enable-sdl-audio use SDL for audio [default=no]], [WANT_SDL_AUDIO=$enableval], [WANT_SDL_AUDIO=no]) -AC_ARG_ENABLE(sdl-framework, [ --enable-sdl-framework use SDL framework [default=no]], [WANT_SDL_FRAMEWORK=$enableval], [WANT_SDL_FRAMEWORK=no]) -AC_ARG_ENABLE(sdl-framework-prefix, [ --enable-sdl-framework-prefix=PFX default=/Library/Frameworks], [SDL_FRAMEWORK="$enableval"], [SDL_FRAMEWORK=/Library/Frameworks]) - -dnl JIT compiler options. -AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=no]], [WANT_JIT=$enableval], [WANT_JIT=no]) -AC_ARG_ENABLE(jit-debug, [ --enable-jit-debug activate native code disassemblers [default=no]], [WANT_JIT_DEBUG=$enableval], [WANT_JIT_DEBUG=no]) dnl FPU emulation core. AC_ARG_ENABLE(fpe, [ --enable-fpe=FPE specify which fpu emulator to use [default=auto]], [ case "$enableval" in dnl default is always ieee, if architecture has this fp format - auto) FPE_CORE_TEST_ORDER="ieee uae";; - ieee) FPE_CORE_TEST_ORDER="ieee";; uae) FPE_CORE_TEST_ORDER="uae";; - x86) FPE_CORE_TEST_ORDER="x86";; *) AC_MSG_ERROR([--enable-fpe takes only one of the following values: auto, x86, ieee, uae]);; esac ], @@ -70,35 +50,12 @@ AC_ARG_ENABLE(addressing, [ ADDRESSING_TEST_ORDER="direct banks" ]) -dnl External packages. -AC_ARG_WITH(esd, [ --with-esd support ESD for sound under Linux/FreeBSD [default=yes]], [WANT_ESD=$withval], [WANT_ESD=yes]) -AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]], - [case "$withval" in - gtk1) WANT_GTK="gtk";; - gtk|gtk2) WANT_GTK="$withval";; - yes) WANT_GTK="gtk2 gtk";; - *) WANT_GTK="no";; - esac], - [WANT_GTK="gtk2 gtk"]) -AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=yes]], [WANT_MON=$withval], [WANT_MON=yes]) - -AC_ARG_WITH(bincue, - AS_HELP_STRING([--with-bincue], [Allow cdrom image files in bin/cue mode])) - -AC_ARG_WITH(libvhd, - AS_HELP_STRING([--with-libvhd], [Enable VHD disk images])) - - dnl Canonical system information. AC_CANONICAL_HOST AC_CANONICAL_TARGET dnl Target OS type (target is host if not cross-compiling). case "$target_os" in - linux*) OS_TYPE=linux;; - netbsd*) OS_TYPE=netbsd;; - freebsd*) OS_TYPE=freebsd;; - solaris*) OS_TYPE=solaris;; darwin*) OS_TYPE=darwin;; *) OS_TYPE=`echo $target_os | sed -e 's/-/_/g' | sed -e 's/\./_/g'`;; esac @@ -106,15 +63,9 @@ DEFINES="$DEFINES -DOS_$OS_TYPE" dnl Target CPU type. HAVE_I386=no -HAVE_M68K=no -HAVE_SPARC=no -HAVE_POWERPC=no HAVE_X86_64=no case "$target_cpu" in i386* | i486* | i586* | i686* | i786* ) HAVE_I386=yes;; - m68k* ) HAVE_M68K=yes;; - sparc* ) HAVE_SPARC=yes;; - powerpc* ) HAVE_POWERPC=yes;; x86_64* | amd64* ) HAVE_X86_64=yes;; esac @@ -143,73 +94,17 @@ AC_PROG_MAKE_SET AC_PROG_INSTALL AC_PROG_EGREP -dnl We use mon if possible. -MONSRCS= -if [[ "x$WANT_MON" = "xyes" ]]; then - AC_MSG_CHECKING(for mon) - mon_srcdir=../../../mon/src - if grep mon_init $mon_srcdir/mon.h >/dev/null 2>/dev/null; then - AC_MSG_RESULT(yes) - AC_DEFINE(ENABLE_MON, 1, [Define if using "mon".]) - MONSRCS="$mon_srcdir/mon.cpp $mon_srcdir/mon_6502.cpp $mon_srcdir/mon_z80.cpp $mon_srcdir/mon_cmd.cpp $mon_srcdir/mon_disass.cpp $mon_srcdir/mon_ppc.cpp $mon_srcdir/mon_lowmem.cpp $mon_srcdir/disass/floatformat.c $mon_srcdir/disass/i386-dis.c $mon_srcdir/disass/m68k-dis.c $mon_srcdir/disass/m68k-opc.c $mon_srcdir/disass/mips-dis.c $mon_srcdir/disass/mips-opc.c $mon_srcdir/disass/mips16-opc.c" - CXXFLAGS="$CXXFLAGS -I$mon_srcdir -I$mon_srcdir/disass" - AC_CHECK_LIB(ncurses, tgetent, , - [AC_CHECK_LIB(termcap, tgetent, , - [AC_CHECK_LIB(termlib, tgetent, , - [AC_CHECK_LIB(terminfo, tgetent, , - [AC_CHECK_LIB(Hcurses, tgetent, , - [AC_CHECK_LIB(curses, tgetent)])])])])]) - AC_CHECK_LIB(readline, readline) - else - AC_MSG_RESULT(no) - AC_MSG_WARN([Could not find mon, ignoring --with-mon.]) - WANT_MON=no - fi -fi - dnl Checks for libraries. AC_CHECK_LIB(posix4, sem_init) AC_CHECK_LIB(rt, timer_create) AC_CHECK_LIB(rt, shm_open) AC_CHECK_LIB(m, cos) -dnl AC_CHECK_SDLFRAMEWORK($1=NAME, $2=INCLUDES) -dnl AC_TRY_LINK uses main() but SDL needs main to take args, -dnl therefore main is undefined with #undef. -dnl Framework can be in an custom location. -AC_DEFUN([AC_CHECK_SDLFRAMEWORK], [ - AS_VAR_PUSHDEF([ac_Framework], [ac_cv_framework_$1]) - AC_CACHE_CHECK([whether compiler supports framework $1], - ac_Framework, [ - saved_LIBS="$LIBS" - LIBS="$LIBS -framework $1" - if [[ "x$SDL_FRAMEWORK" != "x/Library/Frameworks" ]]; then - if [[ "x$SDL_FRAMEWORK" != "x/System/Library/Frameworks" ]]; then - LIBS="$saved_LIBS -F$SDL_FRAMEWORK -framework $1" - fi - fi - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I$SDL_FRAMEWORK/SDL.framework/Headers" - AC_TRY_LINK( - [$2 -#undef main], [], - [AS_VAR_SET(ac_Framework, yes)], [AS_VAR_SET(ac_Framework, no); -LIBS="$saved_LIBS"; CPPFLAGS="$saved_CPPFLAGS"] - ) - ]) - AS_IF([test AS_VAR_GET(ac_Framework) = yes], - [AC_DEFINE(AS_TR_CPP(HAVE_FRAMEWORK_$1), 1, [Define if framework $1 is available.])] - ) - AS_VAR_POPDEF([ac_Framework]) -]) dnl Do we need SDL? WANT_SDL=no if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then WANT_SDL=yes - WANT_XF86_DGA=no - WANT_XF86_VIDMODE=no - WANT_FBDEV_DGA=no SDL_SUPPORT="$SDL_SUPPORT video" fi if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then @@ -217,86 +112,36 @@ if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then SDL_SUPPORT="$SDL_SUPPORT audio" fi if [[ "x$WANT_SDL" = "xyes" ]]; then - if [[ "x$WANT_SDL_FRAMEWORK" = "xyes" ]]; then - AC_CHECK_SDLFRAMEWORK(SDL, [#include ]) + + AC_PATH_PROG(sdl_config, "sdl-config") + if [[ -n "$sdl_config" ]]; then + case $target_os in + *) + sdl_cflags=`$sdl_config --cflags` + if [[ "x$WANT_SDL_STATIC" = "xyes" ]]; then + sdl_libs=`$sdl_config --static-libs` + else + sdl_libs=`$sdl_config --libs` + fi + ;; + esac + CFLAGS="$CFLAGS $sdl_cflags" + CXXFLAGS="$CXXFLAGS $sdl_cflags" + LIBS="$LIBS $sdl_libs" else - ac_cv_framework_SDL=no - fi - if [[ "x$ac_cv_framework_SDL" = "xno" ]]; then - AC_PATH_PROG(sdl_config, "sdl-config") - if [[ -n "$sdl_config" ]]; then - case $target_os in - # Special treatment for Cygwin so that we can still use the POSIX layer - *cygwin*) - sdl_cflags="-I`$sdl_config --prefix`/include/SDL" - sdl_libs="-L`$sdl_config --exec-prefix`/lib -lSDL" - ;; - *) - sdl_cflags=`$sdl_config --cflags` - if [[ "x$WANT_SDL_STATIC" = "xyes" ]]; then - sdl_libs=`$sdl_config --static-libs` - else - sdl_libs=`$sdl_config --libs` - fi - ;; - esac - CFLAGS="$CFLAGS $sdl_cflags" - CXXFLAGS="$CXXFLAGS $sdl_cflags" - LIBS="$LIBS $sdl_libs" - else - WANT_SDL=no - fi + WANT_SDL=no fi + SDL_SUPPORT=`echo "$SDL_SUPPORT" | sed -e "s/^ //"` else SDL_SUPPORT="none" fi -dnl We need X11, if not using SDL. -if [[ "x$WANT_SDL_VIDEO" = "xno" ]]; then - AC_PATH_XTRA - if [[ "x$no_x" = "xyes" ]]; then - AC_MSG_ERROR([You need X11 to run Basilisk II.]) - fi - CFLAGS="$CFLAGS $X_CFLAGS" - CXXFLAGS="$CXXFLAGS $X_CFLAGS" - LIBS="$LIBS $X_PRE_LIBS $X_LIBS -lX11 -lXext $X_EXTRA_LIBS" -fi - -dnl BINCUE -AS_IF([test "x$with_bincue" = "xyes" ], [have_bincue=yes], [have_bincue=no]) -AS_IF([test "x$have_bincue" = "xyes" ], [ - if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then - DEFINES="$DEFINES -DBINCUE" - else - AC_MSG_ERROR([You need SDL Audio to use BINCUE support.]) - fi -]) - -dnl LIBVHD -AS_IF([test "x$with_libvhd" = "xyes" ], [have_libvhd=yes], [have_libvhd=no]) -AS_IF([test "x$have_libvhd" = "xyes" ], [ - CPPFLAGS="$CPPFLAGS -DHAVE_LIBVHD" - LIBS="$LIBS -lvhd" - case $target_os in - linux*) - LIBS="$LIBS -luuid" - esac - AC_CHECK_LIB(vhd, vhd_open) - AC_CHECK_LIB(vhd, vhd_io_read) - AC_CHECK_LIB(vhd, vhd_io_write) - AC_CHECK_LIB(vhd, vhd_close) -]) - - - -dnl We want pthreads. Try libpthread first, then libc_r (FreeBSD), then PTL. +dnl We want pthreads. Try libpthread first, then PTL. HAVE_PTHREADS=yes AC_CHECK_LIB(pthread, pthread_create, , [ - AC_CHECK_LIB(c_r, pthread_create, , [ - AC_CHECK_LIB(PTL, pthread_create, , [ - HAVE_PTHREADS=no - ]) + AC_CHECK_LIB(PTL, pthread_create, , [ + HAVE_PTHREADS=no ]) ]) if [[ "x$HAVE_PTHREADS" = "xyes" ]]; then @@ -316,103 +161,7 @@ AC_CHECK_FUNCS(sem_init, , [ fi ]) -dnl We use DGA (XFree86 or fbdev) if possible. -if [[ "x$WANT_XF86_DGA" = "xyes" ]]; then - AC_CHECK_LIB(Xxf86dga, XF86DGAQueryExtension, [ - AC_DEFINE(ENABLE_XF86_DGA, 1, [Define if using XFree86 DGA extension.]) - LIBS="$LIBS -lXxf86dga" - if [[ "x$WANT_FBDEV_DGA" = "xyes" ]]; then - AC_MSG_WARN([Cannot have both --enable-xf86-dga and --enable-fbdev-dga, ignoring --enable-fbdev-dga.]) - WANT_FBDEV_DGA=no - fi - ], [ - AC_MSG_WARN([Could not find XFree86 DGA extension, ignoring --enable-xf86-dga.]) - WANT_XF86_DGA=no - ]) -fi -if [[ "x$WANT_FBDEV_DGA" = "xyes" ]]; then - AC_DEFINE(ENABLE_FBDEV_DGA, 1, [Define if using DGA with framebuffer device.]) -fi - -dnl We use XFree86 VidMode if possible. -if [[ "x$WANT_XF86_VIDMODE" = "xyes" ]]; then - AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryExtension, [ - AC_DEFINE(ENABLE_XF86_VIDMODE, 1, [Define if using XFree86 DGA extension.]) - LIBS="$LIBS -lXxf86vm" - ], [ - AC_MSG_WARN([Could not find XFree86 VidMode extension, ignoring --enable-xf86-vidmode.]) - WANT_XF86_VIDMODE=no - ]) -fi - -dnl We use GTK+ if possible. UISRCS=../dummy/prefs_editor_dummy.cpp -case "x$WANT_GTK" in -xgtk2*) - AM_PATH_GTK_2_0(1.3.15, [ - GUI_CFLAGS="$GTK_CFLAGS" - GUI_LIBS="$GTK_LIBS" - WANT_GTK=gtk2 - ], [ - case "x${WANT_GTK}x" in - *gtkx) - AC_MSG_WARN([Could not find GTK+ 2.0, trying with GTK+ 1.2.]) - WANT_GTK=gtk - ;; - *) - AC_MSG_WARN([Could not find GTK+, disabling user interface.]) - WANT_GTK=no - ;; - esac - ]) - ;; -esac -if [[ "x$WANT_GTK" = "xgtk" ]]; then - AM_PATH_GTK(1.2.0, [ - GUI_CFLAGS="$GTK_CFLAGS" - GUI_LIBS="$GTK_LIBS" - dnl somehow, would redefine gettext() to nothing if - dnl ENABLE_NLS is not set, thusly conflicting with C++ which - dnl includes - AM_GNU_GETTEXT - B2_PATH_GNOMEUI([ - AC_DEFINE(HAVE_GNOMEUI, 1, [Define if libgnomeui is available.]) - GUI_CFLAGS="$GUI_CFLAGS $GNOMEUI_CFLAGS" - GUI_LIBS="$GUI_LIBS $GNOMEUI_LIBS" - ], []) - ], [ - AC_MSG_WARN([Could not find GTK+, disabling user interface.]) - WANT_GTK=no - ]) -fi -if [[ "x$WANT_GTK" != "xno" -a "x$WANT_STANDALONE_GUI" = "xno" ]]; then - AC_DEFINE(ENABLE_GTK, 1, [Define if using GTK.]) - UISRCS=prefs_editor_gtk.cpp -fi -AC_SUBST(GUI_CFLAGS) -AC_SUBST(GUI_LIBS) - -dnl Build external GUI if requested. -if [[ "$WANT_STANDALONE_GUI" != "yes" ]]; then - WANT_STANDALONE_GUI=no -fi -if [[ "$WANT_GTK" = "no" ]]; then - WANT_STANDALONE_GUI=no -fi -AC_SUBST(STANDALONE_GUI, [$WANT_STANDALONE_GUI]) - -dnl We use ESD if possible. -if [[ "x$WANT_ESD" = "xyes" ]]; then - AM_PATH_ESD(0.2.8, [ - AC_DEFINE(ENABLE_ESD, 1, [Define is using ESD.]) - CFLAGS="$CFLAGS $ESD_CFLAGS" - CXXFLAGS="$CXXFLAGS $ESD_CFLAGS" - LIBS="$LIBS $ESD_LIBS" - ], [ - AC_MSG_WARN([Could not find ESD, disabling ESD support.]) - WANT_ESD=no - ]) -fi dnl We use 64-bit file size support if possible. AC_SYS_LARGEFILE @@ -425,14 +174,6 @@ AC_CHECK_HEADERS(readline.h history.h readline/readline.h readline/history.h) AC_CHECK_HEADERS(sys/socket.h sys/ioctl.h sys/filio.h sys/bitypes.h sys/wait.h) AC_CHECK_HEADERS(sys/poll.h sys/select.h) AC_CHECK_HEADERS(arpa/inet.h) -AC_CHECK_HEADERS(linux/if.h linux/if_tun.h net/if.h net/if_tun.h, [], [], [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -]) AC_CHECK_HEADERS(AvailabilityMacros.h) AC_CHECK_HEADERS(IOKit/storage/IOBlockStorageDevice.h) AC_CHECK_HEADERS(sys/stropts.h stropts.h) @@ -485,58 +226,6 @@ AC_CHECK_FUNCS(poll inet_aton) dnl Darwin seems to define mach_task_self() instead of task_self(). AC_CHECK_FUNCS(mach_task_self task_self) -dnl Check for headers and functions related to pty support (sshpty.c) -dnl From openssh-3.2.2p1 configure.ac - -AC_CHECK_HEADERS(strings.h login.h sys/bsdtty.h sys/stat.h util.h pty.h) -AC_CHECK_FUNCS(_getpty vhangup strlcpy) - -case "$host" in -*-*-hpux10.26) - disable_ptmx_check=yes - ;; -*-*-linux*) - no_dev_ptmx=1 - ;; -mips-sony-bsd|mips-sony-newsos4) - AC_DEFINE(HAVE_NEWS4, 1, [Define if you are on NEWS-OS (additions from openssh-3.2.2p1, for sshpty.c).]) - ;; -*-*-sco3.2v4*) - no_dev_ptmx=1 - ;; -*-*-sco3.2v5*) - no_dev_ptmx=1 - ;; -*-*-cygwin*) - no_dev_ptmx=1 - ;; -*-*-darwin*) - no_dev_ptmx=1 - LIBS="$LIBS -lstdc++" - ;; -*-*-freebsd*) - no_dev_ptmx=1 - ;; -esac - -if test -z "$no_dev_ptmx" ; then - if test "x$disable_ptmx_check" != "xyes" ; then - AC_CHECK_FILE([/dev/ptmx], - [ - AC_DEFINE_UNQUOTED(HAVE_DEV_PTMX, 1, [Define if you have /dev/ptmx.]) - have_dev_ptmx=1 - ] - ) - fi -fi -AC_CHECK_FILE([/dev/ptc], - [ - AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC, 1, [Define if you have /dev/ptc.]) - have_dev_ptc=1 - ] -) -dnl (end of code from openssh-3.2.2p1 configure.ac) - dnl Check for systems where POSIX-style non-blocking I/O (O_NONBLOCK) dnl doesn't work or is unimplemented. On these systems (mostly older dnl ones), use the old BSD-style FIONBIO approach instead. [tcl.m4] @@ -616,191 +305,41 @@ AC_CHECK_FRAMEWORK(IOKit, [#include ]) AC_CHECK_FRAMEWORK(CoreFoundation, [#include ]) dnl Select system-dependant source files. -SERIALSRC=serial_unix.cpp +SERIALSRC=../dummy/serial_dummy.cpp ETHERSRC=../dummy/ether_dummy.cpp SCSISRC=../dummy/scsi_dummy.cpp AUDIOSRC=../dummy/audio_dummy.cpp EXTFSSRC=extfs_unix.cpp EXTRASYSSRCS= -CAN_NATIVE_M68K=no case "$target_os" in -linux*) - ETHERSRC=ether_unix.cpp - AUDIOSRC=audio_oss_esd.cpp - SCSISRC=Linux/scsi_linux.cpp - ;; -freebsd*) - ETHERSRC=ether_unix.cpp - AUDIOSRC=audio_oss_esd.cpp - DEFINES="$DEFINES -DBSD_COMP" - CXXFLAGS="$CXXFLAGS -fpermissive" - dnl Check for the CAM library - AC_CHECK_LIB(cam, cam_open_btl, HAVE_LIBCAM=yes, HAVE_LIBCAM=no) - if [[ "x$HAVE_LIBCAM" = "xno" ]]; then - AC_MSG_WARN([Cannot find libcam for SCSI management, disabling SCSI support.]) - else - dnl Check for the sys kernel includes - AC_CHECK_HEADER(camlib.h) - if [[ "x$ac_cv_header_camlib_h" = "xno" ]]; then - dnl In this case I should fix this thing including a "patch" - dnl to access directly to the functions in the kernel :) --Orlando - AC_MSG_WARN([Cannot find includes for CAM library, disabling SCSI support.]) - else - SCSISRC=FreeBSD/scsi_freebsd.cpp - LIBS="$LIBS -lcam" - DEFINES="$DEFINES -DCAM" - fi - fi - ;; -netbsd*) - CAN_NATIVE_M68K=yes - ETHERSRC=ether_unix.cpp - ;; -solaris*) - AUDIOSRC=Solaris/audio_solaris.cpp - DEFINES="$DEFINES -DBSD_COMP -D_POSIX_PTHREAD_SEMANTICS" - ;; -irix*) - AUDIOSRC=Irix/audio_irix.cpp - EXTRASYSSRCS=Irix/unaligned.c - LIBS="$LIBS -laudio" - WANT_ESD=no - - dnl Check if our compiler supports -IPA (MIPSPro) - HAVE_IPA=no - ocflags="$CFLAGS" - CFLAGS=`echo "$CFLAGS -IPA" | sed -e "s/-g//g"` - AC_MSG_CHECKING(if "-IPA" works) - dnl Do a test compile of an empty function - AC_TRY_COMPILE([#if defined __GNUC__ - # error GCC does not support IPA yet - #endif],, [AC_MSG_RESULT(yes); HAVE_IPA=yes], AC_MSG_RESULT(no)) - CFLAGS="$ocflags" - ;; darwin*) - ETHERSRC=ether_unix.cpp if [[ "x$ac_cv_framework_IOKit" = "xyes" -a "x$ac_cv_framework_CoreFoundation" = "xyes" ]]; then - EXTRASYSSRCS="../MacOSX/sys_darwin.cpp" + EXTRASYSSRCS="Darwin/sys_darwin.cpp" fi - if [[ "x$ac_cv_framework_Carbon" = "xyes" ]]; then - EXTFSSRC=../MacOSX/extfs_macosx.cpp - fi - ;; -cygwin*) - SERIALSRC="../dummy/serial_dummy.cpp" - EXTRASYSSRCS="../Windows/BasiliskII.rc" ;; esac -dnl Is the slirp library supported? -case "$ac_cv_have_byte_bitfields" in -yes|"guessing yes") - CAN_SLIRP=yes - ETHERSRC=ether_unix.cpp - ;; -esac -if [[ -n "$CAN_SLIRP" ]]; then - AC_DEFINE(HAVE_SLIRP, 1, [Define if slirp library is supported]) - SLIRP_SRCS="\ - ../slirp/bootp.c ../slirp/ip_output.c ../slirp/tcp_input.c \ - ../slirp/cksum.c ../slirp/mbuf.c ../slirp/tcp_output.c \ - ../slirp/debug.c ../slirp/misc.c ../slirp/tcp_subr.c \ - ../slirp/if.c ../slirp/sbuf.c ../slirp/tcp_timer.c \ - ../slirp/ip_icmp.c ../slirp/slirp.c ../slirp/tftp.c \ - ../slirp/ip_input.c ../slirp/socket.c ../slirp/udp.c" -fi -AC_SUBST(SLIRP_SRCS) - -if [[ "x$WANT_MACOSX_GUI" = "xyes" ]]; then - CPPFLAGS="$CPPFLAGS -I../MacOSX" - LIBS="$LIBS -framework CoreAudio -framework AudioUnit -framework AudioToolbox" - - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/Controller.mm" - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/Emulator.mm" - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/EmulatorView.mm" - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/PrefsEditor.mm" - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/NNThread.m" - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/misc_macosx.mm" - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/clip_macosx.cpp" - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/main_macosx.mm" - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/prefs_macosx.cpp" - - VIDEOSRCS="../MacOSX/video_macosx.mm" -else - EXTRASYSSRCS="$EXTRASYSSRCS main_unix.cpp prefs_unix.cpp" -fi - -if [[ "x$WANT_MACOSX_SOUND" = "xyes" ]]; then - AUDIOSRC="../MacOSX/audio_macosx.cpp ../MacOSX/AudioBackEnd.cpp ../MacOSX/AudioDevice.cpp ../MacOSX/MacOSX_sound_if.cpp" - LIBS="$LIBS -framework AudioToolbox -framework AudioUnit -framework CoreAudio" -fi +EXTRASYSSRCS="$EXTRASYSSRCS main_unix.cpp prefs_unix.cpp" dnl SDL overrides if [[ "x$WANT_SDL" = "xyes" ]]; then AC_DEFINE(USE_SDL, 1, [Define to enble SDL support]) - if [[ "x$WANT_SDL_FRAMEWORK" = "xyes" ]]; then - EXTRASYSSRCS="$EXTRASYSSRCS ../SDL/SDLMain.m" - fi fi if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support]) VIDEOSRCS="../SDL/video_sdl.cpp" KEYCODES="../SDL/keycodes" - if [[ "x$ac_cv_framework_Carbon" = "xyes" ]]; then - AC_MSG_CHECKING([whether __LP64__ is defined]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#if !defined(__LP64__) - # error __LP64__ not defined - #endif - ]])], - [AC_MSG_RESULT(yes); LP64_DEFINED=yes], - [AC_MSG_RESULT(no)]) - if [[ "x$LP64_DEFINED" = "xyes" ]]; then - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/clip_macosx64.mm ../pict.c" - else - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/clip_macosx.cpp" - fi - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/utils_macosx.mm" - CPPFLAGS="$CPPFLAGS -I../MacOSX" - else - case "$target_os" in - cygwin*) - EXTRASYSSRCS="$EXTRASYSSRCS ../Windows/clip_windows.cpp" - ;; - *) - EXTRASYSSRCS="$EXTRASYSSRCS ../dummy/clip_dummy.cpp" - ;; - esac - fi -elif [[ "x$WANT_MACOSX_GUI" != "xyes" ]]; then - VIDEOSRCS="video_x.cpp" - KEYCODES="keycodes" - EXTRASYSSRCS="$EXTRASYSSRCS clip_unix.cpp" + case "$target_os" in + *) + EXTRASYSSRCS="$EXTRASYSSRCS ../dummy/clip_dummy.cpp" + ;; + esac fi if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then AC_DEFINE(USE_SDL_AUDIO, 1, [Define to enable SDL audio support]) AUDIOSRC="../SDL/audio_sdl.cpp" fi -dnl BINCUE overrides - -if [[ "x$have_bincue" = "xyes" ]]; then - EXTRASYSSRCS="$EXTRASYSSRCS bincue_unix.cpp" -fi - -dnl libvhd overrides - -if [[ "x$have_libvhd" = "xyes" ]]; then - EXTRASYSSRCS="$EXTRASYSSRCS vhd_unix.cpp" -fi - - -dnl Use 68k CPU natively? -WANT_NATIVE_M68K=no -if [[ "x$HAVE_M68K" = "xyes" -a "x$CAN_NATIVE_M68K" = "xyes" ]]; then - AC_DEFINE(ENABLE_NATIVE_M68K, 1, [Define if using native 68k mode.]) - WANT_NATIVE_M68K=yes -fi - if [[ "x$HAVE_PTHREADS" = "xno" ]]; then dnl Serial, ethernet and audio support needs pthreads AC_MSG_WARN([You don't have pthreads, disabling serial, ethernet and audio support.]) @@ -808,7 +347,7 @@ if [[ "x$HAVE_PTHREADS" = "xno" ]]; then ETHERSRC=../dummy/ether_dummy.cpp AUDIOSRC=../dummy/audio_dummy.cpp fi -SYSSRCS="$VIDEOSRCS $EXTFSSRC $SERIALSRC $ETHERSRC $SCSISRC $AUDIOSRC $SEMSRC $UISRCS $MONSRCS $EXTRASYSSRCS" +SYSSRCS="$VIDEOSRCS $EXTFSSRC $SERIALSRC $ETHERSRC $SCSISRC $AUDIOSRC $SEMSRC $UISRCS $EXTRASYSSRCS" dnl Define a macro that translates a yesno-variable into a C macro definition dnl to be put into the config.h file @@ -825,10 +364,6 @@ dnl Check that the host supports TUN/TAP devices AC_CACHE_CHECK([whether TUN/TAP is supported], ac_cv_tun_tap_support, [ AC_TRY_COMPILE([ - #if defined(HAVE_LINUX_IF_H) && defined(HAVE_LINUX_IF_TUN_H) - #include - #include - #endif #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_IF_TUN_H) #include #include @@ -1114,30 +649,6 @@ AC_CACHE_CHECK([whether your system supports Mach exceptions], AC_TRANSLATE_DEFINE(HAVE_MACH_EXCEPTIONS, "$ac_cv_have_mach_exceptions", [Define if your system supports Mach exceptions.]) -dnl Check if Windows exceptions are supported. -AC_CACHE_CHECK([whether your system supports Windows exceptions], - ac_cv_have_win32_exceptions, [ - AC_LANG_SAVE - AC_LANG_CPLUSPLUS - AC_TRY_RUN([ - #define HAVE_WIN32_EXCEPTIONS 1 - #define CONFIGURE_TEST_SIGSEGV_RECOVERY - #include "../CrossPlatform/vm_alloc.cpp" - #include "../CrossPlatform/sigsegv.cpp" - ], [ - sigsegv_recovery=win32 - ac_cv_have_win32_exceptions=yes - ], - ac_cv_have_win32_exceptions=no, - dnl When cross-compiling, do not assume anything. - ac_cv_have_win32_exceptions=no - ) - AC_LANG_RESTORE - ] -) -AC_TRANSLATE_DEFINE(HAVE_WIN32_EXCEPTIONS, "$ac_cv_have_win32_exceptions", - [Define if your system supports Windows exceptions.]) - dnl Otherwise, check if extended signals are supported with . if [[ -z "$sigsegv_recovery" ]]; then AC_CACHE_CHECK([whether your system supports extended signal handlers via asm], @@ -1254,11 +765,6 @@ AC_PATH_PROG([BLESS], "true") dnl Check for linker script support case $target_os:$target_cpu in -linux*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-i386.ld";; -linux*:x86_64) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-x86_64.ld";; -linux*:powerpc) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-ppc.ld";; -netbsd*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-i386.ld";; -freebsd*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/freebsd-i386.ld";; darwin*:*) LINKER_SCRIPT_FLAGS="-Wl,-seg1addr,0x78048000";; esac if [[ -n "$LINKER_SCRIPT_FLAGS" ]]; then @@ -1286,60 +792,52 @@ AC_TRANSLATE_DEFINE(HAVE_LINKER_SCRIPT, "$ac_cv_linker_script_works", [Define if there is a linker script to relocate the executable above 0x70000000.]) dnl Determine the addressing mode to use -if [[ "x$WANT_NATIVE_M68K" = "xyes" ]]; then - ADDRESSING_MODE="real" -else - ADDRESSING_MODE="" - AC_MSG_CHECKING([for the addressing mode to use]) - for am in $ADDRESSING_TEST_ORDER; do - case $am in - real) - dnl Requires ability to mmap() Low Memory globals - if [[ "x$ac_cv_can_map_lm$ac_cv_pagezero_hack" = "xnono" ]]; then - continue - fi - dnl Requires VOSF screen updates - if [[ "x$CAN_VOSF" = "xno" ]]; then - continue - fi - dnl Real addressing will probably work. - ADDRESSING_MODE="real" - WANT_VOSF=yes dnl we can use VOSF and we need it actually - DEFINES="$DEFINES -DREAL_ADDRESSING" - if [[ "x$ac_cv_pagezero_hack" = "xyes" ]]; then - BLESS=Darwin/lowmem - LDFLAGS="$LDFLAGS -pagezero_size 0x2000" - fi - break - ;; - direct) - dnl Requires VOSF screen updates - if [[ "x$CAN_VOSF" = "xyes" ]]; then - ADDRESSING_MODE="direct" - WANT_VOSF=yes dnl we can use VOSF and we need it actually - DEFINES="$DEFINES -DDIRECT_ADDRESSING" - break - fi - ;; - banks) - dnl Default addressing mode - ADDRESSING_MODE="memory banks" - break - ;; - *) - AC_MSG_ERROR([Internal configure.in script error for $am addressing mode]) - esac - done - AC_MSG_RESULT($ADDRESSING_MODE) - if [[ "x$ADDRESSING_MODE" = "x" ]]; then - AC_MSG_WARN([Sorry, no suitable addressing mode in $ADDRESSING_TEST_ORDER]) - ADDRESSING_MODE="memory banks" - fi -fi -dnl Banked Memory Addressing mode is not supported by the JIT compiler -if [[ "x$WANT_JIT" = "xyes" -a "x$ADDRESSING_MODE" = "xmemory banks" ]]; then - AC_MSG_ERROR([Sorry, the JIT Compiler requires Direct Addressing, at least]) +ADDRESSING_MODE="" +AC_MSG_CHECKING([for the addressing mode to use]) +for am in $ADDRESSING_TEST_ORDER; do + case $am in + real) + dnl Requires ability to mmap() Low Memory globals + if [[ "x$ac_cv_can_map_lm$ac_cv_pagezero_hack" = "xnono" ]]; then + continue + fi + dnl Requires VOSF screen updates + if [[ "x$CAN_VOSF" = "xno" ]]; then + continue + fi + dnl Real addressing will probably work. + ADDRESSING_MODE="real" + WANT_VOSF=yes dnl we can use VOSF and we need it actually + DEFINES="$DEFINES -DREAL_ADDRESSING" + if [[ "x$ac_cv_pagezero_hack" = "xyes" ]]; then + BLESS=Darwin/lowmem + LDFLAGS="$LDFLAGS -pagezero_size 0x2000" + fi + break + ;; + direct) + dnl Requires VOSF screen updates + if [[ "x$CAN_VOSF" = "xyes" ]]; then + ADDRESSING_MODE="direct" + WANT_VOSF=yes dnl we can use VOSF and we need it actually + DEFINES="$DEFINES -DDIRECT_ADDRESSING" + break + fi + ;; + banks) + dnl Default addressing mode + ADDRESSING_MODE="memory banks" + break + ;; + *) + AC_MSG_ERROR([Internal configure.in script error for $am addressing mode]) + esac +done +AC_MSG_RESULT($ADDRESSING_MODE) +if [[ "x$ADDRESSING_MODE" = "x" ]]; then + AC_MSG_WARN([Sorry, no suitable addressing mode in $ADDRESSING_TEST_ORDER]) + ADDRESSING_MODE="memory banks" fi dnl Enable VOSF screen updates with this feature is requested and feasible @@ -1349,16 +847,6 @@ else WANT_VOSF=no fi -dnl Check for GAS. -HAVE_GAS=no -AC_MSG_CHECKING(for GAS .p2align feature) -cat >conftest.S << EOF - .text - .p2align 5 -EOF -if $CC conftest.S -c -o conftest.o >/dev/null 2>&1 ; then HAVE_GAS=yes; fi -AC_MSG_RESULT($HAVE_GAS) - dnl Check for GCC 2.7 or higher. HAVE_GCC27=no AC_MSG_CHECKING(for GCC 2.7 or higher) @@ -1395,54 +883,6 @@ if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_I386" = "xyes" ]]; then CXXFLAGS="$CXXFLAGS -fomit-frame-pointer -fno-exceptions" fi -dnl (gb) Do not merge constants since it breaks fpu/fpu_x86.cpp. -dnl As of 2001/08/02, this affects the following compilers: -dnl Official: probably gcc-3.1 (mainline CVS) -dnl Mandrake: gcc-2.96 >= 0.59mdk, gcc-3.0.1 >= 0.1mdk -dnl Red Hat : gcc-2.96 >= 89, gcc-3.0 >= 1 -if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_ICC" = "xno" ]]; then - SAVED_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS -fno-merge-constants" - AC_CACHE_CHECK([whether GCC supports constants merging], ac_cv_gcc_constants_merging, [ - AC_LANG_SAVE - AC_LANG_CPLUSPLUS - AC_TRY_COMPILE([],[],[ac_cv_gcc_constants_merging=yes],[ac_cv_gcc_constants_merging=no]) - AC_LANG_RESTORE - ]) - if [[ "x$ac_cv_gcc_constants_merging" != "xyes" ]]; then - CXXFLAGS="$SAVED_CXXFLAGS" - fi -fi - -dnl Store motion was introduced in 3.3-hammer branch and any gcc >= 3.4 -dnl However, there are some corner cases exposed on x86-64 -if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_ICC" = "xno" ]]; then - SAVED_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS -fno-gcse-sm" - AC_CACHE_CHECK([whether GCC supports store motion], ac_cv_gcc_store_motion, [ - AC_LANG_SAVE - AC_LANG_CPLUSPLUS - AC_TRY_COMPILE([],[],[ac_cv_gcc_store_motion=yes],[ac_cv_gcc_store_motion=no]) - AC_LANG_RESTORE - ]) - if [[ "x$ac_cv_gcc_store_motion" != "xyes" ]]; then - CXXFLAGS="$SAVED_CXXFLAGS" - fi -fi - -dnl Add -fno-strict-aliasing for slirp sources -if [[ "x$HAVE_GCC30" = "xyes" ]]; then - SAVED_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fno-strict-aliasing" - AC_CACHE_CHECK([whether the compiler supports -fno-strict-aliasing], - ac_cv_gcc_no_strict_aliasing, [ - AC_TRY_COMPILE([],[],[ac_cv_gcc_no_strict_aliasing=yes],[ac_cv_gcc_no_strict_aliasing=no]) - ]) - if [[ "x$ac_cv_gcc_no_strict_aliasing" = "xyes" ]]; then - AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing") - fi - CFLAGS="$SAVED_CFLAGS" -fi dnl Add -mdynamic-no-pic for MacOS X (XXX icc10 will support MacOS X) if [[ "x$HAVE_GCC30" = "xyes" -a "x$HAVE_ICC" = "xno" ]]; then @@ -1460,257 +900,13 @@ if [[ "x$HAVE_GCC30" = "xyes" -a "x$HAVE_ICC" = "xno" ]]; then fi dnl Select appropriate CPU source and REGPARAM define. -ASM_OPTIMIZATIONS=none -CPUSRCS="cpuemu1.cpp cpuemu2.cpp cpuemu3.cpp cpuemu4.cpp cpuemu5.cpp cpuemu6.cpp cpuemu7.cpp cpuemu8.cpp" - -dnl (gb) JITSRCS will be emptied later if the JIT is not available -dnl Other platforms should define their own set of noflags file variants -CAN_JIT=no -JITSRCS="compemu1.cpp compemu2.cpp compemu3.cpp compemu4.cpp compemu5.cpp compemu6.cpp compemu7.cpp compemu8.cpp" - -if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_I386" = "xyes" ]]; then - dnl i386 CPU - DEFINES="$DEFINES -DUNALIGNED_PROFITABLE -DREGPARAM=\"__attribute__((regparm(3)))\"" - if [[ "x$HAVE_GAS" = "xyes" ]]; then - ASM_OPTIMIZATIONS=i386 - DEFINES="$DEFINES -DX86_ASSEMBLY -DOPTIMIZED_FLAGS -DSAHF_SETO_PROFITABLE" - JITSRCS="cpuemu1_nf.cpp cpuemu2_nf.cpp cpuemu3_nf.cpp cpuemu4_nf.cpp cpuemu5_nf.cpp cpuemu6_nf.cpp cpuemu7_nf.cpp cpuemu8_nf.cpp $JITSRCS" - CAN_JIT=yes - fi -elif [[ "x$HAVE_GCC30" = "xyes" -a "x$HAVE_X86_64" = "xyes" ]]; then - dnl x86-64 CPU - DEFINES="$DEFINES -DUNALIGNED_PROFITABLE" - if [[ "x$HAVE_GAS" = "xyes" ]]; then - ASM_OPTIMIZATIONS="x86-64" - DEFINES="$DEFINES -DX86_64_ASSEMBLY -DOPTIMIZED_FLAGS" - JITSRCS="cpuemu1_nf.cpp cpuemu2_nf.cpp cpuemu3_nf.cpp cpuemu4_nf.cpp cpuemu5_nf.cpp cpuemu6_nf.cpp cpuemu7_nf.cpp cpuemu8_nf.cpp $JITSRCS" - CAN_JIT=yes - fi -elif [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_SPARC" = "xyes" -a "x$HAVE_GAS" = "xyes" ]]; then - dnl SPARC CPU - case "$target_os" in - solaris*) - AC_MSG_CHECKING(SPARC CPU architecture) - SPARC_TYPE=`Solaris/which_sparc` - AC_MSG_RESULT($SPARC_TYPE) - case "$SPARC_TYPE" in - SPARC_V8) - ASM_OPTIMIZATIONS="SPARC V8 architecture" - DEFINES="$DEFINES -DSPARC_V8_ASSEMBLY" dnl -DOPTIMIZED_FLAGS" - CFLAGS="$CFLAGS -Wa,-Av8" - CXXFLAGS="$CXXFLAGS -Wa,-Av8" - ;; - SPARC_V9) - ASM_OPTIMIZATIONS="SPARC V9 architecture" - DEFINES="$DEFINES -DSPARC_V9_ASSEMBLY" dnl -DOPTIMIZED_FLAGS" - CFLAGS="$CFLAGS -Wa,-Av9" - CXXFLAGS="$CXXFLAGS -Wa,-Av9" - ;; - esac - ;; - esac -elif [[ "x$WANT_NATIVE_M68K" = "xyes" ]]; then - dnl Native m68k, no emulation - CPUINCLUDES="-I../native_cpu" - CPUSRCS="asm_support.s" -fi - -dnl Enable JIT compiler, if possible. -if [[ "x$WANT_JIT" = "xyes" -a "x$CAN_JIT" ]]; then - JITSRCS="$JITSRCS ../uae_cpu/compiler/compemu_support.cpp ../uae_cpu/compiler/compemu_fpp.cpp compstbl.o cpustbl_nf.o" - DEFINES="$DEFINES -DUSE_JIT -DUSE_JIT_FPU" - - if [[ "x$WANT_JIT_DEBUG" = "xyes" ]]; then - if [[ "x$WANT_MON" = "xyes" ]]; then - DEFINES="$DEFINES -DJIT_DEBUG=1" - else - AC_MSG_WARN([cxmon not found, ignoring --enable-jit-debug]) - WANT_JIT_DEBUG=no - fi - fi - - dnl IEEE core is the only FPU emulator to use with the JIT compiler - case $FPE_CORE_TEST_ORDER in - ieee*) ;; - *) AC_MSG_WARN([Forcing use of the IEEE FPU core, as the JIT compiler supports only this one.]) ;; - esac - FPE_CORE_TEST_ORDER="ieee" -else - WANT_JIT=no - WANT_JIT_DEBUG=no - JITSRCS="" -fi - -dnl Utility macro used by next two tests. -dnl AC_EXAMINE_OBJECT(C source code, -dnl commands examining object file, -dnl [commands to run if compile failed]): -dnl -dnl Compile the source code to an object file; then convert it into a -dnl printable representation. All unprintable characters and -dnl asterisks (*) are replaced by dots (.). All white space is -dnl deleted. Newlines (ASCII 0x10) in the input are preserved in the -dnl output, but runs of newlines are compressed to a single newline. -dnl Finally, line breaks are forcibly inserted so that no line is -dnl longer than 80 columns and the file ends with a newline. The -dnl result of all this processing is in the file conftest.dmp, which -dnl may be examined by the commands in the second argument. -dnl -AC_DEFUN([gcc_AC_EXAMINE_OBJECT], -[AC_LANG_SAVE -AC_LANG_C -dnl Next bit cribbed from AC_TRY_COMPILE. -cat > conftest.$ac_ext < conftest.dmp - $2 -ifelse($3, , , else - $3 -)dnl -fi -rm -rf conftest* -AC_LANG_RESTORE]) - -dnl Floating point format probe. -dnl The basic concept is the same as the above: grep the object -dnl file for an interesting string. We have to watch out for -dnl rounding changing the values in the object, however; this is -dnl handled by ignoring the least significant byte of the float. -dnl -dnl Does not know about VAX G-float or C4x idiosyncratic format. -dnl It does know about PDP-10 idiosyncratic format, but this is -dnl not presently supported by GCC. S/390 "binary floating point" -dnl is in fact IEEE (but maybe we should have that in EBCDIC as well -dnl as ASCII?) -dnl -AC_DEFUN([gcc_AC_C_FLOAT_FORMAT], -[AC_CACHE_CHECK(floating point format, ac_cv_c_float_format, -[gcc_AC_EXAMINE_OBJECT( -[/* This will not work unless sizeof(double) == 8. */ -extern char sizeof_double_must_be_8 [sizeof(double) == 8 ? 1 : -1]; - -/* This structure must have no internal padding. */ -struct possibility { - char prefix[8]; - double candidate; - char postfix[8]; -}; - -#define C(cand) { "\nformat:", cand, ":tamrof\n" } -struct possibility table [] = -{ - C( 3.25724264705901305206e+01), /* @@IEEEFP - IEEE 754 */ - C( 3.53802595280598432000e+18), /* D__float - VAX */ - C( 5.32201830133125317057e-19), /* D.PDP-10 - PDP-10 - the dot is 0x13a */ - C( 1.77977764695171661377e+10), /* IBMHEXFP - s/390 format, ascii */ - C(-5.22995989424860458374e+10) /* IBMHEXFP - s/390 format, EBCDIC */ -};], - [if grep 'format:.@IEEEF.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='IEEE (big-endian)' - elif grep 'format:.I@@PFE.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='IEEE (big-endian)' - elif grep 'format:.FEEEI@.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='IEEE (little-endian)' - elif grep 'format:.EFP@@I.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='IEEE (little-endian)' - elif grep 'format:.__floa.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='VAX D-float' - elif grep 'format:..PDP-1.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='PDP-10' - elif grep 'format:.BMHEXF.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='IBM 370 hex' - else - AC_MSG_ERROR(Unknown floating point format) - fi], - [AC_MSG_ERROR(compile failed)]) -]) -# IEEE is the default format. If the float endianness isn't the same -# as the integer endianness, we have to set FLOAT_WORDS_BIG_ENDIAN -# (which is a tristate: yes, no, default). This is only an issue with -# IEEE; the other formats are only supported by a few machines each, -# all with the same endianness. -format=IEEE_FLOAT_FORMAT -fbigend= -case $ac_cv_c_float_format in - 'IEEE (big-endian)' ) - if test $ac_cv_c_bigendian = no; then - fbigend=1 - fi - ;; - 'IEEE (little-endian)' ) - if test $ac_cv_c_bigendian = yes; then - fbigend=0 - fi - ;; - 'VAX D-float' ) - format=VAX_FLOAT_FORMAT - ;; - 'PDP-10' ) - format=PDP10_FLOAT_FORMAT - ;; - 'IBM 370 hex' ) - format=IBM_FLOAT_FORMAT - ;; -esac -AC_DEFINE_UNQUOTED(HOST_FLOAT_FORMAT, $format, - [Define to the floating point format of the host machine.]) -if test -n "$fbigend"; then - AC_DEFINE_UNQUOTED(HOST_FLOAT_WORDS_BIG_ENDIAN, $fbigend, - [Define to 1 if the host machine stores floating point numbers in - memory with the word containing the sign bit at the lowest address, - or to 0 if it does it the other way around. - - This macro should not be defined if the ordering is the same as for - multi-word integers.]) -fi -]) +CPUSRCS="cpuemu.cpp" dnl Select appropriate FPU source. -gcc_AC_C_FLOAT_FORMAT AC_CHECK_HEADERS(ieee754.h ieeefp.h floatingpoint.h nan.h) for fpe in $FPE_CORE_TEST_ORDER; do case $fpe in - ieee) - case $ac_cv_c_float_format in - IEEE*) - FPE_CORE="IEEE fpu core" - DEFINES="$DEFINES -DFPU_IEEE" - FPUSRCS="../uae_cpu/fpu/fpu_ieee.cpp" - dnl Math functions not mandated by C99 standard - AC_CHECK_FUNCS(isnanl isinfl) - dnl Math functions required by C99 standard, but probably not - dnl implemented everywhere. In that case, we fall back to the - dnl regular variant for doubles. - AC_CHECK_FUNCS(logl log10l expl powl fabsl sqrtl) - AC_CHECK_FUNCS(sinl cosl tanl sinhl coshl tanhl) - AC_CHECK_FUNCS(asinl acosl atanl asinhl acoshl atanhl) - AC_CHECK_FUNCS(floorl ceill) - break - ;; - esac - ;; - x86) - if [[ ":$HAVE_GCC27:$HAVE_I386:$HAVE_GAS:" = ":yes:yes:yes:" ]]; then - FPE_CORE="i387 fpu core" - DEFINES="$DEFINES -DFPU_X86" - FPUSRCS="../uae_cpu/fpu/fpu_x86.cpp" - break - fi - ;; uae) FPE_CORE="uae fpu core" DEFINES="$DEFINES -DFPU_UAE" @@ -1731,18 +927,8 @@ AC_CHECK_FUNCS(atanh) AC_CHECK_FUNCS(isnan isinf finite isnormal signbit) dnl UAE CPU sources for all non-m68k-native architectures. -if [[ "x$WANT_NATIVE_M68K" = "xno" ]]; then - CPUINCLUDES="-I../uae_cpu" - CPUSRCS="../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp ../uae_cpu/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS $JITSRCS" -fi - -dnl Or if we have -IPA (MIPSPro compilers) -if [[ "x$HAVE_IPA" = "xyes" ]]; then - CFLAGS="`echo $CFLAGS | sed -e 's/-g//g'` -O3 -OPT:Olimit=0 -IPA" - CXXFLAGS="`echo $CXXFLAGS | sed -e 's/-g//g'` -O3 -OPT:Olimit=0 -IPA" - CXXFLAGS="-LANG:std $CXXFLAGS" - LDFLAGS="$LDFLAGS -O3 -OPT:Olimit=0 -IPA" -fi +CPUINCLUDES="-I../uae_cpu" +CPUSRCS="../uae_cpu/basilisk_glue.cpp ../uae_cpu/newcpu.cpp ../uae_cpu/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS" dnl Generate Makefile. AC_SUBST(DEFINES) @@ -1758,23 +944,9 @@ dnl Print summary. echo echo Basilisk II configuration summary: echo -echo Mac OS X GUI ........................... : $WANT_MACOSX_GUI -echo Mac OS X Sound ......................... : $WANT_MACOSX_SOUND echo SDL support ............................ : $SDL_SUPPORT -echo BINCUE support ......................... : $have_bincue -echo LIBVHD support ......................... : $have_libvhd -echo XFree86 DGA support .................... : $WANT_XF86_DGA -echo XFree86 VidMode support ................ : $WANT_XF86_VIDMODE -echo fbdev DGA support ...................... : $WANT_FBDEV_DGA echo Enable video on SEGV signals ........... : $WANT_VOSF -echo ESD sound support ...................... : $WANT_ESD -echo GTK user interface ..................... : $WANT_GTK -echo mon debugger support ................... : $WANT_MON -echo Running m68k code natively ............. : $WANT_NATIVE_M68K -echo Use JIT compiler ....................... : $WANT_JIT -echo JIT debug mode ......................... : $WANT_JIT_DEBUG echo Floating-Point emulation core .......... : $FPE_CORE -echo Assembly optimizations ................. : $ASM_OPTIMIZATIONS echo Addressing mode ........................ : $ADDRESSING_MODE echo Bad memory access recovery type ........ : $sigsegv_recovery echo diff --git a/BasiliskII/src/Unix/disk_sparsebundle.cpp b/BasiliskII/src/Unix/disk_sparsebundle.cpp deleted file mode 100644 index 063e3296..00000000 --- a/BasiliskII/src/Unix/disk_sparsebundle.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/* - * disk_sparsebundle.cpp - Apple sparse bundle implementation - * - * Basilisk II (C) Dave Vasilevsky - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "disk_unix.h" -#include "tinyxml2.h" - -#include -#include -#include - -#if defined __APPLE__ && defined __MACH__ -#define __MACOSX__ 1 -#endif - -struct disk_sparsebundle : disk_generic { - disk_sparsebundle(const char *bands, int fd, bool read_only, - loff_t band_size, loff_t total_size) - : token_fd(fd), read_only(read_only), band_size(band_size), - total_size(total_size), band_dir(strdup(bands)), - band_cur(-1), band_fd(-1), band_alloc(-1) { - } - - virtual ~disk_sparsebundle() { - if (band_fd != -1) - close(band_fd); - close(token_fd); - free(band_dir); - } - - virtual bool is_read_only() { return read_only; } - virtual loff_t size() { return total_size; } - - virtual size_t read(void *buf, loff_t offset, size_t length) { - return band_do(&disk_sparsebundle::band_read, buf, offset, length); - } - - virtual size_t write(void *buf, loff_t offset, size_t length) { - return band_do(&disk_sparsebundle::band_write, buf, offset, length); - } - -protected: - int token_fd; // lockfile - bool read_only; - loff_t band_size, total_size; - char *band_dir; // directory containing band files - - // Currently open band - loff_t band_cur; // index of the band - int band_fd; // -1 if not open - loff_t band_alloc; // how much space is already used? - - typedef ssize_t (disk_sparsebundle::*band_func)(char *buf, loff_t band, - size_t offset, size_t len); - - // Split an (offset, length) operation into bands. - size_t band_do(band_func func, void *buf, loff_t offset, size_t length) { - char *b = (char*)buf; - loff_t band = offset / band_size; - size_t done = 0; - while (length) { - if (offset >= total_size) - break; - size_t start = offset % band_size; - size_t segment = std::min((size_t)band_size - start, length); - - ssize_t err = (this->*func)(b, band, start, segment); - if (err > 0) - done += err; - if (err < segment) - break; - - b += segment; - offset += segment; - length -= segment; - ++band; - } - return done; - } - - // Open a band by index. It's ok if the band is already open. - enum open_ret { - OPEN_FAILED = 0, - OPEN_NOENT, // Band doesn't exist yet - OPEN_OK, - }; - open_ret open_band(loff_t band, bool create) { - if (band_cur == band) - return OPEN_OK; - - char path[PATH_MAX + 1]; - if (snprintf(path, PATH_MAX, "%s/%lx", band_dir, - (unsigned long)band) >= PATH_MAX) { - return OPEN_FAILED; - } - - if (band_fd != -1) - close(band_fd); - band_alloc = -1; - band_cur = -1; - - int oflags = read_only ? O_RDONLY : O_RDWR; - if (create) - oflags |= O_CREAT; - band_fd = open(path, oflags, 0644); - if (band_fd == -1) { - return (!create && errno == ENOENT) ? OPEN_NOENT : OPEN_FAILED; - } - - // Get the allocated size - if (!read_only) { - band_alloc = lseek(band_fd, 0, SEEK_END); - if (band_alloc == -1) - band_alloc = band_size; - } - band_cur = band; - return OPEN_OK; - } - - ssize_t band_read(char *buf, loff_t band, size_t off, size_t len) { - open_ret st = open_band(band, false); - if (st == OPEN_FAILED) - return -1; - - // Unallocated bytes - size_t want = (st == OPEN_NOENT || off >= band_alloc) ? 0 - : std::min(len, (size_t)band_alloc - off); - if (want) { - if (lseek(band_fd, off, SEEK_SET) == -1) - return -1; - ssize_t err = ::read(band_fd, buf, want); - if (err < want) - return err; - } - memset(buf + want, 0, len - want); - return len; - } - - ssize_t band_write(char *buf, loff_t band, size_t off, size_t len) { - // If space is unused, don't needlessly fill it with zeros - - // Find min length such that all trailing chars are zero: - size_t nz = len; - for (; nz > 0 && !buf[nz-1]; --nz) - ; // pass - - open_ret st = open_band(band, nz); - if (st != OPEN_OK) - return st == OPEN_NOENT ? len : -1; - - if (lseek(band_fd, off, SEEK_SET) == -1) - return -1; - - size_t space = (off >= band_alloc ? 0 : band_alloc - off); - size_t want = std::max(nz, std::min(space, len)); - ssize_t err = ::write(band_fd, buf, want); - if (err >= 0) - band_alloc = std::max(band_alloc, loff_t(off + err)); - if (err < want) - return err; - return len; - } -}; - - - -using tinyxml2::XML_NO_ERROR; -using tinyxml2::XMLElement; - -// Simplistic plist parser -struct plist { - plist() : doc(true, tinyxml2::COLLAPSE_WHITESPACE) { } - - bool open(const char *path) { - if (doc.LoadFile(path) != XML_NO_ERROR) - return false; - tinyxml2::XMLHandle hnd(&doc); - dict = hnd.FirstChildElement("plist").FirstChildElement("dict") - .ToElement(); - return dict; - } - - const char *str_val(const char *key) { - return value(key, "string"); - } - - bool int_val(const char *key, loff_t *i) { - const char *v = value(key, "integer"); - if (!v || !*v) - return false; - - char *endp; - long long ll = strtoll(v, &endp, 10); - if (*endp) - return false; - *i = ll; - return true; - } - -protected: - tinyxml2::XMLDocument doc; - XMLElement *dict; - - const char *value(const char *key, const char *type) { - // Assume it's a flat plist - XMLElement *cur = dict->FirstChildElement(); - bool found_key = false; - while (cur) { - if (found_key) { - if (strcmp(cur->Name(), type) != 0) - return NULL; - return cur->GetText(); - } - found_key = strcmp(cur->Name(), "key") == 0 - && strcmp(cur->GetText(), key) == 0; - cur = cur->NextSiblingElement(); - } - return NULL; - } -}; - - -static int try_open(const char *path, bool read_only, bool *locked) { - int oflags = (read_only ? O_RDONLY : O_RDWR); - int lockflags = 0; -#if defined(__MACOSX__) - lockflags = O_NONBLOCK | (read_only ? O_SHLOCK : O_EXLOCK); -#endif - int fd = open(path, oflags | lockflags); -#if defined(__MACOSX__) - if (fd == -1) { - if (errno == EOPNOTSUPP) { // no locking support, try again - fd = open(path, oflags); - } else if (errno == EAGAIN) { // locked - *locked = true; - } - } -#endif - return fd; -} - -disk_generic::status disk_sparsebundle_factory(const char *path, - bool read_only, disk_generic **disk) { - // Does it look like a sparsebundle? - char buf[PATH_MAX + 1]; - if (snprintf(buf, PATH_MAX, "%s/%s", path, "Info.plist") >= PATH_MAX) - return disk_generic::DISK_UNKNOWN; - - plist pl; - if (!pl.open(buf)) - return disk_generic::DISK_UNKNOWN; - - const char *type; - if (!(type = pl.str_val("diskimage-bundle-type"))) - return disk_generic::DISK_UNKNOWN; - if (strcmp(type, "com.apple.diskimage.sparsebundle") != 0) - return disk_generic::DISK_UNKNOWN; - - - // Find the sparsebundle parameters - loff_t version, band_size, total_size; - if (!pl.int_val("bundle-backingstore-version", &version) || version != 1) { - fprintf(stderr, "sparsebundle: Bad version\n"); - return disk_generic::DISK_UNKNOWN; - } - if (!pl.int_val("band-size", &band_size) - || !pl.int_val("size", &total_size)) { - fprintf(stderr, "sparsebundle: Can't find size\n"); - return disk_generic::DISK_INVALID; - } - - - // Check if we can open it - if (snprintf(buf, PATH_MAX, "%s/%s", path, "token") >= PATH_MAX) - return disk_generic::DISK_INVALID; - bool locked = false; - int token = try_open(buf, read_only, &locked); - if (token == -1 && !read_only) { // try again, read-only - token = try_open(buf, true, &locked); - if (token != -1 && !read_only) - fprintf(stderr, "sparsebundle: Can only mount read-only\n"); - read_only = true; - } - if (token == -1) { - if (locked) - fprintf(stderr, "sparsebundle: Refusing to double-mount\n"); - else - perror("sparsebundle: open failed:"); - return disk_generic::DISK_INVALID; - } - - - // We're good to go! - if (snprintf(buf, PATH_MAX, "%s/%s", path, "bands") >= PATH_MAX) - return disk_generic::DISK_INVALID; - *disk = new disk_sparsebundle(buf, token, read_only, band_size, - total_size); - return disk_generic::DISK_VALID; -} diff --git a/BasiliskII/src/Unix/disk_unix.h b/BasiliskII/src/Unix/disk_unix.h index 6c427881..042c90ef 100644 --- a/BasiliskII/src/Unix/disk_unix.h +++ b/BasiliskII/src/Unix/disk_unix.h @@ -42,7 +42,4 @@ struct disk_generic { typedef disk_generic::status (disk_factory)(const char *path, bool read_only, disk_generic **disk); -extern disk_factory disk_sparsebundle_factory; -extern disk_factory disk_vhd_factory; - #endif diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp deleted file mode 100644 index 526ee29c..00000000 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ /dev/null @@ -1,1051 +0,0 @@ -/* - * ether_unix.cpp - Ethernet device driver, Unix specific stuff (Linux and FreeBSD) - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -/* - * NOTES concerning MacOS X issues: - * - poll() does not exist in 10.2.8, but is available in 10.4.4 - * - select(), and very likely poll(), are not cancellation points. So - * the ethernet thread doesn't stop on exit. An explicit check is - * performed to workaround this problem. - */ -#if (defined __APPLE__ && defined __MACH__) || ! defined HAVE_POLL -#define USE_POLL 0 -#else -#define USE_POLL 1 -#endif - -// Define to let the slirp library determine the right timeout for select() -#define USE_SLIRP_TIMEOUT 1 - -#ifdef HAVE_SYS_POLL_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__FreeBSD__) || defined(sgi) || (defined(__APPLE__) && defined(__MACH__)) -#include -#endif - -#if defined(HAVE_LINUX_IF_H) && defined(HAVE_LINUX_IF_TUN_H) -#include -#include -#endif - -#if defined(HAVE_NET_IF_H) && defined(HAVE_NET_IF_TUN_H) -#include -#include -#endif - -#ifdef HAVE_SLIRP -#include "libslirp.h" -#include "ctl.h" -#endif - -#include "cpu_emulation.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "ether.h" -#include "ether_defs.h" - -#ifndef NO_STD_NAMESPACE -using std::map; -#endif - -#define DEBUG 0 -#include "debug.h" - -#define STATISTICS 0 -#define MONITOR 0 - - -// Ethernet device types -enum { - NET_IF_SHEEPNET, - NET_IF_ETHERTAP, - NET_IF_TUNTAP, - NET_IF_SLIRP -}; - -// Constants -#if ENABLE_TUNTAP -static const char ETHERCONFIG_FILE_NAME[] = DATADIR "/tunconfig"; -#endif - -// Global variables -static int fd = -1; // fd of sheep_net device -static pthread_t ether_thread; // Packet reception thread -static pthread_attr_t ether_thread_attr; // Packet reception thread attributes -static bool thread_active = false; // Flag: Packet reception thread installed -static sem_t int_ack; // Interrupt acknowledge semaphore -static bool udp_tunnel; // Flag: UDP tunnelling active, fd is the socket descriptor -static int net_if_type = -1; // Ethernet device type -static char *net_if_name = NULL; // TUN/TAP device name -static const char *net_if_script = NULL; // Network config script -static pthread_t slirp_thread; // Slirp reception thread -static bool slirp_thread_active = false; // Flag: Slirp reception threadinstalled -static int slirp_output_fd = -1; // fd of slirp output pipe -static int slirp_input_fds[2] = { -1, -1 }; // fds of slirp input pipe -#ifdef SHEEPSHAVER -static bool net_open = false; // Flag: initialization succeeded, network device open -static uint8 ether_addr[6]; // Our Ethernet address -#else -const bool ether_driver_opened = true; // Flag: is the MacOS driver opened? -#endif - -// Attached network protocols, maps protocol type to MacOS handler address -static map net_protocols; - -// Prototypes -static void *receive_func(void *arg); -static void *slirp_receive_func(void *arg); -static int16 ether_do_add_multicast(uint8 *addr); -static int16 ether_do_del_multicast(uint8 *addr); -static int16 ether_do_write(uint32 arg); -static void ether_do_interrupt(void); -static void slirp_add_redirs(); -static int slirp_add_redir(const char *redir_str); - - -/* - * Start packet reception thread - */ - -static bool start_thread(void) -{ - if (sem_init(&int_ack, 0, 0) < 0) { - printf("WARNING: Cannot init semaphore"); - return false; - } - - Set_pthread_attr(ðer_thread_attr, 1); - thread_active = (pthread_create(ðer_thread, ðer_thread_attr, receive_func, NULL) == 0); - if (!thread_active) { - printf("WARNING: Cannot start Ethernet thread"); - return false; - } - -#ifdef HAVE_SLIRP - if (net_if_type == NET_IF_SLIRP) { - slirp_thread_active = (pthread_create(&slirp_thread, NULL, slirp_receive_func, NULL) == 0); - if (!slirp_thread_active) { - printf("WARNING: Cannot start slirp reception thread\n"); - return false; - } - } -#endif - - return true; -} - - -/* - * Stop packet reception thread - */ - -static void stop_thread(void) -{ -#ifdef HAVE_SLIRP - if (slirp_thread_active) { -#ifdef HAVE_PTHREAD_CANCEL - pthread_cancel(slirp_thread); -#endif - pthread_join(slirp_thread, NULL); - slirp_thread_active = false; - } -#endif - - if (thread_active) { -#ifdef HAVE_PTHREAD_CANCEL - pthread_cancel(ether_thread); -#endif - pthread_join(ether_thread, NULL); - sem_destroy(&int_ack); - thread_active = false; - } -} - - -/* - * Execute network script up|down - */ - -static bool execute_network_script(const char *action) -{ - if (net_if_script == NULL || net_if_name == NULL) - return false; - - int pid = fork(); - if (pid >= 0) { - if (pid == 0) { - char *args[4]; - args[0] = (char *)net_if_script; - args[1] = net_if_name; - args[2] = (char *)action; - args[3] = NULL; - execv(net_if_script, args); - exit(1); - } - int status; - while (waitpid(pid, &status, 0) != pid); - return WIFEXITED(status) && WEXITSTATUS(status) == 0; - } - - return false; -} - - -/* - * Initialization - */ - -bool ether_init(void) -{ - int val; - char str[256]; - - // Do nothing if no Ethernet device specified - const char *name = PrefsFindString("ether"); - if (name == NULL) - return false; - - // Determine Ethernet device type - net_if_type = -1; - if (strncmp(name, "tap", 3) == 0) - net_if_type = NET_IF_ETHERTAP; -#if ENABLE_TUNTAP - else if (strcmp(name, "tun") == 0) - net_if_type = NET_IF_TUNTAP; -#endif -#ifdef HAVE_SLIRP - else if (strcmp(name, "slirp") == 0) - net_if_type = NET_IF_SLIRP; -#endif - else - net_if_type = NET_IF_SHEEPNET; - - // Don't raise SIGPIPE, let errno be set to EPIPE - struct sigaction sigpipe_sa; - if (sigaction(SIGPIPE, NULL, &sigpipe_sa) == 0) { - assert(sigpipe_sa.sa_handler == SIG_DFL || sigpipe_sa.sa_handler == SIG_IGN); - sigfillset(&sigpipe_sa.sa_mask); - sigpipe_sa.sa_flags = 0; - sigpipe_sa.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &sigpipe_sa, NULL); - } - -#ifdef HAVE_SLIRP - // Initialize slirp library - if (net_if_type == NET_IF_SLIRP) { - if (slirp_init() < 0) { - sprintf(str, "%s", GetString(STR_SLIRP_NO_DNS_FOUND_WARN)); - WarningAlert(str); - return false; - } - - // Open slirp output pipe - int fds[2]; - if (pipe(fds) < 0) - return false; - fd = fds[0]; - slirp_output_fd = fds[1]; - - // Open slirp input pipe - if (pipe(slirp_input_fds) < 0) - return false; - - // Set up port redirects - slirp_add_redirs(); - } -#endif - - // Open sheep_net or ethertap or TUN/TAP device - char dev_name[16]; - switch (net_if_type) { - case NET_IF_ETHERTAP: - sprintf(dev_name, "/dev/%s", name); - break; - case NET_IF_TUNTAP: - strcpy(dev_name, "/dev/net/tun"); - break; - case NET_IF_SHEEPNET: - strcpy(dev_name, "/dev/sheep_net"); - break; - } - if (net_if_type != NET_IF_SLIRP) { - fd = open(dev_name, O_RDWR); - if (fd < 0) { - sprintf(str, GetString(STR_NO_SHEEP_NET_DRIVER_WARN), dev_name, strerror(errno)); - WarningAlert(str); - goto open_error; - } - } - -#if ENABLE_TUNTAP - // Open TUN/TAP interface - if (net_if_type == NET_IF_TUNTAP) { - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - strcpy(ifr.ifr_name, "tun%d"); - if (ioctl(fd, TUNSETIFF, (void *) &ifr) != 0) { - sprintf(str, GetString(STR_SHEEP_NET_ATTACH_WARN), strerror(errno)); - WarningAlert(str); - goto open_error; - } - - // Get network config script file path - net_if_script = PrefsFindString("etherconfig"); - if (net_if_script == NULL) - net_if_script = ETHERCONFIG_FILE_NAME; - - // Start network script up - if (net_if_script == NULL) { - sprintf(str, GetString(STR_TUN_TAP_CONFIG_WARN), "script not found"); - WarningAlert(str); - goto open_error; - } - net_if_name = strdup(ifr.ifr_name); - if (!execute_network_script("up")) { - sprintf(str, GetString(STR_TUN_TAP_CONFIG_WARN), "script execute error"); - WarningAlert(str); - goto open_error; - } - D(bug("Connected to host network interface: %s\n", net_if_name)); - } -#endif - -#if defined(__linux__) - // Attach sheep_net to selected Ethernet card - if (net_if_type == NET_IF_SHEEPNET && ioctl(fd, SIOCSIFLINK, name) < 0) { - sprintf(str, GetString(STR_SHEEP_NET_ATTACH_WARN), strerror(errno)); - WarningAlert(str); - goto open_error; - } -#endif - - // Set nonblocking I/O -#ifdef USE_FIONBIO - int nonblock = 1; - if (ioctl(fd, FIONBIO, &nonblock) < 0) { - sprintf(str, GetString(STR_BLOCKING_NET_SOCKET_WARN), strerror(errno)); - WarningAlert(str); - goto open_error; - } -#else - val = fcntl(fd, F_GETFL, 0); - if (val < 0 || fcntl(fd, F_SETFL, val | O_NONBLOCK) < 0) { - sprintf(str, GetString(STR_BLOCKING_NET_SOCKET_WARN), strerror(errno)); - WarningAlert(str); - goto open_error; - } -#endif - - // Get Ethernet address - if (net_if_type == NET_IF_ETHERTAP) { - pid_t p = getpid(); // If configured for multicast, ethertap requires that the lower 32 bit of the Ethernet address are our PID - ether_addr[0] = 0xfe; - ether_addr[1] = 0xfd; - ether_addr[2] = p >> 24; - ether_addr[3] = p >> 16; - ether_addr[4] = p >> 8; - ether_addr[5] = p; -#ifdef HAVE_SLIRP - } else if (net_if_type == NET_IF_SLIRP) { - ether_addr[0] = 0x52; - ether_addr[1] = 0x54; - ether_addr[2] = 0x00; - ether_addr[3] = 0x12; - ether_addr[4] = 0x34; - ether_addr[5] = 0x56; -#endif - } else - ioctl(fd, SIOCGIFADDR, ether_addr); - D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); - - // Start packet reception thread - if (!start_thread()) - goto open_error; - - // Everything OK - return true; - -open_error: - stop_thread(); - - if (fd > 0) { - close(fd); - fd = -1; - } - if (slirp_input_fds[0] >= 0) { - close(slirp_input_fds[0]); - slirp_input_fds[0] = -1; - } - if (slirp_input_fds[1] >= 0) { - close(slirp_input_fds[1]); - slirp_input_fds[1] = -1; - } - if (slirp_output_fd >= 0) { - close(slirp_output_fd); - slirp_output_fd = -1; - } - return false; -} - - -/* - * Deinitialization - */ - -void ether_exit(void) -{ - // Stop reception threads - stop_thread(); - - // Shut down TUN/TAP interface - if (net_if_type == NET_IF_TUNTAP) - execute_network_script("down"); - - // Free TUN/TAP device name - if (net_if_name) - free(net_if_name); - - // Close sheep_net device - if (fd > 0) - close(fd); - - // Close slirp input buffer - if (slirp_input_fds[0] >= 0) - close(slirp_input_fds[0]); - if (slirp_input_fds[1] >= 0) - close(slirp_input_fds[1]); - - // Close slirp output buffer - if (slirp_output_fd > 0) - close(slirp_output_fd); - -#if STATISTICS - // Show statistics - printf("%ld messages put on write queue\n", num_wput); - printf("%ld error acks\n", num_error_acks); - printf("%ld packets transmitted (%ld raw, %ld normal)\n", num_tx_packets, num_tx_raw_packets, num_tx_normal_packets); - printf("%ld tx packets dropped because buffer full\n", num_tx_buffer_full); - printf("%ld packets received\n", num_rx_packets); - printf("%ld packets passed upstream (%ld Fast Path, %ld normal)\n", num_rx_fastpath + num_unitdata_ind, num_rx_fastpath, num_unitdata_ind); - printf("EtherIRQ called %ld times\n", num_ether_irq); - printf("%ld rx packets dropped due to low memory\n", num_rx_no_mem); - printf("%ld rx packets dropped because no stream found\n", num_rx_dropped); - printf("%ld rx packets dropped because stream not ready\n", num_rx_stream_not_ready); - printf("%ld rx packets dropped because no memory for unitdata_ind\n", num_rx_no_unitdata_mem); -#endif -} - - -/* - * Glue around low-level implementation - */ - -#ifdef SHEEPSHAVER -// Error codes -enum { - eMultiErr = -91, - eLenErr = -92, - lapProtErr = -94, - excessCollsns = -95 -}; - -// Initialize ethernet -void EtherInit(void) -{ - net_open = false; - - // Do nothing if the user disabled the network - if (PrefsFindBool("nonet")) - return; - - net_open = ether_init(); -} - -// Exit ethernet -void EtherExit(void) -{ - ether_exit(); - net_open = false; -} - -// Get ethernet hardware address -void AO_get_ethernet_address(uint32 arg) -{ - uint8 *addr = Mac2HostAddr(arg); - if (net_open) - OTCopy48BitAddress(ether_addr, addr); - else { - addr[0] = 0x12; - addr[1] = 0x34; - addr[2] = 0x56; - addr[3] = 0x78; - addr[4] = 0x9a; - addr[5] = 0xbc; - } - D(bug("AO_get_ethernet_address: got address %02x%02x%02x%02x%02x%02x\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5])); -} - -// Add multicast address -void AO_enable_multicast(uint32 addr) -{ - if (net_open) - ether_do_add_multicast(Mac2HostAddr(addr)); -} - -// Disable multicast address -void AO_disable_multicast(uint32 addr) -{ - if (net_open) - ether_do_del_multicast(Mac2HostAddr(addr)); -} - -// Transmit one packet -void AO_transmit_packet(uint32 mp) -{ - if (net_open) { - switch (ether_do_write(mp)) { - case noErr: - num_tx_packets++; - break; - case excessCollsns: - num_tx_buffer_full++; - break; - } - } -} - -// Copy packet data from message block to linear buffer -static inline int ether_arg_to_buffer(uint32 mp, uint8 *p) -{ - return ether_msgb_to_buffer(mp, p); -} - -// Ethernet interrupt -void EtherIRQ(void) -{ - D(bug("EtherIRQ\n")); - num_ether_irq++; - - OTEnterInterrupt(); - ether_do_interrupt(); - OTLeaveInterrupt(); - - // Acknowledge interrupt to reception thread - D(bug(" EtherIRQ done\n")); - sem_post(&int_ack); -} -#else -// Add multicast address -int16 ether_add_multicast(uint32 pb) -{ - return ether_do_add_multicast(Mac2HostAddr(pb + eMultiAddr)); -} - -// Disable multicast address -int16 ether_del_multicast(uint32 pb) -{ - return ether_do_del_multicast(Mac2HostAddr(pb + eMultiAddr)); -} - -// Transmit one packet -int16 ether_write(uint32 wds) -{ - return ether_do_write(wds); -} - -// Copy packet data from WDS to linear buffer -static inline int ether_arg_to_buffer(uint32 wds, uint8 *p) -{ - return ether_wds_to_buffer(wds, p); -} - -// Dispatch packet to protocol handler -static void ether_dispatch_packet(uint32 p, uint32 length) -{ - // Get packet type - uint16 type = ReadMacInt16(p + 12); - - // Look for protocol - uint16 search_type = (type <= 1500 ? 0 : type); - if (net_protocols.find(search_type) == net_protocols.end()) - return; - uint32 handler = net_protocols[search_type]; - - // No default handler - if (handler == 0) - return; - - // Copy header to RHA - Mac2Mac_memcpy(ether_data + ed_RHA, p, 14); - D(bug(" header %08x%04x %08x%04x %04x\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12))); - - // Call protocol handler - M68kRegisters r; - r.d[0] = type; // Packet type - r.d[1] = length - 14; // Remaining packet length (without header, for ReadPacket) - r.a[0] = p + 14; // Pointer to packet (Mac address, for ReadPacket) - r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA - r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines - D(bug(" calling protocol handler %08x, type %08x, length %08x, data %08x, rha %08x, read_packet %08x\n", handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4])); - Execute68k(handler, &r); -} - -// Ethernet interrupt -void EtherInterrupt(void) -{ - D(bug("EtherIRQ\n")); - ether_do_interrupt(); - - // Acknowledge interrupt to reception thread - D(bug(" EtherIRQ done\n")); - sem_post(&int_ack); -} -#endif - - -/* - * Reset - */ - -void ether_reset(void) -{ - net_protocols.clear(); -} - - -/* - * Add multicast address - */ - -static int16 ether_do_add_multicast(uint8 *addr) -{ - switch (net_if_type) { - case NET_IF_ETHERTAP: - case NET_IF_SHEEPNET: - if (ioctl(fd, SIOCADDMULTI, addr) < 0) { - D(bug("WARNING: Couldn't enable multicast address\n")); - if (net_if_type == NET_IF_ETHERTAP) { - return noErr; - } else { - return eMultiErr; - } - } - return noErr; - default: - return noErr; - } -} - - -/* - * Delete multicast address - */ - -static int16 ether_do_del_multicast(uint8 *addr) -{ - switch (net_if_type) { - case NET_IF_ETHERTAP: - case NET_IF_SHEEPNET: - if (ioctl(fd, SIOCDELMULTI, addr) < 0) { - D(bug("WARNING: Couldn't disable multicast address\n")); - return eMultiErr; - } - return noErr; - default: - return noErr; - } -} - - -/* - * Attach protocol handler - */ - -int16 ether_attach_ph(uint16 type, uint32 handler) -{ - if (net_protocols.find(type) != net_protocols.end()) - return lapProtErr; - net_protocols[type] = handler; - return noErr; -} - - -/* - * Detach protocol handler - */ - -int16 ether_detach_ph(uint16 type) -{ - if (net_protocols.erase(type) == 0) - return lapProtErr; - return noErr; -} - - -/* - * Transmit raw ethernet packet - */ - -static int16 ether_do_write(uint32 arg) -{ - // Copy packet to buffer - uint8 packet[1516], *p = packet; - int len = 0; -#if defined(__linux__) - if (net_if_type == NET_IF_ETHERTAP) { - *p++ = 0; // Linux ethertap discards the first 2 bytes - *p++ = 0; - len += 2; - } -#endif - len += ether_arg_to_buffer(arg, p); - -#if MONITOR - bug("Sending Ethernet packet:\n"); - for (int i=0; i 0) { - int len; - read(slirp_input_fd, &len, sizeof(len)); - uint8 packet[1516]; - assert(len <= sizeof(packet)); - read(slirp_input_fd, packet, len); - slirp_input(packet, len); - } - - // ... in the output queue - nfds = -1; - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - int timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); -#if ! USE_SLIRP_TIMEOUT - timeout = 10000; -#endif - tv.tv_sec = 0; - tv.tv_usec = timeout; - if (select(nfds + 1, &rfds, &wfds, &xfds, &tv) >= 0) - slirp_select_poll(&rfds, &wfds, &xfds); - -#ifdef HAVE_PTHREAD_TESTCANCEL - // Explicit cancellation point if select() was not covered - // This seems to be the case on MacOS X 10.2 - pthread_testcancel(); -#endif - } - return NULL; -} -#else -int slirp_can_output(void) -{ - return 0; -} - -void slirp_output(const uint8 *packet, int len) -{ -} -#endif - - -/* - * Packet reception thread - */ - -static void *receive_func(void *arg) -{ - for (;;) { - - // Wait for packets to arrive -#if USE_POLL - struct pollfd pf = {fd, POLLIN, 0}; - int res = poll(&pf, 1, -1); -#else - fd_set rfds; - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - // A NULL timeout could cause select() to block indefinitely, - // even if it is supposed to be a cancellation point [MacOS X] - struct timeval tv = { 0, 20000 }; - int res = select(fd + 1, &rfds, NULL, NULL, &tv); -#ifdef HAVE_PTHREAD_TESTCANCEL - pthread_testcancel(); -#endif - if (res == 0 || (res == -1 && errno == EINTR)) - continue; -#endif - if (res <= 0) - break; - - if (ether_driver_opened) { - // Trigger Ethernet interrupt - D(bug(" packet received, triggering Ethernet interrupt\n")); - SetInterruptFlag(INTFLAG_ETHER); - TriggerInterrupt(); - - // Wait for interrupt acknowledge by EtherInterrupt() - sem_wait(&int_ack); - } else - Delay_usec(20000); - } - return NULL; -} - - -/* - * Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers - */ - -void ether_do_interrupt(void) -{ - // Call protocol handler for received packets - EthernetPacket ether_packet; - uint32 packet = ether_packet.addr(); - ssize_t length; - for (;;) { - -#ifndef SHEEPSHAVER - if (udp_tunnel) { - - // Read packet from socket - struct sockaddr_in from; - socklen_t from_len = sizeof(from); - length = recvfrom(fd, Mac2HostAddr(packet), 1514, 0, (struct sockaddr *)&from, &from_len); - if (length < 14) - break; - ether_udp_read(packet, length, &from); - - } else -#endif - { - - // Read packet from sheep_net device -#if defined(__linux__) - length = read(fd, Mac2HostAddr(packet), net_if_type == NET_IF_ETHERTAP ? 1516 : 1514); -#else - length = read(fd, Mac2HostAddr(packet), 1514); -#endif - if (length < 14) - break; - -#if MONITOR - bug("Receiving Ethernet packet:\n"); - for (int i=0; i 0) { - if (len > buf_size - 1) - len = buf_size - 1; - memcpy(buf, p, len); - buf[len] = '\0'; - } - *pp = p1; - return 0; -} - -// Set up port forwarding for slirp -static void slirp_add_redirs() -{ - int index = 0; - const char *str; - while ((str = PrefsFindString("redir", index++)) != NULL) { - slirp_add_redir(str); - } -} - -// Add a port forward/redirection for slirp -static int slirp_add_redir(const char *redir_str) -{ - // code adapted from qemu source - struct in_addr guest_addr = {0}; - int host_port, guest_port; - const char *p; - char buf[256]; - int is_udp; - char *end; - char str[256]; - - p = redir_str; - if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) { - goto fail_syntax; - } - if (!strcmp(buf, "tcp") || buf[0] == '\0') { - is_udp = 0; - } else if (!strcmp(buf, "udp")) { - is_udp = 1; - } else { - goto fail_syntax; - } - - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { - goto fail_syntax; - } - host_port = strtol(buf, &end, 0); - if (*end != '\0' || host_port < 1 || host_port > 65535) { - goto fail_syntax; - } - - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { - goto fail_syntax; - } - // 0.0.0.0 doesn't seem to work, so default to a client address - // if none is specified - if (buf[0] == '\0' ? - !inet_aton(CTL_LOCAL, &guest_addr) : - !inet_aton(buf, &guest_addr)) { - goto fail_syntax; - } - - guest_port = strtol(p, &end, 0); - if (*end != '\0' || guest_port < 1 || guest_port > 65535) { - goto fail_syntax; - } - - if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) { - sprintf(str, "could not set up host forwarding rule '%s'", redir_str); - WarningAlert(str); - return -1; - } - return 0; - - fail_syntax: - sprintf(str, "invalid host forwarding rule '%s'", redir_str); - WarningAlert(str); - return -1; -} diff --git a/BasiliskII/src/Unix/ldscripts/freebsd-i386.ld b/BasiliskII/src/Unix/ldscripts/freebsd-i386.ld deleted file mode 100644 index a8d6745d..00000000 --- a/BasiliskII/src/Unix/ldscripts/freebsd-i386.ld +++ /dev/null @@ -1,175 +0,0 @@ -/* Script for -z combreloc: combine and sort reloc sections */ -OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd", "elf32-i386-freebsd") -OUTPUT_ARCH(i386) -ENTRY(_start) -SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0x78048000 + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rel.dyn : - { - *(.rel.init) - *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) - *(.rel.fini) - *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) - *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) - *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) - *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) - *(.rel.ctors) - *(.rel.dtors) - *(.rel.got) - *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) - } - .rela.dyn : - { - *(.rela.init) - *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) - *(.rela.fini) - *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) - *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) - *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) - *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) - *(.rela.ctors) - *(.rela.dtors) - *(.rela.got) - *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) - } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : - { - KEEP (*(.init)) - } =0x90909090 - .plt : { *(.plt) } - .text : - { - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - } =0x90909090 - .fini : - { - KEEP (*(.fini)) - } =0x90909090 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .eh_frame_hdr : { *(.eh_frame_hdr) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. */ - . = ALIGN (0x1000) - ((0x1000 - .) & (0x1000 - 1)); . = DATA_SEGMENT_ALIGN (0x1000, 0x1000); - /* Ensure the __preinit_array_start label is properly aligned. We - could instead move the label definition inside the section, but - the linker would then create the section even if it turns out to - be empty, which isn't pretty. */ - . = ALIGN(32 / 8); - PROVIDE (__preinit_array_start = .); - .preinit_array : { *(.preinit_array) } - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - .init_array : { *(.init_array) } - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - .fini_array : { *(.fini_array) } - PROVIDE (__fini_array_end = .); - .data : - { - *(.data .data.* .gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - .eh_frame : { KEEP (*(.eh_frame)) } - .gcc_except_table : { *(.gcc_except_table) } - .dynamic : { *(.dynamic) } - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin*.o(.ctors)) - /* We don't want to include the .ctor section from - from the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } - .dtors : - { - KEEP (*crtbegin*.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } - .jcr : { KEEP (*(.jcr)) } - .got : { *(.got.plt) *(.got) } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - .bss : - { - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - /* Align here to ensure that the .bss section occupies space up to - _end. Align after .bss to ensure correct alignment even if the - .bss section disappears because there are no input sections. */ - . = ALIGN(32 / 8); - } - . = ALIGN(32 / 8); - _end = .; - PROVIDE (end = .); - . = DATA_SEGMENT_END (.); - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} diff --git a/BasiliskII/src/Unix/ldscripts/linux-i386.ld b/BasiliskII/src/Unix/ldscripts/linux-i386.ld deleted file mode 100644 index ed3a0b5d..00000000 --- a/BasiliskII/src/Unix/ldscripts/linux-i386.ld +++ /dev/null @@ -1,137 +0,0 @@ -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH(i386) -SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); -ENTRY(_start) -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0x78048000 + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rel.text : - { *(.rel.text) *(.rel.gnu.linkonce.t*) } - .rela.text : - { *(.rela.text) *(.rela.gnu.linkonce.t*) } - .rel.data : - { *(.rel.data) *(.rel.gnu.linkonce.d*) } - .rela.data : - { *(.rela.data) *(.rela.gnu.linkonce.d*) } - .rel.rodata : - { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } - .rela.rodata : - { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.init : { *(.rel.init) } - .rela.init : { *(.rela.init) } - .rel.fini : { *(.rel.fini) } - .rela.fini : { *(.rela.fini) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : { *(.init) } =0x47ff041f - .text : - { - *(.text) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.gnu.linkonce.t*) - } =0x47ff041f - _etext = .; - PROVIDE (etext = .); - .fini : { *(.fini) } =0x47ff041f - . = ALIGN(32 / 8); - PROVIDE (__preinit_array_start = .); - .preinit_array : { *(.preinit_array) } - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - .init_array : { *(.init_array) } - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - .fini_array : { *(.fini_array) } - PROVIDE (__fini_array_end = .); - .rodata : { *(.rodata) *(.gnu.linkonce.r*) } - .rodata1 : { *(.rodata1) } - .reginfo : { *(.reginfo) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. */ - . = ALIGN(0x100000) + (. & (0x100000 - 1)); - .data : - { - *(.data) - *(.gnu.linkonce.d*) - CONSTRUCTORS - } - .data1 : { *(.data1) } - .ctors : - { - *(.ctors) - } - .dtors : - { - *(.dtors) - } - .plt : { *(.plt) } - .got : { *(.got.plt) *(.got) } - .dynamic : { *(.dynamic) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : { *(.sdata) } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - .sbss : { *(.sbss) *(.scommon) } - .bss : - { - *(.dynbss) - *(.bss) - *(COMMON) - } - _end = . ; - PROVIDE (end = .); - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* These must appear regardless of . */ -} diff --git a/BasiliskII/src/Unix/ldscripts/linux-ppc.ld b/BasiliskII/src/Unix/ldscripts/linux-ppc.ld deleted file mode 100644 index b54743f5..00000000 --- a/BasiliskII/src/Unix/ldscripts/linux-ppc.ld +++ /dev/null @@ -1,219 +0,0 @@ -/* Script for -z combreloc: combine and sort reloc sections */ -OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") -OUTPUT_ARCH(powerpc:common) -ENTRY(_start) -SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/local/lib"); -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0x78048000 + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rel.dyn : - { - *(.rel.init) - *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) - *(.rel.fini) - *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) - *(.rel.data.rel.ro*) - *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) - *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) - *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) - *(.rel.ctors) - *(.rel.dtors) - *(.rel.got) - *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) - *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) - *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) - *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) - *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) - } - .rela.dyn : - { - *(.rela.init) - *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) - *(.rela.fini) - *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) - *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) - *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) - *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) - *(.rela.ctors) - *(.rela.dtors) - *(.rela.got) - *(.rela.got1) - *(.rela.got2) - *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) - *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) - *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) - *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) - *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) - } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : - { - KEEP (*(.init)) - } =0 - .text : - { - *(.text .stub .text.* .gnu.linkonce.t.*) - KEEP (*(.text.*personality*)) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - } =0 - .fini : - { - KEEP (*(.fini)) - } =0 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } - .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } - .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. */ - . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x1000); - /* Exception handling */ - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } - /* Thread Local Storage sections */ - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - /* Ensure the __preinit_array_start label is properly aligned. We - could instead move the label definition inside the section, but - the linker would then create the section even if it turns out to - be empty, which isn't pretty. */ - . = ALIGN(32 / 8); - PROVIDE (__preinit_array_start = .); - .preinit_array : { KEEP (*(.preinit_array)) } - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - .init_array : { KEEP (*(.init_array)) } - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - .fini_array : { KEEP (*(.fini_array)) } - PROVIDE (__fini_array_end = .); - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin*.o(.ctors)) - /* We don't want to include the .ctor section from - from the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } - .dtors : - { - KEEP (*crtbegin*.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } - .jcr : { KEEP (*(.jcr)) } - .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } - .fixup : { *(.fixup) } - .got1 : { *(.got1) } - .got2 : { *(.got2) } - .dynamic : { *(.dynamic) } - . = DATA_SEGMENT_RELRO_END (0, .); - .data : - { - *(.data .data.* .gnu.linkonce.d.*) - KEEP (*(.gnu.linkonce.d.*personality*)) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - .got1 : { *(.got1) } - .got2 : { *(.got2) } - .got : { *(.got.plt) *(.got) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : - { - *(.sdata .sdata.* .gnu.linkonce.s.*) - } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - .sbss : - { - PROVIDE (__sbss_start = .); - PROVIDE (___sbss_start = .); - *(.dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - PROVIDE (__sbss_end = .); - PROVIDE (___sbss_end = .); - } - .plt : { *(.plt) } - .bss : - { - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - /* Align here to ensure that the .bss section occupies space up to - _end. Align after .bss to ensure correct alignment even if the - .bss section disappears because there are no input sections. */ - . = ALIGN(32 / 8); - } - . = ALIGN(32 / 8); - _end = .; - PROVIDE (end = .); - . = DATA_SEGMENT_END (.); - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /DISCARD/ : { *(.fixup) } -} diff --git a/BasiliskII/src/Unix/ldscripts/linux-x86_64.ld b/BasiliskII/src/Unix/ldscripts/linux-x86_64.ld deleted file mode 100644 index b824271a..00000000 --- a/BasiliskII/src/Unix/ldscripts/linux-x86_64.ld +++ /dev/null @@ -1,171 +0,0 @@ -/* Default linker script, for normal executables */ -OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") -OUTPUT_ARCH(i386:x86-64) -ENTRY(_start) -SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64"); -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0x78048000 + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rel.init : { *(.rel.init) } - .rela.init : { *(.rela.init) } - .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } - .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } - .rel.fini : { *(.rel.fini) } - .rela.fini : { *(.rela.fini) } - .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } - .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } - .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } - .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } - .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } - .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } - .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } - .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } - .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : - { - KEEP (*(.init)) - } =0x90909090 - .plt : { *(.plt) } - .text : - { - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - } =0x90909090 - .fini : - { - KEEP (*(.fini)) - } =0x90909090 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. */ - . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000); - /* Ensure the __preinit_array_start label is properly aligned. We - could instead move the label definition inside the section, but - the linker would then create the section even if it turns out to - be empty, which isn't pretty. */ - . = ALIGN(64 / 8); - PROVIDE (__preinit_array_start = .); - .preinit_array : { *(.preinit_array) } - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - .init_array : { *(.init_array) } - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - .fini_array : { *(.fini_array) } - PROVIDE (__fini_array_end = .); - .data : - { - *(.data .data.* .gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) } - .dynamic : { *(.dynamic) } - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin.o(.ctors)) - /* We don't want to include the .ctor section from - from the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } - .dtors : - { - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } - .jcr : { KEEP (*(.jcr)) } - .got : { *(.got.plt) *(.got) } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - .bss : - { - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - /* Align here to ensure that the .bss section occupies space up to - _end. Align after .bss to ensure correct alignment even if the - .bss section disappears because there are no input sections. */ - . = ALIGN(64 / 8); - } - . = ALIGN(64 / 8); - _end = .; - PROVIDE (end = .); - . = DATA_SEGMENT_END (.); - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index 3505335e..644c215b 100644 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -29,45 +29,14 @@ # include #endif -#ifndef USE_SDL_VIDEO -# include -#endif - #ifdef HAVE_PTHREADS # include #endif -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING # include #endif -#if !EMULATED_68K && defined(__NetBSD__) -# include -# include -# include -# include -struct sigstate { - int ss_flags; - struct frame ss_frame; - struct fpframe ss_fpstate; -}; -# define SS_FPSTATE 0x02 -# define SS_USERREGS 0x04 -#endif - -#ifdef ENABLE_GTK -# include -# include -# ifdef HAVE_GNOMEUI -# include -# endif -#endif - -#ifdef ENABLE_XF86_DGA -# include -# include -#endif - #include using std::string; @@ -88,13 +57,6 @@ using std::string; #include "sigsegv.h" #include "rpc.h" -#if USE_JIT -extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp -#endif - -#ifdef ENABLE_MON -# include "mon.h" -#endif #define DEBUG 0 #include "debug.h" @@ -102,23 +64,10 @@ extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_suppo // Constants const char ROM_FILE_NAME[] = "ROM"; -#if !EMULATED_68K -const int SIG_STACK_SIZE = SIGSTKSZ; // Size of signal stack -#endif + const int SCRATCH_MEM_SIZE = 0x10000; // Size of scratch memory area -#if !EMULATED_68K -// RAM and ROM pointers -uint32 RAMBaseMac; // RAM base (Mac address space) -uint8 *RAMBaseHost; // RAM base (host address space) -uint32 RAMSize; // Size of RAM -uint32 ROMBaseMac; // ROM base (Mac address space) -uint8 *ROMBaseHost; // ROM base (host address space) -uint32 ROMSize; // Size of ROM -#endif - - // CPU and FPU type, addressing mode int CPUType; bool CPUIs68060; @@ -127,20 +76,10 @@ bool TwentyFourBitAddressing; // Global variables -#ifndef USE_SDL_VIDEO -extern char *x_display_name; // X11 display name -extern Display *x_display; // X11 display handle -#ifdef X11_LOCK_TYPE -X11_LOCK_TYPE x_display_lock = X11_LOCK_INIT; // X11 display lock -#endif -#endif static uint8 last_xpram[XPRAM_SIZE]; // Buffer for monitoring XPRAM changes #ifdef HAVE_PTHREADS -#if !EMULATED_68K -static pthread_t emul_thread; // Handle of MacOS emulation thread (main thread) -#endif static bool xpram_thread_active = false; // Flag: XPRAM watchdog installed static volatile bool xpram_thread_cancel = false; // Flag: Cancel XPRAM thread @@ -162,14 +101,6 @@ static pthread_mutex_t intflag_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to pro #endif -#if !EMULATED_68K -#define SIG_IRQ SIGUSR1 -static struct sigaction sigirq_sa; // Virtual 68k interrupt signal -static struct sigaction sigill_sa; // Illegal instruction -static void *sig_stack = NULL; // Stack for signal handlers -uint16 EmulatedSR; // Emulated bits of SR (supervisor bit and interrupt mask) -#endif - #if USE_SCRATCHMEM_SUBTERFUGE uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes #endif @@ -183,14 +114,6 @@ static timer_t timer; // 60Hz timer #endif #endif // !HAVE_PTHREADS -#ifdef ENABLE_MON -static struct sigaction sigint_sa; // sigaction for SIGINT handler -static void sigint_handler(...); -#endif - -#if REAL_ADDRESSING -static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped -#endif static rpc_connection_t *gui_connection = NULL; // RPC connection to the GUI static const char *gui_connection_path = NULL; // GUI connection identifier @@ -200,11 +123,6 @@ static const char *gui_connection_path = NULL; // GUI connection identifier static void *xpram_func(void *arg); static void *tick_func(void *arg); static void one_tick(...); -#if !EMULATED_68K -static void sigirq_handler(int sig, int code, struct sigcontext *scp); -static void sigill_handler(int sig, int code, struct sigcontext *scp); -extern "C" void EmulOpTrampoline(void); -#endif /* @@ -285,15 +203,9 @@ static void sigsegv_dump_state(sigsegv_info_t *sip) extern void m68k_dumpstate(uaecptr *nextpc); m68k_dumpstate(&nextpc); #endif -#if USE_JIT && JIT_DEBUG - extern void compiler_dumpstate(void); - compiler_dumpstate(); -#endif + VideoQuitFullScreen(); -#ifdef ENABLE_MON - const char *arg[4] = {"mon", "-m", "-r", NULL}; - mon(3, arg); -#endif + QuitEmulator(); } @@ -398,12 +310,6 @@ int main(int argc, char **argv) for (int i=1; i 1023*1024*1024) // Cap to 1023MB (APD crashes at 1GB) RAMSize = 1023*1024*1024; -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING RAMSize = RAMSize & -getpagesize(); // Round down to page boundary #endif // Initialize VM system vm_init(); -#if REAL_ADDRESSING - // Flag: RAM and ROM are contigously allocated from address 0 - bool memory_mapped_from_zero = false; - - // Make sure to map RAM & ROM at address 0 only on platforms that - // supports linker scripts to relocate the Basilisk II executable - // above 0x70000000 -#if HAVE_LINKER_SCRIPT - const bool can_map_all_memory = true; -#else - const bool can_map_all_memory = false; -#endif - - // Try to allocate all memory from 0x0000, if it is not known to crash - if (can_map_all_memory && (vm_acquire_mac_fixed(0, RAMSize + 0x100000) == 0)) { - D(bug("Could allocate RAM and ROM from 0x0000\n")); - memory_mapped_from_zero = true; - } - -#ifndef PAGEZERO_HACK - // Otherwise, just create the Low Memory area (0x0000..0x2000) - else if (vm_acquire_mac_fixed(0, 0x2000) == 0) { - D(bug("Could allocate the Low Memory globals\n")); - lm_area_mapped = true; - } - - // Exit on failure - else { - sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno)); - ErrorAlert(str); - QuitEmulator(); - } -#endif -#endif /* REAL_ADDRESSING */ - // Create areas for Mac RAM and ROM -#if REAL_ADDRESSING - if (memory_mapped_from_zero) { - RAMBaseHost = (uint8 *)0; - ROMBaseHost = RAMBaseHost + RAMSize; - } - else -#endif { uint8 *ram_rom_area = (uint8 *)vm_acquire_mac(RAMSize + 0x100000); if (ram_rom_area == VM_MAP_FAILED) { @@ -615,10 +448,7 @@ int main(int argc, char **argv) RAMBaseMac = 0; ROMBaseMac = Host2MacAddr(ROMBaseHost); #endif -#if REAL_ADDRESSING - RAMBaseMac = Host2MacAddr(RAMBaseHost); - ROMBaseMac = Host2MacAddr(ROMBaseHost); -#endif + D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac)); D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac)); @@ -645,98 +475,11 @@ int main(int argc, char **argv) QuitEmulator(); } -#if !EMULATED_68K - // Get CPU model - int mib[2] = {CTL_HW, HW_MODEL}; - char *model; - size_t model_len; - sysctl(mib, 2, NULL, &model_len, NULL, 0); - model = (char *)malloc(model_len); - sysctl(mib, 2, model, &model_len, NULL, 0); - D(bug("Model: %s\n", model)); - - // Set CPU and FPU type - CPUIs68060 = false; - if (strstr(model, "020")) - CPUType = 2; - else if (strstr(model, "030")) - CPUType = 3; - else if (strstr(model, "040")) - CPUType = 4; - else if (strstr(model, "060")) { - CPUType = 4; - CPUIs68060 = true; - } else { - printf("WARNING: Cannot detect CPU type, assuming 68020\n"); - CPUType = 2; - } - FPUType = 1; // NetBSD has an FPU emulation, so the FPU ought to be available at all times - TwentyFourBitAddressing = false; -#endif - // Initialize everything if (!InitAll(vmdir)) QuitEmulator(); D(bug("Initialization complete\n")); -#if !EMULATED_68K - // (Virtual) supervisor mode, disable interrupts - EmulatedSR = 0x2700; - -#ifdef HAVE_PTHREADS - // Get handle of main thread - emul_thread = pthread_self(); -#endif - - // Create and install stack for signal handlers - sig_stack = malloc(SIG_STACK_SIZE); - D(bug("Signal stack at %p\n", sig_stack)); - if (sig_stack == NULL) { - ErrorAlert(STR_NOT_ENOUGH_MEMORY_ERR); - QuitEmulator(); - } - stack_t new_stack; - new_stack.ss_sp = sig_stack; - new_stack.ss_flags = 0; - new_stack.ss_size = SIG_STACK_SIZE; - if (sigaltstack(&new_stack, NULL) < 0) { - sprintf(str, GetString(STR_SIGALTSTACK_ERR), strerror(errno)); - ErrorAlert(str); - QuitEmulator(); - } - - // Install SIGILL handler for emulating privileged instructions and - // executing A-Trap and EMUL_OP opcodes - sigemptyset(&sigill_sa.sa_mask); // Block virtual 68k interrupts during SIGILL handling - sigaddset(&sigill_sa.sa_mask, SIG_IRQ); - sigaddset(&sigill_sa.sa_mask, SIGALRM); - sigill_sa.sa_handler = (void (*)(int))sigill_handler; - sigill_sa.sa_flags = SA_ONSTACK; - if (sigaction(SIGILL, &sigill_sa, NULL) < 0) { - sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIGILL", strerror(errno)); - ErrorAlert(str); - QuitEmulator(); - } - - // Install virtual 68k interrupt signal handler - sigemptyset(&sigirq_sa.sa_mask); - sigaddset(&sigirq_sa.sa_mask, SIGALRM); - sigirq_sa.sa_handler = (void (*)(int))sigirq_handler; - sigirq_sa.sa_flags = SA_ONSTACK | SA_RESTART; - if (sigaction(SIG_IRQ, &sigirq_sa, NULL) < 0) { - sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIG_IRQ", strerror(errno)); - ErrorAlert(str); - QuitEmulator(); - } -#endif - -#ifdef ENABLE_MON - // Setup SIGINT handler to enter mon - sigemptyset(&sigint_sa.sa_mask); - sigint_sa.sa_handler = (void (*)(int))sigint_handler; - sigint_sa.sa_flags = 0; - sigaction(SIGINT, &sigint_sa, NULL); -#endif #ifndef USE_CPU_EMUL_SERVICES #if defined(HAVE_PTHREADS) @@ -786,9 +529,6 @@ int main(int argc, char **argv) // Start 60Hz timer sigemptyset(&timer_sa.sa_mask); // Block virtual 68k interrupts during SIGARLM handling -#if !EMULATED_68K - sigaddset(&timer_sa.sa_mask, SIG_IRQ); -#endif timer_sa.sa_handler = one_tick; timer_sa.sa_flags = SA_ONSTACK | SA_RESTART; if (sigaction(SIGALRM, &timer_sa, NULL) < 0) { @@ -887,12 +627,6 @@ void QuitEmulator(void) } #endif -#if REAL_ADDRESSING - // Delete Low Memory area - if (lm_area_mapped) - vm_release(0, 0x2000); -#endif - // Exit VM wrappers vm_exit(); @@ -902,12 +636,6 @@ void QuitEmulator(void) // Exit preferences PrefsExit(); - // Close X11 server connection -#ifndef USE_SDL_VIDEO - if (x_display) - XCloseDisplay(x_display); -#endif - // Notify GUI we are about to leave if (gui_connection) { if (rpc_method_invoke(gui_connection, RPC_METHOD_EXIT, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR) @@ -925,35 +653,10 @@ void QuitEmulator(void) void FlushCodeCache(void *start, uint32 size) { -#if USE_JIT - if (UseJIT) - flush_icache_range((uint8 *)start, size); -#endif -#if !EMULATED_68K && defined(__NetBSD__) - m68k_sync_icache(start, size); -#endif + } -/* - * SIGINT handler, enters mon - */ - -#ifdef ENABLE_MON -static void sigint_handler(...) -{ -#if EMULATED_68K - uaecptr nextpc; - extern void m68k_dumpstate(uaecptr *nextpc); - m68k_dumpstate(&nextpc); -#endif - VideoQuitFullScreen(); - const char *arg[4] = {"mon", "-m", "-r", NULL}; - mon(3, arg); - QuitEmulator(); -} -#endif - #ifdef HAVE_PTHREADS /* @@ -1089,22 +792,6 @@ void ClearInterruptFlag(uint32 flag) } #endif -#if !EMULATED_68K -void TriggerInterrupt(void) -{ -#if defined(HAVE_PTHREADS) - pthread_kill(emul_thread, SIG_IRQ); -#else - raise(SIG_IRQ); -#endif -} - -void TriggerNMI(void) -{ - // not yet supported -} -#endif - /* * XPRAM watchdog thread (saves XPRAM every minute) @@ -1200,354 +887,6 @@ static void *tick_func(void *arg) #endif -#if !EMULATED_68K -/* - * Virtual 68k interrupt handler - */ - -static void sigirq_handler(int sig, int code, struct sigcontext *scp) -{ - // Interrupts disabled? Then do nothing - if (EmulatedSR & 0x0700) - return; - - struct sigstate *state = (struct sigstate *)scp->sc_ap; - M68kRegisters *regs = (M68kRegisters *)&state->ss_frame; - - // Set up interrupt frame on stack - uint32 a7 = regs->a[7]; - a7 -= 2; - WriteMacInt16(a7, 0x64); - a7 -= 4; - WriteMacInt32(a7, scp->sc_pc); - a7 -= 2; - WriteMacInt16(a7, scp->sc_ps | EmulatedSR); - scp->sc_sp = regs->a[7] = a7; - - // Set interrupt level - EmulatedSR |= 0x2100; - - // Jump to MacOS interrupt handler on return - scp->sc_pc = ReadMacInt32(0x64); -} - - -/* - * SIGILL handler, for emulation of privileged instructions and executing - * A-Trap and EMUL_OP opcodes - */ - -static void sigill_handler(int sig, int code, struct sigcontext *scp) -{ - struct sigstate *state = (struct sigstate *)scp->sc_ap; - uint16 *pc = (uint16 *)scp->sc_pc; - uint16 opcode = *pc; - M68kRegisters *regs = (M68kRegisters *)&state->ss_frame; - -#define INC_PC(n) scp->sc_pc += (n) - -#define GET_SR (scp->sc_ps | EmulatedSR) - -#define STORE_SR(v) \ - scp->sc_ps = (v) & 0xff; \ - EmulatedSR = (v) & 0xe700; \ - if (((v) & 0x0700) == 0 && InterruptFlags) \ - TriggerInterrupt(); - -//printf("opcode %04x at %p, sr %04x, emul_sr %04x\n", opcode, pc, scp->sc_ps, EmulatedSR); - - if ((opcode & 0xf000) == 0xa000) { - - // A-Line instruction, set up A-Line trap frame on stack - uint32 a7 = regs->a[7]; - a7 -= 2; - WriteMacInt16(a7, 0x28); - a7 -= 4; - WriteMacInt32(a7, (uint32)pc); - a7 -= 2; - WriteMacInt16(a7, GET_SR); - scp->sc_sp = regs->a[7] = a7; - - // Jump to MacOS A-Line handler on return - scp->sc_pc = ReadMacInt32(0x28); - - } else if ((opcode & 0xff00) == 0x7100) { - - // Extended opcode, push registers on user stack - uint32 a7 = regs->a[7]; - a7 -= 4; - WriteMacInt32(a7, (uint32)pc); - a7 -= 2; - WriteMacInt16(a7, scp->sc_ps); - for (int i=7; i>=0; i--) { - a7 -= 4; - WriteMacInt32(a7, regs->a[i]); - } - for (int i=7; i>=0; i--) { - a7 -= 4; - WriteMacInt32(a7, regs->d[i]); - } - scp->sc_sp = regs->a[7] = a7; - - // Jump to EmulOp trampoline code on return - scp->sc_pc = (uint32)EmulOpTrampoline; - - } else switch (opcode) { // Emulate privileged instructions - - case 0x40e7: // move sr,-(sp) - regs->a[7] -= 2; - WriteMacInt16(regs->a[7], GET_SR); - scp->sc_sp = regs->a[7]; - INC_PC(2); - break; - - case 0x46df: { // move (sp)+,sr - uint16 sr = ReadMacInt16(regs->a[7]); - STORE_SR(sr); - regs->a[7] += 2; - scp->sc_sp = regs->a[7]; - INC_PC(2); - break; - } - - case 0x007c: { // ori #xxxx,sr - uint16 sr = GET_SR | pc[1]; - scp->sc_ps = sr & 0xff; // oring bits into the sr can't enable interrupts, so we don't need to call STORE_SR - EmulatedSR = sr & 0xe700; - INC_PC(4); - break; - } - - case 0x027c: { // andi #xxxx,sr - uint16 sr = GET_SR & pc[1]; - STORE_SR(sr); - INC_PC(4); - break; - } - - case 0x46fc: // move #xxxx,sr - STORE_SR(pc[1]); - INC_PC(4); - break; - - case 0x46ef: { // move (xxxx,sp),sr - uint16 sr = ReadMacInt16(regs->a[7] + (int32)(int16)pc[1]); - STORE_SR(sr); - INC_PC(4); - break; - } - - case 0x46d8: // move (a0)+,sr - case 0x46d9: { // move (a1)+,sr - uint16 sr = ReadMacInt16(regs->a[opcode & 7]); - STORE_SR(sr); - regs->a[opcode & 7] += 2; - INC_PC(2); - break; - } - - case 0x40f8: // move sr,xxxx.w - WriteMacInt16(pc[1], GET_SR); - INC_PC(4); - break; - - case 0x40d0: // move sr,(a0) - case 0x40d1: // move sr,(a1) - case 0x40d2: // move sr,(a2) - case 0x40d3: // move sr,(a3) - case 0x40d4: // move sr,(a4) - case 0x40d5: // move sr,(a5) - case 0x40d6: // move sr,(a6) - case 0x40d7: // move sr,(sp) - WriteMacInt16(regs->a[opcode & 7], GET_SR); - INC_PC(2); - break; - - case 0x40c0: // move sr,d0 - case 0x40c1: // move sr,d1 - case 0x40c2: // move sr,d2 - case 0x40c3: // move sr,d3 - case 0x40c4: // move sr,d4 - case 0x40c5: // move sr,d5 - case 0x40c6: // move sr,d6 - case 0x40c7: // move sr,d7 - regs->d[opcode & 7] = GET_SR; - INC_PC(2); - break; - - case 0x46c0: // move d0,sr - case 0x46c1: // move d1,sr - case 0x46c2: // move d2,sr - case 0x46c3: // move d3,sr - case 0x46c4: // move d4,sr - case 0x46c5: // move d5,sr - case 0x46c6: // move d6,sr - case 0x46c7: { // move d7,sr - uint16 sr = regs->d[opcode & 7]; - STORE_SR(sr); - INC_PC(2); - break; - } - - case 0xf327: // fsave -(sp) - regs->a[7] -= 4; - WriteMacInt32(regs->a[7], 0x41000000); // Idle frame - scp->sc_sp = regs->a[7]; - INC_PC(2); - break; - - case 0xf35f: // frestore (sp)+ - regs->a[7] += 4; - scp->sc_sp = regs->a[7]; - INC_PC(2); - break; - - case 0x4e73: { // rte - uint32 a7 = regs->a[7]; - uint16 sr = ReadMacInt16(a7); - a7 += 2; - scp->sc_ps = sr & 0xff; - EmulatedSR = sr & 0xe700; - scp->sc_pc = ReadMacInt32(a7); - a7 += 4; - uint16 format = ReadMacInt16(a7) >> 12; - a7 += 2; - static const int frame_adj[16] = { - 0, 0, 4, 4, 8, 0, 0, 52, 50, 12, 24, 84, 16, 0, 0, 0 - }; - scp->sc_sp = regs->a[7] = a7 + frame_adj[format]; - break; - } - - case 0x4e7a: // movec cr,x - switch (pc[1]) { - case 0x0002: // movec cacr,d0 - regs->d[0] = 0x3111; - break; - case 0x1002: // movec cacr,d1 - regs->d[1] = 0x3111; - break; - case 0x0003: // movec tc,d0 - case 0x0004: // movec itt0,d0 - case 0x0005: // movec itt1,d0 - case 0x0006: // movec dtt0,d0 - case 0x0007: // movec dtt1,d0 - case 0x0806: // movec urp,d0 - case 0x0807: // movec srp,d0 - regs->d[0] = 0; - break; - case 0x1000: // movec sfc,d1 - case 0x1001: // movec dfc,d1 - case 0x1003: // movec tc,d1 - case 0x1801: // movec vbr,d1 - regs->d[1] = 0; - break; - case 0x8801: // movec vbr,a0 - regs->a[0] = 0; - break; - case 0x9801: // movec vbr,a1 - regs->a[1] = 0; - break; - default: - goto ill; - } - INC_PC(4); - break; - - case 0x4e7b: // movec x,cr - switch (pc[1]) { - case 0x1000: // movec d1,sfc - case 0x1001: // movec d1,dfc - case 0x0801: // movec d0,vbr - case 0x1801: // movec d1,vbr - break; - case 0x0002: // movec d0,cacr - case 0x1002: // movec d1,cacr - FlushCodeCache(NULL, 0); - break; - default: - goto ill; - } - INC_PC(4); - break; - - case 0xf478: // cpusha dc - case 0xf4f8: // cpusha dc/ic - FlushCodeCache(NULL, 0); - INC_PC(2); - break; - - default: -ill: printf("SIGILL num %d, code %d\n", sig, code); - printf(" context %p:\n", scp); - printf(" onstack %08x\n", scp->sc_onstack); - printf(" sp %08x\n", scp->sc_sp); - printf(" fp %08x\n", scp->sc_fp); - printf(" pc %08x\n", scp->sc_pc); - printf(" opcode %04x\n", opcode); - printf(" sr %08x\n", scp->sc_ps); - printf(" state %p:\n", state); - printf(" flags %d\n", state->ss_flags); - for (int i=0; i<8; i++) - printf(" d%d %08x\n", i, state->ss_frame.f_regs[i]); - for (int i=0; i<8; i++) - printf(" a%d %08x\n", i, state->ss_frame.f_regs[i+8]); - - VideoQuitFullScreen(); -#ifdef ENABLE_MON - char *arg[4] = {"mon", "-m", "-r", NULL}; - mon(3, arg); -#endif - QuitEmulator(); - break; - } -} -#endif - - -/* - * Display alert - */ - -#ifdef ENABLE_GTK -static void dl_destroyed(void) -{ - gtk_main_quit(); -} - -static void dl_quit(GtkWidget *dialog) -{ - gtk_widget_destroy(dialog); -} - -void display_alert(int title_id, int prefix_id, int button_id, const char *text) -{ - char str[256]; - sprintf(str, GetString(prefix_id), text); - - GtkWidget *dialog = gtk_dialog_new(); - gtk_window_set_title(GTK_WINDOW(dialog), GetString(title_id)); - gtk_container_border_width(GTK_CONTAINER(dialog), 5); - gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150); - gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(dl_destroyed), NULL); - - GtkWidget *label = gtk_label_new(str); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); - - GtkWidget *button = gtk_button_new_with_label(GetString(button_id)); - gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog)); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_widget_grab_default(button); - gtk_widget_show(dialog); - - gtk_main(); -} -#endif - - /* * Display error alert */ @@ -1559,16 +898,7 @@ void ErrorAlert(const char *text) rpc_method_wait_for_reply(gui_connection, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR) return; } -#if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO) - if (PrefsFindBool("nogui") || x_display == NULL) { - printf(GetString(STR_SHELL_ERROR_PREFIX), text); - return; - } - VideoQuitFullScreen(); - display_alert(STR_ERROR_ALERT_TITLE, STR_GUI_ERROR_PREFIX, STR_QUIT_BUTTON, text); -#else printf(GetString(STR_SHELL_ERROR_PREFIX), text); -#endif } @@ -1583,15 +913,7 @@ void WarningAlert(const char *text) rpc_method_wait_for_reply(gui_connection, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR) return; } -#if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO) - if (PrefsFindBool("nogui") || x_display == NULL) { - printf(GetString(STR_SHELL_WARNING_PREFIX), text); - return; - } - display_alert(STR_WARNING_ALERT_TITLE, STR_GUI_WARNING_PREFIX, STR_OK_BUTTON, text); -#else printf(GetString(STR_SHELL_WARNING_PREFIX), text); -#endif } diff --git a/BasiliskII/src/Unix/prefs_editor_gtk.cpp b/BasiliskII/src/Unix/prefs_editor_gtk.cpp deleted file mode 100644 index 637e1e67..00000000 --- a/BasiliskII/src/Unix/prefs_editor_gtk.cpp +++ /dev/null @@ -1,1828 +0,0 @@ -/* - * prefs_editor_gtk.cpp - Preferences editor, Unix implementation using GTK+ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_GNOMEUI -#include -#endif - -#include "user_strings.h" -#include "version.h" -#include "cdrom.h" -#include "xpram.h" -#include "prefs.h" -#include "prefs_editor.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static GtkWidget *win; // Preferences window -static bool start_clicked = false; // Return value of PrefsEditor() function - - -// Prototypes -static void create_volumes_pane(GtkWidget *top); -static void create_scsi_pane(GtkWidget *top); -static void create_graphics_pane(GtkWidget *top); -static void create_input_pane(GtkWidget *top); -static void create_serial_pane(GtkWidget *top); -static void create_memory_pane(GtkWidget *top); -static void create_jit_pane(GtkWidget *top); -static void read_settings(void); - - -/* - * Utility functions - */ - -#if ! GLIB_CHECK_VERSION(2,0,0) -#define G_OBJECT(obj) GTK_OBJECT(obj) -#define g_object_get_data(obj, key) gtk_object_get_data((obj), (key)) -#define g_object_set_data(obj, key, data) gtk_object_set_data((obj), (key), (data)) -#endif - -struct opt_desc { - int label_id; - GtkSignalFunc func; -}; - -struct combo_desc { - int label_id; -}; - -struct file_req_assoc { - file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {} - GtkWidget *req; - GtkWidget *entry; -}; - -static void cb_browse_ok(GtkWidget *button, file_req_assoc *assoc) -{ - gchar *file = (char *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); - gtk_entry_set_text(GTK_ENTRY(assoc->entry), file); - gtk_widget_destroy(assoc->req); - delete assoc; -} - -static void cb_browse(GtkWidget *widget, void *user_data) -{ - GtkWidget *req = gtk_file_selection_new(GetString(STR_BROWSE_TITLE)); - gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(cb_browse_ok), new file_req_assoc(req, (GtkWidget *)user_data)); - gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_widget_show(req); -} - -static GtkWidget *make_browse_button(GtkWidget *entry) -{ - GtkWidget *button; - - button = gtk_button_new_with_label(GetString(STR_BROWSE_CTRL)); - gtk_widget_show(button); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc)cb_browse, (void *)entry); - return button; -} - -static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func) -{ - GtkWidget *item = gtk_menu_item_new_with_label(GetString(label_id)); - gtk_widget_show(item); - gtk_signal_connect(GTK_OBJECT(item), "activate", func, NULL); - gtk_menu_append(GTK_MENU(menu), item); -} - -static GtkWidget *make_pane(GtkWidget *notebook, int title_id) -{ - GtkWidget *frame, *label, *box; - - frame = gtk_frame_new(NULL); - gtk_container_set_border_width(GTK_CONTAINER(frame), 4); - - box = gtk_vbox_new(FALSE, 4); - gtk_container_set_border_width(GTK_CONTAINER(box), 4); - gtk_container_add(GTK_CONTAINER(frame), box); - - gtk_widget_show_all(frame); - - label = gtk_label_new(GetString(title_id)); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label); - return box; -} - -static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *buttons) -{ - GtkWidget *bb, *button; - - bb = gtk_hbutton_box_new(); - gtk_widget_show(bb); - gtk_container_set_border_width(GTK_CONTAINER(bb), border); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bb), GTK_BUTTONBOX_DEFAULT_STYLE); - gtk_button_box_set_spacing(GTK_BUTTON_BOX(bb), 4); - gtk_box_pack_start(GTK_BOX(top), bb, FALSE, FALSE, 0); - - while (buttons->label_id) { - button = gtk_button_new_with_label(GetString(buttons->label_id)); - gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", buttons->func, NULL); - gtk_box_pack_start(GTK_BOX(bb), button, TRUE, TRUE, 0); - buttons++; - } - return bb; -} - -static GtkWidget *make_separator(GtkWidget *top) -{ - GtkWidget *sep = gtk_hseparator_new(); - gtk_box_pack_start(GTK_BOX(top), sep, FALSE, FALSE, 0); - gtk_widget_show(sep); - return sep; -} - -static GtkWidget *make_table(GtkWidget *top, int x, int y) -{ - GtkWidget *table = gtk_table_new(x, y, FALSE); - gtk_widget_show(table); - gtk_box_pack_start(GTK_BOX(top), table, FALSE, FALSE, 0); - return table; -} - -static GtkWidget *table_make_option_menu(GtkWidget *table, int row, int label_id, const opt_desc *options, int active) -{ - GtkWidget *label, *opt, *menu; - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - opt = gtk_option_menu_new(); - gtk_widget_show(opt); - menu = gtk_menu_new(); - - while (options->label_id) { - add_menu_item(menu, options->label_id, options->func); - options++; - } - gtk_menu_set_active(GTK_MENU(menu), active); - - gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu); - gtk_table_attach(GTK_TABLE(table), opt, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - return menu; -} - -static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, GList *glist) -{ - GtkWidget *label, *combo; - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - combo = gtk_combo_new(); - gtk_widget_show(combo); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist); - - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value); - gtk_table_attach(GTK_TABLE(table), combo, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - - return combo; -} - -static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, const combo_desc *options) -{ - GList *glist = NULL; - while (options->label_id) { - glist = g_list_append(glist, (void *)GetString(options->label_id)); - options++; - } - - return table_make_combobox(table, row, label_id, default_value, glist); -} - -static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id, const char *prefs_item, bool only_dirs = false) -{ - GtkWidget *box, *label, *entry, *button; - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - const char *str = PrefsFindString(prefs_item); - if (str == NULL) - str = ""; - - box = gtk_hbox_new(FALSE, 4); - gtk_widget_show(box); - gtk_table_attach(GTK_TABLE(table), box, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - - entry = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(entry), str); - gtk_widget_show(entry); - gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); - - button = make_browse_button(entry); - gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); - g_object_set_data(G_OBJECT(entry), "chooser_button", button); - return entry; -} - -static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc *options, int active) -{ - GtkWidget *box, *label, *opt, *menu; - - box = gtk_hbox_new(FALSE, 4); - gtk_widget_show(box); - gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0); - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); - - opt = gtk_option_menu_new(); - gtk_widget_show(opt); - menu = gtk_menu_new(); - - while (options->label_id) { - add_menu_item(menu, options->label_id, options->func); - options++; - } - gtk_menu_set_active(GTK_MENU(menu), active); - - gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu); - gtk_box_pack_start(GTK_BOX(box), opt, FALSE, FALSE, 0); - return menu; -} - -static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *prefs_item, bool only_dirs = false) -{ - GtkWidget *box, *label, *entry; - - box = gtk_hbox_new(FALSE, 4); - gtk_widget_show(box); - gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0); - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); - - const char *str = PrefsFindString(prefs_item); - if (str == NULL) - str = ""; - -#ifdef HAVE_GNOMEUI - entry = gnome_file_entry_new(NULL, GetString(label_id)); - if (only_dirs) - gnome_file_entry_set_directory(GNOME_FILE_ENTRY(entry), true); - gtk_entry_set_text(GTK_ENTRY(gnome_file_entry_gtk_entry(GNOME_FILE_ENTRY(entry))), str); -#else - entry = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(entry), str); -#endif - gtk_widget_show(entry); - gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); - return entry; -} - -static const gchar *get_file_entry_path(GtkWidget *entry) -{ -#ifdef HAVE_GNOMEUI - return gnome_file_entry_get_full_path(GNOME_FILE_ENTRY(entry), false); -#else - return gtk_entry_get_text(GTK_ENTRY(entry)); -#endif -} - -static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func) -{ - GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id)); - gtk_widget_show(button); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), PrefsFindBool(prefs_item)); - gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button); - gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0); - return button; -} - -static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *prefs_item, const combo_desc *options) -{ - GtkWidget *box, *label, *combo; - char str[32]; - - box = gtk_hbox_new(FALSE, 4); - gtk_widget_show(box); - gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0); - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); - - GList *glist = NULL; - while (options->label_id) { - glist = g_list_append(glist, (void *)GetString(options->label_id)); - options++; - } - - combo = gtk_combo_new(); - gtk_widget_show(combo); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist); - - sprintf(str, "%d", PrefsFindInt32(prefs_item)); - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str); - gtk_box_pack_start(GTK_BOX(box), combo, TRUE, TRUE, 0); - - return combo; -} - - -/* - * Show preferences editor - * Returns true when user clicked on "Start", false otherwise - */ - -// Window closed -static gint window_closed(void) -{ - return FALSE; -} - -// Window destroyed -static void window_destroyed(void) -{ - gtk_main_quit(); -} - -// "Start" button clicked -static void cb_start(...) -{ - start_clicked = true; - read_settings(); - SavePrefs(); - gtk_widget_destroy(win); -} - -// "Quit" button clicked -static void cb_quit(...) -{ - start_clicked = false; - gtk_widget_destroy(win); -} - -// "OK" button of "About" dialog clicked -static void dl_quit(GtkWidget *dialog) -{ - gtk_widget_destroy(dialog); -} - -// "About" selected -static void mn_about(...) -{ - GtkWidget *dialog; - -#ifdef HAVE_GNOMEUI - - char version[32]; - sprintf(version, "Version %d.%d", VERSION_MAJOR, VERSION_MINOR); - const char *authors[] = { - "Christian Bauer", - "Orlando Bassotto", - "Gwenolé Beauchesne", - "Marc Chabanas", - "Marc Hellwig", - "Biill Huey", - "Brian J. Johnson", - "Jürgen Lachmann", - "Samuel Lander", - "David Lawrence", - "Lauri Pesonen", - "Bernd Schmidt", - "and others", - NULL - }; - dialog = gnome_about_new( - "Basilisk II", - version, - "Copyright (C) 1997-2008 Christian Bauer", - authors, - "Basilisk II comes with ABSOLUTELY NO WARRANTY." - "This is free software, and you are welcome to redistribute it" - "under the terms of the GNU General Public License.", - NULL - ); - gnome_dialog_set_parent(GNOME_DIALOG(dialog), GTK_WINDOW(win)); - -#else - - GtkWidget *label, *button; - - char str[512]; - sprintf(str, - "Basilisk II\nVersion %d.%d\n\n" - "Copyright (C) 1997-2008 Christian Bauer et al.\n" - "E-mail: Christian.Bauer@uni-mainz.de\n" - "http://www.uni-mainz.de/~bauec002/B2Main.html\n\n" - "Basilisk II comes with ABSOLUTELY NO\n" - "WARRANTY. This is free software, and\n" - "you are welcome to redistribute it\n" - "under the terms of the GNU General\n" - "Public License.\n", - VERSION_MAJOR, VERSION_MINOR - ); - - dialog = gtk_dialog_new(); - gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE)); - gtk_container_border_width(GTK_CONTAINER(dialog), 5); - gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150); - - label = gtk_label_new(str); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); - - button = gtk_button_new_with_label(GetString(STR_OK_BUTTON)); - gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog)); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_widget_grab_default(button); - -#endif - - gtk_widget_show(dialog); -} - -// "Zap PRAM" selected -static void mn_zap_pram(...) -{ - ZapPRAM(); -} - -// Menu item descriptions -static GtkItemFactoryEntry menu_items[] = { - {(gchar *)GetString(STR_PREFS_MENU_FILE_GTK), NULL, NULL, 0, ""}, - {(gchar *)GetString(STR_PREFS_ITEM_START_GTK), "S", GTK_SIGNAL_FUNC(cb_start), 0, NULL}, - {(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK), NULL, GTK_SIGNAL_FUNC(mn_zap_pram), 0, NULL}, - {(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK), NULL, NULL, 0, ""}, - {(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "Q", GTK_SIGNAL_FUNC(cb_quit), 0, NULL}, - {(gchar *)GetString(STR_HELP_MENU_GTK), NULL, NULL, 0, ""}, - {(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), NULL, GTK_SIGNAL_FUNC(mn_about), 0, NULL} -}; - -bool PrefsEditor(void) -{ - // Create window - win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE)); - gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL); - gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL); - - // Create window contents - GtkWidget *box = gtk_vbox_new(FALSE, 4); - gtk_widget_show(box); - gtk_container_add(GTK_CONTAINER(win), box); - - GtkAccelGroup *accel_group = gtk_accel_group_new(); - GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "
", accel_group); - gtk_item_factory_create_items(item_factory, sizeof(menu_items) / sizeof(menu_items[0]), menu_items, NULL); -#if GTK_CHECK_VERSION(1,3,15) - gtk_window_add_accel_group(GTK_WINDOW(win), accel_group); -#else - gtk_accel_group_attach(accel_group, GTK_OBJECT(win)); -#endif - GtkWidget *menu_bar = gtk_item_factory_get_widget(item_factory, "
"); - gtk_widget_show(menu_bar); - gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0); - - GtkWidget *notebook = gtk_notebook_new(); - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP); - gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), FALSE); - gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0); - gtk_widget_realize(notebook); - - create_volumes_pane(notebook); - create_scsi_pane(notebook); - create_graphics_pane(notebook); - create_input_pane(notebook); - create_serial_pane(notebook); - create_memory_pane(notebook); - create_jit_pane(notebook); - gtk_widget_show(notebook); - - static const opt_desc buttons[] = { - {STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)}, - {STR_QUIT_BUTTON, GTK_SIGNAL_FUNC(cb_quit)}, - {0, NULL} - }; - make_button_box(box, 4, buttons); - - // Show window and enter main loop - gtk_widget_show(win); - gtk_main(); - return start_clicked; -} - - -/* - * "Volumes" pane - */ - -static GtkWidget *volume_list, *w_extfs; -static int selected_volume; - -// Volume in list selected -static void cl_selected(GtkWidget *list, int row, int column) -{ - selected_volume = row; -} - -// Volume selected for addition -static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc) -{ - gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); - gtk_clist_append(GTK_CLIST(volume_list), &file); - gtk_widget_destroy(assoc->req); - delete assoc; -} - -// Volume selected for creation -static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc) -{ - gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); - - const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry)); - int size = atoi(str); - - char cmd[1024]; - sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", file, size); - int ret = system(cmd); - if (ret == 0) - gtk_clist_append(GTK_CLIST(volume_list), &file); - gtk_widget_destroy(GTK_WIDGET(assoc->req)); - delete assoc; -} - -// "Add Volume" button clicked -static void cb_add_volume(...) -{ - GtkWidget *req = gtk_file_selection_new(GetString(STR_ADD_VOLUME_TITLE)); - gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(add_volume_ok), new file_req_assoc(req, NULL)); - gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_widget_show(req); -} - -// "Create Hardfile" button clicked -static void cb_create_volume(...) -{ - GtkWidget *req = gtk_file_selection_new(GetString(STR_CREATE_VOLUME_TITLE)); - - GtkWidget *box = gtk_hbox_new(FALSE, 4); - gtk_widget_show(box); - GtkWidget *label = gtk_label_new(GetString(STR_HARDFILE_SIZE_CTRL)); - gtk_widget_show(label); - GtkWidget *entry = gtk_entry_new(); - gtk_widget_show(entry); - char str[32]; - sprintf(str, "%d", 40); - gtk_entry_set_text(GTK_ENTRY(entry), str); - gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(req)->main_vbox), box, FALSE, FALSE, 0); - - gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(create_volume_ok), new file_req_assoc(req, entry)); - gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_widget_show(req); -} - -// "Remove Volume" button clicked -static void cb_remove_volume(...) -{ - gtk_clist_remove(GTK_CLIST(volume_list), selected_volume); -} - -// "Boot From" selected -static void mn_boot_any(...) {PrefsReplaceInt32("bootdriver", 0);} -static void mn_boot_cdrom(...) {PrefsReplaceInt32("bootdriver", CDROMRefNum);} - -// "No CD-ROM Driver" button toggled -static void tb_nocdrom(GtkWidget *widget) -{ - PrefsReplaceBool("nocdrom", GTK_TOGGLE_BUTTON(widget)->active); -} - -// Read settings from widgets and set preferences -static void read_volumes_settings(void) -{ - while (PrefsFindString("disk")) - PrefsRemoveItem("disk"); - - for (int i=0; irows; i++) { - char *str; - gtk_clist_get_text(GTK_CLIST(volume_list), i, 0, &str); - PrefsAddString("disk", str); - } - - PrefsReplaceString("extfs", get_file_entry_path(w_extfs)); -} - -// Create "Volumes" pane -static void create_volumes_pane(GtkWidget *top) -{ - GtkWidget *box, *scroll; - - box = make_pane(top, STR_VOLUMES_PANE_TITLE); - - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_widget_show(scroll); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - volume_list = gtk_clist_new(1); - gtk_widget_show(volume_list); - gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE); - gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE); - gtk_clist_set_reorderable(GTK_CLIST(volume_list), true); - gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL); - char *str; - int32 index = 0; - while ((str = const_cast(PrefsFindString("disk", index++))) != NULL) - gtk_clist_append(GTK_CLIST(volume_list), &str); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), volume_list); - gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0); - selected_volume = 0; - - static const opt_desc buttons[] = { - {STR_ADD_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_add_volume)}, - {STR_CREATE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_create_volume)}, - {STR_REMOVE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_remove_volume)}, - {0, NULL}, - }; - make_button_box(box, 0, buttons); - make_separator(box); - - w_extfs = make_file_entry(box, STR_EXTFS_CTRL, "extfs", true); - - static const opt_desc options[] = { - {STR_BOOT_ANY_LAB, GTK_SIGNAL_FUNC(mn_boot_any)}, - {STR_BOOT_CDROM_LAB, GTK_SIGNAL_FUNC(mn_boot_cdrom)}, - {0, NULL} - }; - int bootdriver = PrefsFindInt32("bootdriver"), active = 0; - switch (bootdriver) { - case 0: active = 0; break; - case CDROMRefNum: active = 1; break; - } - make_option_menu(box, STR_BOOTDRIVER_CTRL, options, active); - - make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", GTK_SIGNAL_FUNC(tb_nocdrom)); -} - - -/* - * "JIT Compiler" pane - */ - -static GtkWidget *w_jit_fpu; -static GtkWidget *w_jit_cache_size; -static GtkWidget *w_jit_lazy_flush; -static GtkWidget *w_jit_follow_const_jumps; - -// Are we running a JIT capable CPU? -static bool is_jit_capable(void) -{ -#if USE_JIT && (defined __i386__ || defined __x86_64__) - return true; -#elif defined __APPLE__ && defined __MACH__ - // XXX run-time detect so that we can use a PPC GUI prefs editor - static char cpu[10]; - if (cpu[0] == 0) { - FILE *fp = popen("uname -p", "r"); - if (fp == NULL) - return false; - fgets(cpu, sizeof(cpu) - 1, fp); - fclose(fp); - } - if (cpu[0] == 'i' && cpu[2] == '8' && cpu[3] == '6') // XXX assuming i?86 - return true; -#endif - return false; -} - -// Set sensitivity of widgets -static void set_jit_sensitive(void) -{ - const bool jit_enabled = PrefsFindBool("jit"); - gtk_widget_set_sensitive(w_jit_fpu, jit_enabled); - gtk_widget_set_sensitive(w_jit_cache_size, jit_enabled); - gtk_widget_set_sensitive(w_jit_lazy_flush, jit_enabled); - gtk_widget_set_sensitive(w_jit_follow_const_jumps, jit_enabled); -} - -// "Use JIT Compiler" button toggled -static void tb_jit(GtkWidget *widget) -{ - PrefsReplaceBool("jit", GTK_TOGGLE_BUTTON(widget)->active); - set_jit_sensitive(); -} - -// "Compile FPU Instructions" button toggled -static void tb_jit_fpu(GtkWidget *widget) -{ - PrefsReplaceBool("jitfpu", GTK_TOGGLE_BUTTON(widget)->active); -} - -// "Lazy translation cache invalidation" button toggled -static void tb_jit_lazy_flush(GtkWidget *widget) -{ - PrefsReplaceBool("jitlazyflush", GTK_TOGGLE_BUTTON(widget)->active); -} - -// "Translate through constant jumps (inline blocks)" button toggled -static void tb_jit_follow_const_jumps(GtkWidget *widget) -{ - PrefsReplaceBool("jitinline", GTK_TOGGLE_BUTTON(widget)->active); -} - -// Read settings from widgets and set preferences -static void read_jit_settings(void) -{ - bool jit_enabled = is_jit_capable() && PrefsFindBool("jit"); - if (jit_enabled) { - const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_jit_cache_size)->entry)); - PrefsReplaceInt32("jitcachesize", atoi(str)); - } -} - -// Create "JIT Compiler" pane -static void create_jit_pane(GtkWidget *top) -{ - if (!is_jit_capable()) - return; - - GtkWidget *box; - - box = make_pane(top, STR_JIT_PANE_TITLE); - make_checkbox(box, STR_JIT_CTRL, "jit", GTK_SIGNAL_FUNC(tb_jit)); - - w_jit_fpu = make_checkbox(box, STR_JIT_FPU_CTRL, "jitfpu", GTK_SIGNAL_FUNC(tb_jit_fpu)); - - // Translation cache size - static const combo_desc options[] = { - STR_JIT_CACHE_SIZE_2MB_LAB, - STR_JIT_CACHE_SIZE_4MB_LAB, - STR_JIT_CACHE_SIZE_8MB_LAB, - STR_JIT_CACHE_SIZE_16MB_LAB, - 0 - }; - w_jit_cache_size = make_combobox(box, STR_JIT_CACHE_SIZE_CTRL, "jitcachesize", options); - - // Lazy translation cache invalidation - w_jit_lazy_flush = make_checkbox(box, STR_JIT_LAZY_CINV_CTRL, "jitlazyflush", GTK_SIGNAL_FUNC(tb_jit_lazy_flush)); - - // Follow constant jumps (inline basic blocks) - w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", GTK_SIGNAL_FUNC(tb_jit_follow_const_jumps)); - - set_jit_sensitive(); -} - -/* - * "SCSI" pane - */ - -static GtkWidget *w_scsi[7]; - -// Read settings from widgets and set preferences -static void read_scsi_settings(void) -{ - for (int id=0; id<7; id++) { - char prefs_name[32]; - sprintf(prefs_name, "scsi%d", id); - const char *str = get_file_entry_path(w_scsi[id]); - if (str && strlen(str)) - PrefsReplaceString(prefs_name, str); - else - PrefsRemoveItem(prefs_name); - } -} - -// Create "SCSI" pane -static void create_scsi_pane(GtkWidget *top) -{ - GtkWidget *box; - - box = make_pane(top, STR_SCSI_PANE_TITLE); - - for (int id=0; id<7; id++) { - char prefs_name[32]; - sprintf(prefs_name, "scsi%d", id); - w_scsi[id] = make_file_entry(box, STR_SCSI_ID_0 + id, prefs_name); - } -} - - -/* - * "Graphics/Sound" pane - */ - -// Display types -enum { - DISPLAY_WINDOW, - DISPLAY_SCREEN -}; - -static GtkWidget *w_frameskip, *w_display_x, *w_display_y; -static GtkWidget *l_frameskip, *l_display_x, *l_display_y; -static int display_type; -static int dis_width, dis_height; - -#ifdef ENABLE_FBDEV_DGA -static GtkWidget *w_fbdev_name, *w_fbdevice_file; -static GtkWidget *l_fbdev_name, *l_fbdevice_file; -static char fbdev_name[256]; -#endif - -static GtkWidget *w_dspdevice_file, *w_mixerdevice_file; - -// Hide/show graphics widgets -static void hide_show_graphics_widgets(void) -{ - switch (display_type) { - case DISPLAY_WINDOW: - gtk_widget_show(w_frameskip); gtk_widget_show(l_frameskip); -#ifdef ENABLE_FBDEV_DGA - gtk_widget_show(w_display_x); gtk_widget_show(l_display_x); - gtk_widget_show(w_display_y); gtk_widget_show(l_display_y); - gtk_widget_hide(w_fbdev_name); gtk_widget_hide(l_fbdev_name); -#endif - break; - case DISPLAY_SCREEN: - gtk_widget_hide(w_frameskip); gtk_widget_hide(l_frameskip); -#ifdef ENABLE_FBDEV_DGA - gtk_widget_hide(w_display_x); gtk_widget_hide(l_display_x); - gtk_widget_hide(w_display_y); gtk_widget_hide(l_display_y); - gtk_widget_show(w_fbdev_name); gtk_widget_show(l_fbdev_name); -#endif - break; - } -} - -// "Window" video type selected -static void mn_window(...) -{ - display_type = DISPLAY_WINDOW; - hide_show_graphics_widgets(); -} - -// "Fullscreen" video type selected -static void mn_fullscreen(...) -{ - display_type = DISPLAY_SCREEN; - hide_show_graphics_widgets(); -} - -// "5 Hz".."60Hz" selected -static void mn_5hz(...) {PrefsReplaceInt32("frameskip", 12);} -static void mn_7hz(...) {PrefsReplaceInt32("frameskip", 8);} -static void mn_10hz(...) {PrefsReplaceInt32("frameskip", 6);} -static void mn_15hz(...) {PrefsReplaceInt32("frameskip", 4);} -static void mn_30hz(...) {PrefsReplaceInt32("frameskip", 2);} -static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);} -static void mn_dynamic(...) {PrefsReplaceInt32("frameskip", 0);} - -// Set sensitivity of widgets -static void set_graphics_sensitive(void) -{ - const bool sound_enabled = !PrefsFindBool("nosound"); - gtk_widget_set_sensitive(w_dspdevice_file, sound_enabled); - gtk_widget_set_sensitive(w_mixerdevice_file, sound_enabled); -} - -// "Disable Sound Output" button toggled -static void tb_nosound(GtkWidget *widget) -{ - PrefsReplaceBool("nosound", GTK_TOGGLE_BUTTON(widget)->active); - set_graphics_sensitive(); -} - -// Read graphics preferences -static void parse_graphics_prefs(void) -{ - display_type = DISPLAY_WINDOW; - dis_width = 512; - dis_height = 384; -#ifdef ENABLE_FBDEV_DGA - fbdev_name[0] = 0; -#endif - - const char *str = PrefsFindString("screen"); - if (str) { - if (sscanf(str, "win/%d/%d", &dis_width, &dis_height) == 2) - display_type = DISPLAY_WINDOW; -#ifdef ENABLE_FBDEV_DGA - else if (sscanf(str, "dga/%255s", fbdev_name) == 1) -#else - else if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2) -#endif - display_type = DISPLAY_SCREEN; - } -} - -// Read settings from widgets and set preferences -static void read_graphics_settings(void) -{ - const char *str; - - str = gtk_entry_get_text(GTK_ENTRY(w_display_x)); - dis_width = atoi(str); - - str = gtk_entry_get_text(GTK_ENTRY(w_display_y)); - dis_height = atoi(str); - - char pref[256]; - switch (display_type) { - case DISPLAY_WINDOW: - sprintf(pref, "win/%d/%d", dis_width, dis_height); - break; - case DISPLAY_SCREEN: -#ifdef ENABLE_FBDEV_DGA - str = gtk_entry_get_text(GTK_ENTRY(w_fbdev_name)); - sprintf(pref, "dga/%s", str); -#else - sprintf(pref, "dga/%d/%d", dis_width, dis_height); -#endif - break; - default: - PrefsRemoveItem("screen"); - return; - } - PrefsReplaceString("screen", pref); - -#ifdef ENABLE_FBDEV_DGA - str = get_file_entry_path(w_fbdevice_file); - if (str && strlen(str)) - PrefsReplaceString("fbdevicefile", str); - else - PrefsRemoveItem("fbdevicefile"); -#endif - PrefsReplaceString("dsp", get_file_entry_path(w_dspdevice_file)); - PrefsReplaceString("mixer", get_file_entry_path(w_mixerdevice_file)); -} - -// Create "Graphics/Sound" pane -static void create_graphics_pane(GtkWidget *top) -{ - GtkWidget *box, *table, *label, *opt, *menu, *combo; - char str[32]; - - parse_graphics_prefs(); - - box = make_pane(top, STR_GRAPHICS_SOUND_PANE_TITLE); - table = make_table(box, 2, 5); - - label = gtk_label_new(GetString(STR_VIDEO_TYPE_CTRL)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - opt = gtk_option_menu_new(); - gtk_widget_show(opt); - menu = gtk_menu_new(); - add_menu_item(menu, STR_WINDOW_LAB, GTK_SIGNAL_FUNC(mn_window)); - add_menu_item(menu, STR_FULLSCREEN_LAB, GTK_SIGNAL_FUNC(mn_fullscreen)); - switch (display_type) { - case DISPLAY_WINDOW: - gtk_menu_set_active(GTK_MENU(menu), 0); - break; - case DISPLAY_SCREEN: - gtk_menu_set_active(GTK_MENU(menu), 1); - break; - } - gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu); - gtk_table_attach(GTK_TABLE(table), opt, 1, 2, 0, 1, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4); - - l_frameskip = gtk_label_new(GetString(STR_FRAMESKIP_CTRL)); - gtk_widget_show(l_frameskip); - gtk_table_attach(GTK_TABLE(table), l_frameskip, 0, 1, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - w_frameskip = gtk_option_menu_new(); - gtk_widget_show(w_frameskip); - menu = gtk_menu_new(); - add_menu_item(menu, STR_REF_5HZ_LAB, GTK_SIGNAL_FUNC(mn_5hz)); - add_menu_item(menu, STR_REF_7_5HZ_LAB, GTK_SIGNAL_FUNC(mn_7hz)); - add_menu_item(menu, STR_REF_10HZ_LAB, GTK_SIGNAL_FUNC(mn_10hz)); - add_menu_item(menu, STR_REF_15HZ_LAB, GTK_SIGNAL_FUNC(mn_15hz)); - add_menu_item(menu, STR_REF_30HZ_LAB, GTK_SIGNAL_FUNC(mn_30hz)); - add_menu_item(menu, STR_REF_60HZ_LAB, GTK_SIGNAL_FUNC(mn_60hz)); - add_menu_item(menu, STR_REF_DYNAMIC_LAB, GTK_SIGNAL_FUNC(mn_dynamic)); - int frameskip = PrefsFindInt32("frameskip"); - int item = -1; - switch (frameskip) { - case 12: item = 0; break; - case 8: item = 1; break; - case 6: item = 2; break; - case 4: item = 3; break; - case 2: item = 4; break; - case 1: item = 5; break; - case 0: item = 6; break; - } - if (item >= 0) - gtk_menu_set_active(GTK_MENU(menu), item); - gtk_option_menu_set_menu(GTK_OPTION_MENU(w_frameskip), menu); - gtk_table_attach(GTK_TABLE(table), w_frameskip, 1, 2, 1, 2, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4); - - l_display_x = gtk_label_new(GetString(STR_DISPLAY_X_CTRL)); - gtk_widget_show(l_display_x); - gtk_table_attach(GTK_TABLE(table), l_display_x, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - combo = gtk_combo_new(); - gtk_widget_show(combo); - GList *glist1 = NULL; - glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_512_LAB)); - glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_640_LAB)); - glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_800_LAB)); - glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_1024_LAB)); - glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_MAX_LAB)); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist1); - if (dis_width) - sprintf(str, "%d", dis_width); - else - strcpy(str, GetString(STR_SIZE_MAX_LAB)); - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str); - gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 2, 3, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4); - w_display_x = GTK_COMBO(combo)->entry; - - l_display_y = gtk_label_new(GetString(STR_DISPLAY_Y_CTRL)); - gtk_widget_show(l_display_y); - gtk_table_attach(GTK_TABLE(table), l_display_y, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - combo = gtk_combo_new(); - gtk_widget_show(combo); - GList *glist2 = NULL; - glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_384_LAB)); - glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_480_LAB)); - glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_600_LAB)); - glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_768_LAB)); - glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_MAX_LAB)); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist2); - if (dis_height) - sprintf(str, "%d", dis_height); - else - strcpy(str, GetString(STR_SIZE_MAX_LAB)); - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str); - gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4); - w_display_y = GTK_COMBO(combo)->entry; - -#ifdef ENABLE_FBDEV_DGA - l_fbdev_name = gtk_label_new(GetString(STR_FBDEV_NAME_CTRL)); - gtk_widget_show(l_fbdev_name); - gtk_table_attach(GTK_TABLE(table), l_fbdev_name, 0, 1, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - w_fbdev_name = gtk_entry_new(); - gtk_widget_show(w_fbdev_name); - gtk_entry_set_text(GTK_ENTRY(w_fbdev_name), fbdev_name); - gtk_table_attach(GTK_TABLE(table), w_fbdev_name, 1, 2, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - w_fbdevice_file = make_file_entry(box, STR_FBDEVICE_FILE_CTRL, "fbdevicefile"); -#endif - - make_separator(box); - make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound)); - w_dspdevice_file = make_file_entry(box, STR_DSPDEVICE_FILE_CTRL, "dsp"); - w_mixerdevice_file = make_file_entry(box, STR_MIXERDEVICE_FILE_CTRL, "mixer"); - - set_graphics_sensitive(); - - hide_show_graphics_widgets(); -} - - -/* - * "Input" pane - */ - -static GtkWidget *w_keycode_file; -static GtkWidget *w_mouse_wheel_lines; - -// Set sensitivity of widgets -static void set_input_sensitive(void) -{ - const bool use_keycodes = PrefsFindBool("keycodes"); - gtk_widget_set_sensitive(w_keycode_file, use_keycodes); - gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_keycode_file), "chooser_button")), use_keycodes); - gtk_widget_set_sensitive(w_mouse_wheel_lines, PrefsFindInt32("mousewheelmode") == 1); -} - -// "Use Raw Keycodes" button toggled -static void tb_keycodes(GtkWidget *widget) -{ - PrefsReplaceBool("keycodes", GTK_TOGGLE_BUTTON(widget)->active); - set_input_sensitive(); -} - -// "Mouse Wheel Mode" selected -static void mn_wheel_page(...) {PrefsReplaceInt32("mousewheelmode", 0); set_input_sensitive();} -static void mn_wheel_cursor(...) {PrefsReplaceInt32("mousewheelmode", 1); set_input_sensitive();} - -// Read settings from widgets and set preferences -static void read_input_settings(void) -{ - const char *str = get_file_entry_path(w_keycode_file); - if (str && strlen(str)) - PrefsReplaceString("keycodefile", str); - else - PrefsRemoveItem("keycodefile"); - - PrefsReplaceInt32("mousewheellines", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w_mouse_wheel_lines))); -} - -// Create "Input" pane -static void create_input_pane(GtkWidget *top) -{ - GtkWidget *box, *hbox, *label, *button; - GtkObject *adj; - - box = make_pane(top, STR_INPUT_PANE_TITLE); - - make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes)); - - hbox = gtk_hbox_new(FALSE, 4); - gtk_widget_show(hbox); - gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0); - - label = gtk_label_new(GetString(STR_KEYCODES_CTRL)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - const char *str = PrefsFindString("keycodefile"); - if (str == NULL) - str = ""; - - w_keycode_file = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str); - gtk_widget_show(w_keycode_file); - gtk_box_pack_start(GTK_BOX(hbox), w_keycode_file, TRUE, TRUE, 0); - - button = make_browse_button(w_keycode_file); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - g_object_set_data(G_OBJECT(w_keycode_file), "chooser_button", button); - - make_separator(box); - - static const opt_desc options[] = { - {STR_MOUSEWHEELMODE_PAGE_LAB, GTK_SIGNAL_FUNC(mn_wheel_page)}, - {STR_MOUSEWHEELMODE_CURSOR_LAB, GTK_SIGNAL_FUNC(mn_wheel_cursor)}, - {0, NULL} - }; - int wheelmode = PrefsFindInt32("mousewheelmode"), active = 0; - switch (wheelmode) { - case 0: active = 0; break; - case 1: active = 1; break; - } - make_option_menu(box, STR_MOUSEWHEELMODE_CTRL, options, active); - - hbox = gtk_hbox_new(FALSE, 4); - gtk_widget_show(hbox); - gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0); - - label = gtk_label_new(GetString(STR_MOUSEWHEELLINES_CTRL)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - adj = gtk_adjustment_new(PrefsFindInt32("mousewheellines"), 1, 1000, 1, 5, 0); - w_mouse_wheel_lines = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 0.0, 0); - gtk_widget_show(w_mouse_wheel_lines); - gtk_box_pack_start(GTK_BOX(hbox), w_mouse_wheel_lines, FALSE, FALSE, 0); - - set_input_sensitive(); -} - - -/* - * "Serial/Network" pane - */ - -static GtkWidget *w_seriala, *w_serialb, *w_ether, *w_udp_port; - -// Set sensitivity of widgets -static void set_serial_sensitive(void) -{ -#if SUPPORTS_UDP_TUNNEL - gtk_widget_set_sensitive(w_ether, !PrefsFindBool("udptunnel")); - gtk_widget_set_sensitive(w_udp_port, PrefsFindBool("udptunnel")); -#endif -} - -// "Tunnel AppleTalk over IP" button toggled -static void tb_udptunnel(GtkWidget *widget) -{ - PrefsReplaceBool("udptunnel", GTK_TOGGLE_BUTTON(widget)->active); - set_serial_sensitive(); -} - -// Read settings from widgets and set preferences -static void read_serial_settings(void) -{ - const char *str; - - str = gtk_entry_get_text(GTK_ENTRY(w_seriala)); - PrefsReplaceString("seriala", str); - - str = gtk_entry_get_text(GTK_ENTRY(w_serialb)); - PrefsReplaceString("serialb", str); - - str = gtk_entry_get_text(GTK_ENTRY(w_ether)); - if (str && strlen(str)) - PrefsReplaceString("ether", str); - else - PrefsRemoveItem("ether"); - -#if SUPPORTS_UDP_TUNNEL - PrefsReplaceInt32("udpport", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w_udp_port))); -#endif -} - -// Add names of serial devices -static gint gl_str_cmp(gconstpointer a, gconstpointer b) -{ - return strcmp((char *)a, (char *)b); -} - -static GList *add_serial_names(void) -{ - GList *glist = NULL; - - // Search /dev for ttyS* and lp* - DIR *d = opendir("/dev"); - if (d) { - struct dirent *de; - while ((de = readdir(d)) != NULL) { -#if defined(__linux__) - if (strncmp(de->d_name, "ttyS", 4) == 0 || strncmp(de->d_name, "lp", 2) == 0) { -#elif defined(__FreeBSD__) - if (strncmp(de->d_name, "cuaa", 4) == 0 || strncmp(de->d_name, "lpt", 3) == 0) { -#elif defined(__NetBSD__) - if (strncmp(de->d_name, "tty0", 4) == 0 || strncmp(de->d_name, "lpt", 3) == 0) { -#elif defined(sgi) - if (strncmp(de->d_name, "ttyf", 4) == 0 || strncmp(de->d_name, "plp", 3) == 0) { -#else - if (false) { -#endif - char *str = new char[64]; - sprintf(str, "/dev/%s", de->d_name); - glist = g_list_append(glist, str); - } - } - closedir(d); - } - if (glist) - g_list_sort(glist, gl_str_cmp); - else - glist = g_list_append(glist, (void *)GetString(STR_NONE_LAB)); - return glist; -} - -// Add names of ethernet interfaces -static GList *add_ether_names(void) -{ - GList *glist = NULL; - - // Get list of all Ethernet interfaces - int s = socket(PF_INET, SOCK_DGRAM, 0); - if (s >= 0) { - char inbuf[8192]; - struct ifconf ifc; - ifc.ifc_len = sizeof(inbuf); - ifc.ifc_buf = inbuf; - if (ioctl(s, SIOCGIFCONF, &ifc) == 0) { - struct ifreq req, *ifr = ifc.ifc_req; - for (int i=0; iifr_name, 63); - glist = g_list_append(glist, str); - } - } - } - close(s); - } -#ifdef HAVE_SLIRP - static char s_slirp[] = "slirp"; - glist = g_list_append(glist, s_slirp); -#endif - if (glist) - g_list_sort(glist, gl_str_cmp); - else - glist = g_list_append(glist, (void *)GetString(STR_NONE_LAB)); - return glist; -} - -// Create "Serial/Network" pane -static void create_serial_pane(GtkWidget *top) -{ - GtkWidget *box, *hbox, *table, *label, *combo, *sep; - GtkObject *adj; - - box = make_pane(top, STR_SERIAL_NETWORK_PANE_TITLE); - table = make_table(box, 2, 4); - - label = gtk_label_new(GetString(STR_SERIALA_CTRL)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - GList *glist = add_serial_names(); - combo = gtk_combo_new(); - gtk_widget_show(combo); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist); - const char *str = PrefsFindString("seriala"); - if (str == NULL) - str = ""; - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str); - gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - w_seriala = GTK_COMBO(combo)->entry; - - label = gtk_label_new(GetString(STR_SERIALB_CTRL)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - combo = gtk_combo_new(); - gtk_widget_show(combo); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist); - str = PrefsFindString("serialb"); - if (str == NULL) - str = ""; - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str); - gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 1, 2, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - w_serialb = GTK_COMBO(combo)->entry; - - sep = gtk_hseparator_new(); - gtk_widget_show(sep); - gtk_table_attach(GTK_TABLE(table), sep, 0, 2, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - label = gtk_label_new(GetString(STR_ETHERNET_IF_CTRL)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - glist = add_ether_names(); - combo = gtk_combo_new(); - gtk_widget_show(combo); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist); - str = PrefsFindString("ether"); - if (str == NULL) - str = ""; - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str); - gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - w_ether = GTK_COMBO(combo)->entry; - -#if SUPPORTS_UDP_TUNNEL - make_checkbox(box, STR_UDPTUNNEL_CTRL, "udptunnel", GTK_SIGNAL_FUNC(tb_udptunnel)); - - hbox = gtk_hbox_new(FALSE, 4); - gtk_widget_show(hbox); - gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0); - - label = gtk_label_new(GetString(STR_UDPPORT_CTRL)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - adj = gtk_adjustment_new(PrefsFindInt32("udpport"), 1, 65535, 1, 5, 0); - w_udp_port = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 0.0, 0); - gtk_widget_show(w_udp_port); - gtk_box_pack_start(GTK_BOX(hbox), w_udp_port, FALSE, FALSE, 0); -#endif - - set_serial_sensitive(); -} - - -/* - * "Memory/Misc" pane - */ - -static GtkWidget *w_ramsize; -static GtkWidget *w_rom_file; - -// Don't use CPU when idle? -static void tb_idlewait(GtkWidget *widget) -{ - PrefsReplaceBool("idlewait", GTK_TOGGLE_BUTTON(widget)->active); -} - -// "Ignore SEGV" button toggled -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION -static void tb_ignoresegv(GtkWidget *widget) -{ - PrefsReplaceBool("ignoresegv", GTK_TOGGLE_BUTTON(widget)->active); -} -#endif - -// Model ID selected -static void mn_modelid_5(...) {PrefsReplaceInt32("modelid", 5);} -static void mn_modelid_14(...) {PrefsReplaceInt32("modelid", 14);} - -// CPU/FPU type -static void mn_cpu_68020(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", false);} -static void mn_cpu_68020_fpu(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", true);} -static void mn_cpu_68030(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", false);} -static void mn_cpu_68030_fpu(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", true);} -static void mn_cpu_68040(...) {PrefsReplaceInt32("cpu", 4); PrefsReplaceBool("fpu", true);} - -// Read settings from widgets and set preferences -static void read_memory_settings(void) -{ - const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_ramsize)->entry)); - PrefsReplaceInt32("ramsize", atoi(str) << 20); - - str = get_file_entry_path(w_rom_file); - if (str && strlen(str)) - PrefsReplaceString("rom", str); - else - PrefsRemoveItem("rom"); - -} - -// Create "Memory/Misc" pane -static void create_memory_pane(GtkWidget *top) -{ - GtkWidget *box, *table; - - box = make_pane(top, STR_MEMORY_MISC_PANE_TITLE); - table = make_table(box, 2, 5); - - static const combo_desc options[] = { - STR_RAMSIZE_2MB_LAB, - STR_RAMSIZE_4MB_LAB, - STR_RAMSIZE_8MB_LAB, - STR_RAMSIZE_16MB_LAB, - STR_RAMSIZE_32MB_LAB, - STR_RAMSIZE_64MB_LAB, - STR_RAMSIZE_128MB_LAB, - STR_RAMSIZE_256MB_LAB, - STR_RAMSIZE_512MB_LAB, - STR_RAMSIZE_1024MB_LAB, - 0 - }; - char default_ramsize[10]; - sprintf(default_ramsize, "%d", PrefsFindInt32("ramsize") >> 20); - w_ramsize = table_make_combobox(table, 0, STR_RAMSIZE_CTRL, default_ramsize, options); - - static const opt_desc model_options[] = { - {STR_MODELID_5_LAB, GTK_SIGNAL_FUNC(mn_modelid_5)}, - {STR_MODELID_14_LAB, GTK_SIGNAL_FUNC(mn_modelid_14)}, - {0, NULL} - }; - int modelid = PrefsFindInt32("modelid"), active = 0; - switch (modelid) { - case 5: active = 0; break; - case 14: active = 1; break; - } - table_make_option_menu(table, 2, STR_MODELID_CTRL, model_options, active); - -#if EMULATED_68K - static const opt_desc cpu_options[] = { - {STR_CPU_68020_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020)}, - {STR_CPU_68020_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020_fpu)}, - {STR_CPU_68030_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030)}, - {STR_CPU_68030_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030_fpu)}, - {STR_CPU_68040_LAB, GTK_SIGNAL_FUNC(mn_cpu_68040)}, - {0, NULL} - }; - int cpu = PrefsFindInt32("cpu"); - bool fpu = PrefsFindBool("fpu"); - active = 0; - switch (cpu) { - case 2: active = fpu ? 1 : 0; break; - case 3: active = fpu ? 3 : 2; break; - case 4: active = 4; - } - table_make_option_menu(table, 3, STR_CPU_CTRL, cpu_options, active); -#endif - - w_rom_file = table_make_file_entry(table, 4, STR_ROM_FILE_CTRL, "rom"); - - make_checkbox(box, STR_IDLEWAIT_CTRL, "idlewait", GTK_SIGNAL_FUNC(tb_idlewait)); -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv)); -#endif -} - - -/* - * Read settings from widgets and set preferences - */ - -static void read_settings(void) -{ - read_volumes_settings(); - read_scsi_settings(); - read_graphics_settings(); - read_input_settings(); - read_serial_settings(); - read_memory_settings(); - read_jit_settings(); -} - - -#ifdef STANDALONE_GUI -#include -#include -#include "rpc.h" - -/* - * Fake unused data and functions - */ - -uint8 XPRAM[XPRAM_SIZE]; -void MountVolume(void *fh) { } -void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { } - -#if defined __APPLE__ && defined __MACH__ -void DarwinSysInit(void) { } -void DarwinSysExit(void) { } -void DarwinAddFloppyPrefs(void) { } -void DarwinAddSerialPrefs(void) { } -bool DarwinCDReadTOC(char *, uint8 *) { } -#endif - - -/* - * Display alert - */ - -static void dl_destroyed(void) -{ - gtk_main_quit(); -} - -static void display_alert(int title_id, int prefix_id, int button_id, const char *text) -{ - char str[256]; - sprintf(str, GetString(prefix_id), text); - - GtkWidget *dialog = gtk_dialog_new(); - gtk_window_set_title(GTK_WINDOW(dialog), GetString(title_id)); - gtk_container_border_width(GTK_CONTAINER(dialog), 5); - gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150); - gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(dl_destroyed), NULL); - - GtkWidget *label = gtk_label_new(str); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); - - GtkWidget *button = gtk_button_new_with_label(GetString(button_id)); - gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog)); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_widget_grab_default(button); - gtk_widget_show(dialog); - - gtk_main(); -} - - -/* - * Display error alert - */ - -void ErrorAlert(const char *text) -{ - display_alert(STR_ERROR_ALERT_TITLE, STR_GUI_ERROR_PREFIX, STR_QUIT_BUTTON, text); -} - - -/* - * Display warning alert - */ - -void WarningAlert(const char *text) -{ - display_alert(STR_WARNING_ALERT_TITLE, STR_GUI_WARNING_PREFIX, STR_OK_BUTTON, text); -} - - -/* - * RPC handlers - */ - -static GMainLoop *g_gui_loop; - -static int handle_ErrorAlert(rpc_connection_t *connection) -{ - D(bug("handle_ErrorAlert\n")); - - int error; - char *str; - if ((error = rpc_method_get_args(connection, RPC_TYPE_STRING, &str, RPC_TYPE_INVALID)) < 0) - return error; - - ErrorAlert(str); - free(str); - return RPC_ERROR_NO_ERROR; -} - -static int handle_WarningAlert(rpc_connection_t *connection) -{ - D(bug("handle_WarningAlert\n")); - - int error; - char *str; - if ((error = rpc_method_get_args(connection, RPC_TYPE_STRING, &str, RPC_TYPE_INVALID)) < 0) - return error; - - WarningAlert(str); - free(str); - return RPC_ERROR_NO_ERROR; -} - -static int handle_Exit(rpc_connection_t *connection) -{ - D(bug("handle_Exit\n")); - - g_main_quit(g_gui_loop); - return RPC_ERROR_NO_ERROR; -} - - -/* - * SIGCHLD handler - */ - -static char g_app_path[PATH_MAX]; -static rpc_connection_t *g_gui_connection = NULL; - -static void sigchld_handler(int sig, siginfo_t *sip, void *) -{ - D(bug("Child %d exitted with status = %x\n", sip->si_pid, sip->si_status)); - - // XXX perform a new wait because sip->si_status is sometimes not - // the exit _value_ on MacOS X but rather the usual status field - // from waitpid() -- we could arrange this code in some other way... - int status; - if (waitpid(sip->si_pid, &status, 0) < 0) - status = sip->si_status; - if (WIFEXITED(status)) - status = WEXITSTATUS(status); - if (status & 0x80) - status |= -1 ^0xff; - - if (status < 0) { // negative -> execlp/-errno - char str[256]; - sprintf(str, GetString(STR_NO_B2_EXE_FOUND), g_app_path, strerror(-status)); - ErrorAlert(str); - status = 1; - } - - if (status != 0) { - if (g_gui_connection) - rpc_exit(g_gui_connection); - exit(status); - } -} - - -/* - * Start standalone GUI - */ - -int main(int argc, char *argv[]) -{ -#ifdef HAVE_GNOMEUI - // Init GNOME/GTK - char version[16]; - sprintf(version, "%d.%d", VERSION_MAJOR, VERSION_MINOR); - gnome_init("Basilisk II", version, argc, argv); -#else - // Init GTK - gtk_set_locale(); - gtk_init(&argc, &argv); -#endif - - // Read preferences - PrefsInit(NULL, argc, argv); - - // Show preferences editor - bool start = PrefsEditor(); - - // Exit preferences - PrefsExit(); - - // Transfer control to the executable - if (start) { - char gui_connection_path[64]; - sprintf(gui_connection_path, "/org/BasiliskII/GUI/%d", getpid()); - - // Catch exits from the child process - struct sigaction sigchld_sa, old_sigchld_sa; - sigemptyset(&sigchld_sa.sa_mask); - sigchld_sa.sa_sigaction = sigchld_handler; - sigchld_sa.sa_flags = SA_NOCLDSTOP | SA_SIGINFO; - if (sigaction(SIGCHLD, &sigchld_sa, &old_sigchld_sa) < 0) { - char str[256]; - sprintf(str, GetString(STR_SIG_INSTALL_ERR), SIGCHLD, strerror(errno)); - ErrorAlert(str); - return 1; - } - - // Search and run the BasiliskII executable - char *p; - strcpy(g_app_path, argv[0]); - if ((p = strstr(g_app_path, "BasiliskIIGUI.app/Contents/MacOS")) != NULL) { - strcpy(p, "BasiliskII.app/Contents/MacOS/BasiliskII"); - if (access(g_app_path, X_OK) < 0) { - char str[256]; - sprintf(str, GetString(STR_NO_B2_EXE_FOUND), g_app_path, strerror(errno)); - WarningAlert(str); - strcpy(g_app_path, "/Applications/BasiliskII.app/Contents/MacOS/BasiliskII"); - } - } else { - p = strrchr(g_app_path, '/'); - p = p ? p + 1 : g_app_path; - strcpy(p, "BasiliskII"); - } - - int pid = fork(); - if (pid == 0) { - D(bug("Trying to execute %s\n", g_app_path)); - execlp(g_app_path, g_app_path, "--gui-connection", gui_connection_path, (char *)NULL); -#ifdef _POSIX_PRIORITY_SCHEDULING - // XXX get a chance to run the parent process so that to not confuse/upset GTK... - sched_yield(); -#endif - _exit(-errno); - } - - // Establish a connection to Basilisk II - if ((g_gui_connection = rpc_init_server(gui_connection_path)) == NULL) { - printf("ERROR: failed to initialize GUI-side RPC server connection\n"); - return 1; - } - static const rpc_method_descriptor_t vtable[] = { - { RPC_METHOD_ERROR_ALERT, handle_ErrorAlert }, - { RPC_METHOD_WARNING_ALERT, handle_WarningAlert }, - { RPC_METHOD_EXIT, handle_Exit } - }; - if (rpc_method_add_callbacks(g_gui_connection, vtable, sizeof(vtable) / sizeof(vtable[0])) < 0) { - printf("ERROR: failed to setup GUI method callbacks\n"); - return 1; - } - int socket; - if ((socket = rpc_listen_socket(g_gui_connection)) < 0) { - printf("ERROR: failed to initialize RPC server thread\n"); - return 1; - } - - g_gui_loop = g_main_new(TRUE); - while (g_main_is_running(g_gui_loop)) { - - // Process a few events pending - const int N_EVENTS_DISPATCH = 10; - for (int i = 0; i < N_EVENTS_DISPATCH; i++) { - if (!g_main_iteration(FALSE)) - break; - } - - // Check for RPC events (100 ms timeout) - int ret = rpc_wait_dispatch(g_gui_connection, 100000); - if (ret == 0) - continue; - if (ret < 0) - break; - rpc_dispatch(g_gui_connection); - } - - rpc_exit(g_gui_connection); - return 0; - } - - return 0; -} -#endif diff --git a/BasiliskII/src/Unix/prefs_unix.cpp b/BasiliskII/src/Unix/prefs_unix.cpp index a92cd640..39e4fba5 100644 --- a/BasiliskII/src/Unix/prefs_unix.cpp +++ b/BasiliskII/src/Unix/prefs_unix.cpp @@ -120,21 +120,8 @@ void AddPlatformPrefsDefaults(void) PrefsReplaceString("extfs", "/"); PrefsReplaceInt32("mousewheelmode", 1); PrefsReplaceInt32("mousewheellines", 3); -#ifdef __linux__ - if (access("/dev/sound/dsp", F_OK) == 0) { - PrefsReplaceString("dsp", "/dev/sound/dsp"); - } else { - PrefsReplaceString("dsp", "/dev/dsp"); - } - if (access("/dev/sound/mixer", F_OK) == 0) { - PrefsReplaceString("mixer", "/dev/sound/mixer"); - } else { - PrefsReplaceString("mixer", "/dev/mixer"); - } -#else PrefsReplaceString("dsp", "/dev/dsp"); PrefsReplaceString("mixer", "/dev/mixer"); -#endif #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION PrefsAddBool("ignoresegv", false); #endif diff --git a/BasiliskII/src/Unix/rpc_unix.cpp b/BasiliskII/src/Unix/rpc_unix.cpp index 378c5dd6..cbc23b60 100644 --- a/BasiliskII/src/Unix/rpc_unix.cpp +++ b/BasiliskII/src/Unix/rpc_unix.cpp @@ -48,11 +48,6 @@ #define NON_BLOCKING_IO 0 -#if defined __linux__ -#define USE_ABSTRACT_NAMESPACES 1 -#endif - - /* ====================================================================== */ /* === PThreads Glue === */ /* ====================================================================== */ diff --git a/BasiliskII/src/Unix/serial_unix.cpp b/BasiliskII/src/Unix/serial_unix.cpp deleted file mode 100644 index 81922b43..00000000 --- a/BasiliskII/src/Unix/serial_unix.cpp +++ /dev/null @@ -1,833 +0,0 @@ -/* - * serial_unix.cpp - Serial device driver, Unix specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include -#include -#include -#ifdef __linux__ -#include -#include -#include -#endif - -#include "cpu_emulation.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "serial.h" -#include "serial_defs.h" - -extern "C" { -#include "sshpty.h" -} - - -#define DEBUG 0 -#include "debug.h" - -#define MONITOR 0 - - -// IRIX missing or unsupported defines -#ifdef sgi -#ifndef CRTSCTS -#define CRTSCTS CNEW_RTSCTS -#endif -#ifndef B230400 -#define B230400 B115200 -#endif -#endif - - -// Missing functions -#ifndef HAVE_CFMAKERAW -static int cfmakeraw(struct termios *termios_p) -{ - termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); - termios_p->c_oflag &= ~OPOST; - termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); - termios_p->c_cflag &= ~(CSIZE|PARENB); - termios_p->c_cflag |= CS8; - return 0; -} -#endif - - -// Driver private variables -class XSERDPort : public SERDPort { -public: - XSERDPort(const char *dev) - { - device_name = dev; - protocol = serial; - fd = -1; - pid = 0; - input_thread_active = output_thread_active = false; - - Set_pthread_attr(&thread_attr, 2); - } - - virtual ~XSERDPort() - { - if (input_thread_active) { - input_thread_cancel = true; -#ifdef HAVE_PTHREAD_CANCEL - pthread_cancel(input_thread); -#endif - pthread_join(input_thread, NULL); - sem_destroy(&input_signal); - input_thread_active = false; - } - if (output_thread_active) { - output_thread_cancel = true; -#ifdef HAVE_PTHREAD_CANCEL - pthread_cancel(output_thread); -#endif - pthread_join(output_thread, NULL); - sem_destroy(&output_signal); - output_thread_active = false; - } - } - - virtual int16 open(uint16 config); - virtual int16 prime_in(uint32 pb, uint32 dce); - virtual int16 prime_out(uint32 pb, uint32 dce); - virtual int16 control(uint32 pb, uint32 dce, uint16 code); - virtual int16 status(uint32 pb, uint32 dce, uint16 code); - virtual int16 close(void); - -private: - bool open_pty(void); - bool configure(uint16 config); - void set_handshake(uint32 s, bool with_dtr); - static void *input_func(void *arg); - static void *output_func(void *arg); - - const char *device_name; // Device name - enum {serial, parallel, pty, midi} - protocol; // Type of device - int fd; // FD of device - pid_t pid; // PID of child process - - bool io_killed; // Flag: KillIO called, I/O threads must not call deferred tasks - bool quitting; // Flag: Quit threads - - pthread_attr_t thread_attr; // Input/output thread attributes - - bool input_thread_active; // Flag: Input thread installed - volatile bool input_thread_cancel; // Flag: Cancel input thread - pthread_t input_thread; // Data input thread - sem_t input_signal; // Signal for input thread: execute command - uint32 input_pb; // Command parameter for input thread - - bool output_thread_active; // Flag: Output thread installed - volatile bool output_thread_cancel; // Flag: Cancel output thread - pthread_t output_thread; // Data output thread - sem_t output_signal; // Signal for output thread: execute command - uint32 output_pb; // Command parameter for output thread - - struct termios mode; // Terminal configuration -}; - - -/* - * Initialization - */ - -void SerialInit(void) -{ - // Read serial preferences and create structs for both ports - the_serd_port[0] = new XSERDPort(PrefsFindString("seriala")); - the_serd_port[1] = new XSERDPort(PrefsFindString("serialb")); -} - - -/* - * Deinitialization - */ - -void SerialExit(void) -{ - delete (XSERDPort *)the_serd_port[0]; - delete (XSERDPort *)the_serd_port[1]; -} - - -/* - * Open serial port - */ - -int16 XSERDPort::open(uint16 config) -{ - // Don't open NULL name devices - if (device_name == NULL) - return openErr; - - // Init variables - io_killed = false; - quitting = false; - - // Open port, according to the syntax of the path - if (device_name[0] == '|') { - // Open a process via ptys - if (!open_pty()) - goto open_error; - } - else if (!strcmp(device_name, "midi")) { - // MIDI: not yet implemented - return openErr; - } - else { - // Device special file - fd = ::open(device_name, O_RDWR); - if (fd < 0) - goto open_error; - -#if defined(__linux__) - // Parallel port? - struct stat st; - if (fstat(fd, &st) == 0) - if (S_ISCHR(st.st_mode)) - protocol = ((MAJOR(st.st_rdev) == LP_MAJOR) ? parallel : serial); -#elif defined(__FreeBSD__) || defined(__NetBSD__) - // Parallel port? - struct stat st; - if (fstat(fd, &st) == 0) - if (S_ISCHR(st.st_mode)) - protocol = (((st.st_rdev >> 16) == 16) ? parallel : serial); -#endif - } - - // Configure port for raw mode - if (protocol == serial || protocol == pty) { - if (tcgetattr(fd, &mode) < 0) - goto open_error; - cfmakeraw(&mode); - mode.c_cflag |= HUPCL; - mode.c_cc[VMIN] = 1; - mode.c_cc[VTIME] = 0; - tcsetattr(fd, TCSAFLUSH, &mode); - } - configure(config); - - // Start input/output threads - input_thread_cancel = false; - output_thread_cancel = false; - if (sem_init(&input_signal, 0, 0) < 0) - goto open_error; - if (sem_init(&output_signal, 0, 0) < 0) - goto open_error; - input_thread_active = (pthread_create(&input_thread, &thread_attr, input_func, this) == 0); - output_thread_active = (pthread_create(&output_thread, &thread_attr, output_func, this) == 0); - if (!input_thread_active || !output_thread_active) - goto open_error; - return noErr; - -open_error: - if (input_thread_active) { - input_thread_cancel = true; -#ifdef HAVE_PTHREAD_CANCEL - pthread_cancel(input_thread); -#endif - pthread_join(input_thread, NULL); - sem_destroy(&input_signal); - input_thread_active = false; - } - if (output_thread_active) { - output_thread_cancel = true; -#ifdef HAVE_PTHREAD_CANCEL - pthread_cancel(output_thread); -#endif - pthread_join(output_thread, NULL); - sem_destroy(&output_signal); - output_thread_active = false; - } - if (fd > 0) { - ::close(fd); - fd = -1; - } - return openErr; -} - - -/* - * Read data from port - */ - -int16 XSERDPort::prime_in(uint32 pb, uint32 dce) -{ - // Send input command to input_thread - read_done = false; - read_pending = true; - input_pb = pb; - WriteMacInt32(input_dt + serdtDCE, dce); - sem_post(&input_signal); - return 1; // Command in progress -} - - -/* - * Write data to port - */ - -int16 XSERDPort::prime_out(uint32 pb, uint32 dce) -{ - // Send output command to output_thread - write_done = false; - write_pending = true; - output_pb = pb; - WriteMacInt32(output_dt + serdtDCE, dce); - sem_post(&output_signal); - return 1; // Command in progress -} - - -/* - * Control calls - */ - -int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code) -{ - switch (code) { - case 1: // KillIO - io_killed = true; - if (protocol == serial) - tcflush(fd, TCIOFLUSH); - while (read_pending || write_pending) - usleep(10000); - io_killed = false; - return noErr; - - case kSERDConfiguration: - if (configure(ReadMacInt16(pb + csParam))) - return noErr; - else - return paramErr; - - case kSERDInputBuffer: - return noErr; // Not supported under Unix - - case kSERDSerHShake: - set_handshake(pb + csParam, false); - return noErr; - - case kSERDSetBreak: - if (protocol == serial) - tcsendbreak(fd, 0); - return noErr; - - case kSERDClearBreak: - return noErr; - - case kSERDBaudRate: { - if (protocol != serial) - return noErr; - uint16 rate = ReadMacInt16(pb + csParam); - speed_t baud_rate; - if (rate <= 50) { - rate = 50; baud_rate = B50; - } else if (rate <= 75) { - rate = 75; baud_rate = B75; - } else if (rate <= 110) { - rate = 110; baud_rate = B110; - } else if (rate <= 134) { - rate = 134; baud_rate = B134; - } else if (rate <= 150) { - rate = 150; baud_rate = B150; - } else if (rate <= 200) { - rate = 200; baud_rate = B200; - } else if (rate <= 300) { - rate = 300; baud_rate = B300; - } else if (rate <= 600) { - rate = 600; baud_rate = B600; - } else if (rate <= 1200) { - rate = 1200; baud_rate = B1200; - } else if (rate <= 1800) { - rate = 1800; baud_rate = B1800; - } else if (rate <= 2400) { - rate = 2400; baud_rate = B2400; - } else if (rate <= 4800) { - rate = 4800; baud_rate = B4800; - } else if (rate <= 9600) { - rate = 9600; baud_rate = B9600; - } else if (rate <= 19200) { - rate = 19200; baud_rate = B19200; - } else if (rate <= 38400) { - rate = 38400; baud_rate = B38400; - } else if (rate <= 57600) { - rate = 57600; baud_rate = B57600; - } else { - // Just for safety in case someone wants a rate between 57600 and 65535 - rate = 57600; baud_rate = B57600; - } - WriteMacInt16(pb + csParam, rate); - cfsetispeed(&mode, baud_rate); - cfsetospeed(&mode, baud_rate); - tcsetattr(fd, TCSANOW, &mode); - return noErr; - } - - case kSERDHandshake: - case kSERDHandshakeRS232: - set_handshake(pb + csParam, true); - return noErr; - - case kSERDMiscOptions: - if (protocol != serial) - return noErr; - if (ReadMacInt8(pb + csParam) & kOptionPreserveDTR) - mode.c_cflag &= ~HUPCL; - else - mode.c_cflag |= HUPCL; - tcsetattr(fd, TCSANOW, &mode); - return noErr; - - case kSERDAssertDTR: { - if (protocol != serial) - return noErr; - unsigned int status = TIOCM_DTR; - ioctl(fd, TIOCMBIS, &status); - return noErr; - } - - case kSERDNegateDTR: { - if (protocol != serial) - return noErr; - unsigned int status = TIOCM_DTR; - ioctl(fd, TIOCMBIC, &status); - return noErr; - } - - case kSERDSetPEChar: - case kSERDSetPEAltChar: - return noErr; // Not supported under Unix - - case kSERDResetChannel: - if (protocol == serial) - tcflush(fd, TCIOFLUSH); - return noErr; - - case kSERDAssertRTS: { - if (protocol != serial) - return noErr; - unsigned int status = TIOCM_RTS; - ioctl(fd, TIOCMBIS, &status); - return noErr; - } - - case kSERDNegateRTS: { - if (protocol != serial) - return noErr; - unsigned int status = TIOCM_RTS; - ioctl(fd, TIOCMBIC, &status); - return noErr; - } - - case kSERD115KBaud: - if (protocol != serial) - return noErr; - cfsetispeed(&mode, B115200); - cfsetospeed(&mode, B115200); - tcsetattr(fd, TCSANOW, &mode); - return noErr; - - case kSERD230KBaud: - case kSERDSetHighSpeed: - if (protocol != serial) - return noErr; - cfsetispeed(&mode, B230400); - cfsetospeed(&mode, B230400); - tcsetattr(fd, TCSANOW, &mode); - return noErr; - - default: - printf("WARNING: SerialControl(): unimplemented control code %d\n", code); - return controlErr; - } -} - - -/* - * Status calls - */ - -int16 XSERDPort::status(uint32 pb, uint32 dce, uint16 code) -{ - switch (code) { - case kSERDInputCount: { - int num; - ioctl(fd, FIONREAD, &num); - WriteMacInt32(pb + csParam, num); - return noErr; - } - - case kSERDStatus: { - uint32 p = pb + csParam; - WriteMacInt8(p + staCumErrs, cum_errors); - cum_errors = 0; - WriteMacInt8(p + staXOffSent, 0); - WriteMacInt8(p + staXOffHold, 0); - WriteMacInt8(p + staRdPend, read_pending); - WriteMacInt8(p + staWrPend, write_pending); - if (protocol != serial) { - WriteMacInt8(p + staCtsHold, 0); - WriteMacInt8(p + staDsrHold, 0); - WriteMacInt8(p + staModemStatus, dsrEvent | dcdEvent | ctsEvent); - } else { - unsigned int status; - ioctl(fd, TIOCMGET, &status); - WriteMacInt8(p + staCtsHold, status & TIOCM_CTS ? 0 : 1); - WriteMacInt8(p + staDsrHold, status & TIOCM_DTR ? 0 : 1); - WriteMacInt8(p + staModemStatus, - (status & TIOCM_DSR ? dsrEvent : 0) - | (status & TIOCM_RI ? riEvent : 0) - | (status & TIOCM_CD ? dcdEvent : 0) - | (status & TIOCM_CTS ? ctsEvent : 0)); - } - return noErr; - } - - default: - printf("WARNING: SerialStatus(): unimplemented status code %d\n", code); - return statusErr; - } -} - - -/* - * Close serial port - */ - -int16 XSERDPort::close() -{ - // Kill threads - if (input_thread_active) { - quitting = true; - sem_post(&input_signal); - pthread_join(input_thread, NULL); - input_thread_active = false; - sem_destroy(&input_signal); - } - if (output_thread_active) { - quitting = true; - sem_post(&output_signal); - pthread_join(output_thread, NULL); - output_thread_active = false; - sem_destroy(&output_signal); - } - - // Close port - if (fd > 0) - ::close(fd); - fd = -1; - - // Wait for the subprocess to exit - if (pid) - waitpid(pid, NULL, 0); - pid = 0; - - return noErr; -} - - -/* - * Open a process via ptys - */ - -bool XSERDPort::open_pty(void) -{ - // Talk to a process via a pty - char slave[128]; - int slavefd; - - protocol = pty; - if (!pty_allocate(&fd, &slavefd, slave, sizeof(slave))) - return false; - - fflush(stdout); - fflush(stderr); - switch (pid = fork()) { - case -1: // error - return false; - break; - case 0: // child - ::close(fd); - - /* Make the pseudo tty our controlling tty. */ - pty_make_controlling_tty(&slavefd, slave); - - ::close(0); dup(slavefd); // Use the slave fd for stdin, - ::close(1); dup(slavefd); // stdout, - ::close(2); dup(slavefd); // and stderr. - - // - // - - // Let the shell do the dirty work - execlp("/bin/sh", "/bin/sh", "-c", ++device_name, (char *)NULL); - - // exec failed! - printf("serial_open: could not exec %s: %s\n", - "/bin/sh", strerror(errno)); - exit(1); - break; - default: // parent - // Pid was stored above - break; - } - - return true; -} - - -/* - * Configure serial port with MacOS config word - */ - -bool XSERDPort::configure(uint16 config) -{ - D(bug(" configure %04x\n", config)); - if (protocol != serial) - return true; - - // Set number of stop bits - switch (config & 0xc000) { - case stop10: - mode.c_cflag &= ~CSTOPB; - break; - case stop20: - mode.c_cflag |= CSTOPB; - break; - default: - return false; - } - - // Set parity mode - switch (config & 0x3000) { - case noParity: - mode.c_iflag &= ~INPCK; - mode.c_oflag &= ~PARENB; - break; - case oddParity: - mode.c_iflag |= INPCK; - mode.c_oflag |= PARENB; - mode.c_oflag |= PARODD; - break; - case evenParity: - mode.c_iflag |= INPCK; - mode.c_oflag |= PARENB; - mode.c_oflag &= ~PARODD; - break; - default: - return false; - } - - // Set number of data bits - switch (config & 0x0c00) { - case data5: - mode.c_cflag = mode.c_cflag & ~CSIZE | CS5; - break; - case data6: - mode.c_cflag = mode.c_cflag & ~CSIZE | CS6; - break; - case data7: - mode.c_cflag = mode.c_cflag & ~CSIZE | CS7; - break; - case data8: - mode.c_cflag = mode.c_cflag & ~CSIZE | CS8; - break; - } - - // Set baud rate - speed_t baud_rate; - switch (config & 0x03ff) { - case baud150: baud_rate = B150; break; - case baud300: baud_rate = B300; break; - case baud600: baud_rate = B600; break; - case baud1200: baud_rate = B1200; break; - case baud1800: baud_rate = B1800; break; - case baud2400: baud_rate = B2400; break; - case baud4800: baud_rate = B4800; break; - case baud9600: baud_rate = B9600; break; - case baud19200: baud_rate = B19200; break; - case baud38400: baud_rate = B38400; break; - case baud57600: baud_rate = B57600; break; - default: - return false; - } - cfsetispeed(&mode, baud_rate); - cfsetospeed(&mode, baud_rate); - tcsetattr(fd, TCSANOW, &mode); - return true; -} - - -/* - * Set serial handshaking - */ - -void XSERDPort::set_handshake(uint32 s, bool with_dtr) -{ - D(bug(" set_handshake %02x %02x %02x %02x %02x %02x %02x %02x\n", - ReadMacInt8(s + 0), ReadMacInt8(s + 1), ReadMacInt8(s + 2), ReadMacInt8(s + 3), - ReadMacInt8(s + 4), ReadMacInt8(s + 5), ReadMacInt8(s + 6), ReadMacInt8(s + 7))); - if (protocol != serial) - return; - - if (with_dtr) { - if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR)) - mode.c_cflag |= CRTSCTS; - else - mode.c_cflag &= ~CRTSCTS; - } else { - if (ReadMacInt8(s + shkFCTS)) - mode.c_cflag |= CRTSCTS; - else - mode.c_cflag &= ~CRTSCTS; - } - - D(bug(" %sware flow control\n", mode.c_cflag & CRTSCTS ? "hard" : "soft")); - tcsetattr(fd, TCSANOW, &mode); -} - - -/* - * Data input thread - */ - -void *XSERDPort::input_func(void *arg) -{ - XSERDPort *s = (XSERDPort *)arg; - while (!s->input_thread_cancel) { - - // Wait for commands - sem_wait(&s->input_signal); - if (s->quitting) - break; - - // Execute command - void *buf = Mac2HostAddr(ReadMacInt32(s->input_pb + ioBuffer)); - uint32 length = ReadMacInt32(s->input_pb + ioReqCount); - D(bug("input_func waiting for %ld bytes of data...\n", length)); - int32 actual = read(s->fd, buf, length); - D(bug(" %ld bytes received\n", actual)); - -#if MONITOR - bug("Receiving serial data:\n"); - uint8 *adr = (uint8 *)buf; - for (int i=0; iio_killed) { - - WriteMacInt16(s->input_pb + ioResult, uint16(abortErr)); - WriteMacInt32(s->input_pb + ioActCount, 0); - s->read_pending = s->read_done = false; - - } else { - - // Set error code - if (actual >= 0) { - WriteMacInt32(s->input_pb + ioActCount, actual); - WriteMacInt32(s->input_dt + serdtResult, noErr); - } else { - WriteMacInt32(s->input_pb + ioActCount, 0); - WriteMacInt32(s->input_dt + serdtResult, uint16(readErr)); - } - - // Trigger serial interrupt - D(bug(" triggering serial interrupt\n")); - s->read_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } - } - return NULL; -} - - -/* - * Data output thread - */ - -void *XSERDPort::output_func(void *arg) -{ - XSERDPort *s = (XSERDPort *)arg; - while (!s->output_thread_cancel) { - - // Wait for commands - sem_wait(&s->output_signal); - if (s->quitting) - break; - - // Execute command - void *buf = Mac2HostAddr(ReadMacInt32(s->output_pb + ioBuffer)); - uint32 length = ReadMacInt32(s->output_pb + ioReqCount); - D(bug("output_func transmitting %ld bytes of data...\n", length)); - -#if MONITOR - bug("Sending serial data:\n"); - uint8 *adr = (uint8 *)buf; - for (int i=0; ifd, buf, length); - D(bug(" %ld bytes transmitted\n", actual)); - - // KillIO called? Then simply return - if (s->io_killed) { - - WriteMacInt16(s->output_pb + ioResult, uint16(abortErr)); - WriteMacInt32(s->output_pb + ioActCount, 0); - s->write_pending = s->write_done = false; - - } else { - - // Set error code - if (actual >= 0) { - WriteMacInt32(s->output_pb + ioActCount, actual); - WriteMacInt32(s->output_dt + serdtResult, noErr); - } else { - WriteMacInt32(s->output_pb + ioActCount, 0); - WriteMacInt32(s->output_dt + serdtResult, uint16(writErr)); - } - - // Trigger serial interrupt - D(bug(" triggering serial interrupt\n")); - s->write_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } - } - return NULL; -} diff --git a/BasiliskII/src/Unix/sshpty.c b/BasiliskII/src/Unix/sshpty.c deleted file mode 100644 index 48e69dc7..00000000 --- a/BasiliskII/src/Unix/sshpty.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland - * All rights reserved - * Allocating a pseudo-terminal, and making it the controlling tty. - * - * As far as I am concerned, the code I have written for this software - * can be used freely for any purpose. Any derived versions of this - * software must be clearly marked as such, and if the derived work is - * incompatible with the protocol description in the RFC file, it must be - * called by a name other than "ssh" or "Secure Shell". - */ - -#if 0 /* not in BasiliskII */ -#include "includes.h" -RCSID("$OpenBSD: sshpty.c,v 1.4 2001/12/19 07:18:56 deraadt Exp $"); -#else /* not in BasiliskII */ -/* Selections from openssh's "includes.h" */ -#include "config.h" - -#include -#include -#include -#include /* For O_NONBLOCK */ -#include -#include -#include - -#include /* For STDIN_FILENO, etc */ -#include /* Struct winsize */ - -/* - *-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively - */ -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_LOGIN_H -# include -#endif - -#include - -#ifdef HAVE_SYS_BSDTTY_H -# include -#endif - -#ifdef HAVE_SYS_STAT_H -# include /* For S_* constants and macros */ -#endif - -#ifndef _PATH_TTY -# define _PATH_TTY "/dev/tty" -#endif - -#include "strlcpy.h" - -#define debug(x) ; - -#endif /* not in BasiliskII */ - -#ifdef HAVE_UTIL_H -# include -#endif /* HAVE_UTIL_H */ - -#include "sshpty.h" -#if 0 /* not in BasiliskII */ -#include "log.h" -#include "misc.h" -#else /* stubs for BasiliskII */ -#define log printf -#define error printf -#define fatal(x) do { printf("Fatal error: %s", x); return 0; } while(0) -#endif /* not in BasiliskII */ - -#define mysig_t sig_t -#define mysignal signal -#include - -/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */ -#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY) -#undef HAVE_DEV_PTMX -#endif - -#ifdef HAVE_PTY_H -# include -#endif -#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) -# include -#endif -#if defined(HAVE_DEV_PTMX) && defined(HAVE_STROPTS_H) -# include -#endif - -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - -/* - * Allocates and opens a pty. Returns 0 if no pty could be allocated, or - * nonzero if a pty was successfully allocated. On success, open file - * descriptors for the pty and tty sides and the name of the tty side are - * returned (the buffer must be able to hold at least 64 characters). - */ - -int -pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) -{ -#if defined(HAVE_OPENPTY) || defined(BSD4_4) - /* openpty(3) exists in OSF/1 and some other os'es */ - char *name; - int i; - - i = openpty(ptyfd, ttyfd, NULL, NULL, NULL); - if (i < 0) { - error("openpty: %.100s", strerror(errno)); - return 0; - } - name = ttyname(*ttyfd); - if (!name) - fatal("openpty returns device for which ttyname fails."); - - strlcpy(namebuf, name, namebuflen); /* possible truncation */ - return 1; -#else /* HAVE_OPENPTY */ -#ifdef HAVE__GETPTY - /* - * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more - * pty's automagically when needed - */ - char *slave; - - slave = _getpty(ptyfd, O_RDWR, 0622, 0); - if (slave == NULL) { - error("_getpty: %.100s", strerror(errno)); - return 0; - } - strlcpy(namebuf, slave, namebuflen); - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("%.200s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } - return 1; -#else /* HAVE__GETPTY */ -#if defined(HAVE_DEV_PTMX) - /* - * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 - * also has bsd-style ptys, but they simply do not work.) - */ - int ptm; - char *pts; - mysig_t old_signal; - - ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); - if (ptm < 0) { - error("/dev/ptmx: %.100s", strerror(errno)); - return 0; - } - old_signal = mysignal(SIGCHLD, SIG_DFL); - if (grantpt(ptm) < 0) { - error("grantpt: %.100s", strerror(errno)); - return 0; - } - mysignal(SIGCHLD, old_signal); - if (unlockpt(ptm) < 0) { - error("unlockpt: %.100s", strerror(errno)); - return 0; - } - pts = ptsname(ptm); - if (pts == NULL) - error("Slave pty side name could not be obtained."); - strlcpy(namebuf, pts, namebuflen); - *ptyfd = ptm; - - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("%.100s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } -#ifndef HAVE_CYGWIN - /* - * Push the appropriate streams modules, as described in Solaris pts(7). - * HP-UX pts(7) doesn't have ttcompat module. - */ - if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) - error("ioctl I_PUSH ptem: %.100s", strerror(errno)); - if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) - error("ioctl I_PUSH ldterm: %.100s", strerror(errno)); -#ifndef __hpux - if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) - error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); -#endif -#endif - return 1; -#else /* HAVE_DEV_PTMX */ -#ifdef HAVE_DEV_PTS_AND_PTC - /* AIX-style pty code. */ - const char *name; - - *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY); - if (*ptyfd < 0) { - error("Could not open /dev/ptc: %.100s", strerror(errno)); - return 0; - } - name = ttyname(*ptyfd); - if (!name) - fatal("Open of /dev/ptc returns device for which ttyname fails."); - strlcpy(namebuf, name, namebuflen); - *ttyfd = open(name, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("Could not open pty slave side %.100s: %.100s", - name, strerror(errno)); - close(*ptyfd); - return 0; - } - return 1; -#else /* HAVE_DEV_PTS_AND_PTC */ -#ifdef _CRAY - char buf[64]; - int i; - int highpty; - -#ifdef _SC_CRAY_NPTY - highpty = sysconf(_SC_CRAY_NPTY); - if (highpty == -1) - highpty = 128; -#else - highpty = 128; -#endif - - for (i = 0; i < highpty; i++) { - snprintf(buf, sizeof(buf), "/dev/pty/%03d", i); - *ptyfd = open(buf, O_RDWR|O_NOCTTY); - if (*ptyfd < 0) - continue; - snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i); - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR|O_NOCTTY); - if (*ttyfd < 0) { - error("%.100s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } - return 1; - } - return 0; -#else - /* BSD-style pty code. */ - char buf[64]; - int i; - const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; - const char *ptyminors = "0123456789abcdef"; - int num_minors = strlen(ptyminors); - int num_ptys = strlen(ptymajors) * num_minors; - struct termios tio; - - for (i = 0; i < num_ptys; i++) { - snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], - ptyminors[i % num_minors]); - snprintf(namebuf, namebuflen, "/dev/tty%c%c", - ptymajors[i / num_minors], ptyminors[i % num_minors]); - - *ptyfd = open(buf, O_RDWR | O_NOCTTY); - if (*ptyfd < 0) { - /* Try SCO style naming */ - snprintf(buf, sizeof buf, "/dev/ptyp%d", i); - snprintf(namebuf, namebuflen, "/dev/ttyp%d", i); - *ptyfd = open(buf, O_RDWR | O_NOCTTY); - if (*ptyfd < 0) - continue; - } - - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("%.100s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } - /* set tty modes to a sane state for broken clients */ - if (tcgetattr(*ptyfd, &tio) < 0) - log("Getting tty modes for pty failed: %.100s", strerror(errno)); - else { - tio.c_lflag |= (ECHO | ISIG | ICANON); - tio.c_oflag |= (OPOST | ONLCR); - tio.c_iflag |= ICRNL; - - /* Set the new modes for the terminal. */ - if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) - log("Setting tty modes for pty failed: %.100s", strerror(errno)); - } - - return 1; - } - return 0; -#endif /* CRAY */ -#endif /* HAVE_DEV_PTS_AND_PTC */ -#endif /* HAVE_DEV_PTMX */ -#endif /* HAVE__GETPTY */ -#endif /* HAVE_OPENPTY */ -} - -/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ - -void -pty_release(const char *ttyname) -{ - if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0) - error("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno)); - if (chmod(ttyname, (mode_t) 0666) < 0) - error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); -} - -/* Makes the tty the processes controlling tty and sets it to sane modes. */ - -void -pty_make_controlling_tty(int *ttyfd, const char *ttyname) -{ - int fd; -#ifdef USE_VHANGUP - void *old; -#endif /* USE_VHANGUP */ - -#ifdef _CRAY - if (setsid() < 0) - error("setsid: %.100s", strerror(errno)); - - fd = open(ttyname, O_RDWR|O_NOCTTY); - if (fd != -1) { - mysignal(SIGHUP, SIG_IGN); - ioctl(fd, TCVHUP, (char *)NULL); - mysignal(SIGHUP, SIG_DFL); - setpgid(0, 0); - close(fd); - } else { - error("Failed to disconnect from controlling tty."); - } - - debug("Setting controlling tty using TCSETCTTY."); - ioctl(*ttyfd, TCSETCTTY, NULL); - fd = open("/dev/tty", O_RDWR); - if (fd < 0) - error("%.100s: %.100s", ttyname, strerror(errno)); - close(*ttyfd); - *ttyfd = fd; -#else /* _CRAY */ - - /* First disconnect from the old controlling tty. */ -#ifdef TIOCNOTTY - fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); - if (fd >= 0) { - (void) ioctl(fd, TIOCNOTTY, NULL); - close(fd); - } -#endif /* TIOCNOTTY */ - if (setsid() < 0) - error("setsid: %.100s", strerror(errno)); - - /* - * Verify that we are successfully disconnected from the controlling - * tty. - */ - fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); - if (fd >= 0) { - error("Failed to disconnect from controlling tty."); - close(fd); - } - /* Make it our controlling tty. */ -#ifdef TIOCSCTTY - debug("Setting controlling tty using TIOCSCTTY."); - if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) - error("ioctl(TIOCSCTTY): %.100s", strerror(errno)); -#endif /* TIOCSCTTY */ -#ifdef HAVE_NEWS4 - if (setpgrp(0,0) < 0) - error("SETPGRP %s",strerror(errno)); -#endif /* HAVE_NEWS4 */ -#ifdef USE_VHANGUP - old = mysignal(SIGHUP, SIG_IGN); - vhangup(); - mysignal(SIGHUP, old); -#endif /* USE_VHANGUP */ - fd = open(ttyname, O_RDWR); - if (fd < 0) { - error("%.100s: %.100s", ttyname, strerror(errno)); - } else { -#ifdef USE_VHANGUP - close(*ttyfd); - *ttyfd = fd; -#else /* USE_VHANGUP */ - close(fd); -#endif /* USE_VHANGUP */ - } - /* Verify that we now have a controlling tty. */ - fd = open(_PATH_TTY, O_WRONLY); - if (fd < 0) - error("open /dev/tty failed - could not set controlling tty: %.100s", - strerror(errno)); - else { - close(fd); - } -#endif /* _CRAY */ -} - -#if 0 /* not in BasiliskII */ -/* Changes the window size associated with the pty. */ - -void -pty_change_window_size(int ptyfd, int row, int col, - int xpixel, int ypixel) -{ - struct winsize w; - w.ws_row = row; - w.ws_col = col; - w.ws_xpixel = xpixel; - w.ws_ypixel = ypixel; - (void) ioctl(ptyfd, TIOCSWINSZ, &w); -} - -void -pty_setowner(struct passwd *pw, const char *ttyname) -{ - struct group *grp; - gid_t gid; - mode_t mode; - struct stat st; - - /* Determine the group to make the owner of the tty. */ - grp = getgrnam("tty"); - if (grp) { - gid = grp->gr_gid; - mode = S_IRUSR | S_IWUSR | S_IWGRP; - } else { - gid = pw->pw_gid; - mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; - } - - /* - * Change owner and mode of the tty as required. - * Warn but continue if filesystem is read-only and the uids match/ - * tty is owned by root. - */ - if (stat(ttyname, &st)) - fatal("stat(%.100s) failed: %.100s", ttyname, - strerror(errno)); - - if (st.st_uid != pw->pw_uid || st.st_gid != gid) { - if (chown(ttyname, pw->pw_uid, gid) < 0) { - if (errno == EROFS && - (st.st_uid == pw->pw_uid || st.st_uid == 0)) - error("chown(%.100s, %d, %d) failed: %.100s", - ttyname, pw->pw_uid, gid, - strerror(errno)); - else - fatal("chown(%.100s, %d, %d) failed: %.100s", - ttyname, pw->pw_uid, gid, - strerror(errno)); - } - } - - if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) { - if (chmod(ttyname, mode) < 0) { - if (errno == EROFS && - (st.st_mode & (S_IRGRP | S_IROTH)) == 0) - error("chmod(%.100s, 0%o) failed: %.100s", - ttyname, mode, strerror(errno)); - else - fatal("chmod(%.100s, 0%o) failed: %.100s", - ttyname, mode, strerror(errno)); - } - } -} -#endif /* not in BasiliskII */ diff --git a/BasiliskII/src/Unix/sshpty.h b/BasiliskII/src/Unix/sshpty.h deleted file mode 100644 index df65e284..00000000 --- a/BasiliskII/src/Unix/sshpty.h +++ /dev/null @@ -1,26 +0,0 @@ -/* $OpenBSD: sshpty.h,v 1.4 2002/03/04 17:27:39 stevesk Exp $ */ - -/* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland - * All rights reserved - * Functions for allocating a pseudo-terminal and making it the controlling - * tty. - * - * As far as I am concerned, the code I have written for this software - * can be used freely for any purpose. Any derived versions of this - * software must be clearly marked as such, and if the derived work is - * incompatible with the protocol description in the RFC file, it must be - * called by a name other than "ssh" or "Secure Shell". - */ - -#ifndef SSHPTY_H -#define SSHPTY_H - -int pty_allocate(int *, int *, char *, int); -void pty_release(const char *); -void pty_make_controlling_tty(int *, const char *); -void pty_change_window_size(int, int, int, int, int); -void pty_setowner(struct passwd *, const char *); - -#endif /* SSHPTY_H */ diff --git a/BasiliskII/src/Unix/strlcpy.c b/BasiliskII/src/Unix/strlcpy.c deleted file mode 100644 index b5e5a552..00000000 --- a/BasiliskII/src/Unix/strlcpy.c +++ /dev/null @@ -1,75 +0,0 @@ -/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */ - -/* - * Copyright (c) 1998 Todd C. Miller - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT 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 SUCH DAMAGE. - */ - -#include "config.h" -#ifndef HAVE_STRLCPY - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include "strlcpy.h" - -/* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ -size_t -strlcpy(dst, src, siz) - char *dst; - const char *src; - size_t siz; -{ - register char *d = dst; - register const char *s = src; - register size_t n = siz; - - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) { - do { - if ((*d++ = *s++) == 0) - break; - } while (--n != 0); - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ -} - -#endif /* !HAVE_STRLCPY */ diff --git a/BasiliskII/src/Unix/strlcpy.h b/BasiliskII/src/Unix/strlcpy.h deleted file mode 100644 index 7b33e4f6..00000000 --- a/BasiliskII/src/Unix/strlcpy.h +++ /dev/null @@ -1,12 +0,0 @@ -/* $Id$ */ - -#ifndef _BSD_STRLCPY_H -#define _BSD_STRLCPY_H - -#include "config.h" -#ifndef HAVE_STRLCPY -#include -size_t strlcpy(char *dst, const char *src, size_t siz); -#endif /* !HAVE_STRLCPY */ - -#endif /* _BSD_STRLCPY_H */ diff --git a/BasiliskII/src/Unix/sys_unix.cpp b/BasiliskII/src/Unix/sys_unix.cpp index 85d650c8..6a5729c1 100644 --- a/BasiliskII/src/Unix/sys_unix.cpp +++ b/BasiliskII/src/Unix/sys_unix.cpp @@ -28,27 +28,9 @@ #include #endif -#ifdef __linux__ -#include -#include -#include -#include -#include -#include -#include -#endif - -#if defined(__FreeBSD__) || defined(__NetBSD__) -#include -#endif - #if defined __APPLE__ && defined __MACH__ #include -#if (defined AQUA || defined HAVE_FRAMEWORK_COREFOUNDATION) -#ifndef __MACOSX__ -#define __MACOSX__ MAC_OS_X_VERSION_MIN_REQUIRED -#endif -#endif + #endif #include "main.h" @@ -58,22 +40,11 @@ #include "sys.h" #include "disk_unix.h" -#if defined(BINCUE) -#include "bincue_unix.h" -#endif - - - #define DEBUG 0 #include "debug.h" static disk_factory *disk_factories[] = { -#ifndef STANDALONE_GUI - disk_sparsebundle_factory, -#if defined(HAVE_LIBVHD) - disk_vhd_factory, -#endif -#endif + NULL }; @@ -93,19 +64,11 @@ struct mac_file_handle { bool is_media_present; // Flag: media is inserted and available disk_generic *generic_disk; -#if defined(__linux__) - int cdrom_cap; // CD-ROM capability flags (only valid if is_cdrom is true) -#elif defined(__FreeBSD__) - struct ioc_capability cdrom_cap; -#elif defined(__APPLE__) && defined(__MACH__) +#if defined(__APPLE__) && defined(__MACH__) char *ioctl_name; // For CDs on OS X - a device for special ioctls int ioctl_fd; #endif -#if defined(BINCUE) - bool is_bincue; // Flag: BIN CUE file - void *bincue_fd; -#endif }; // Open file handles @@ -129,10 +92,7 @@ static bool cdrom_open(mac_file_handle *fh, const char *path = NULL); void SysInit(void) { -#if defined __MACOSX__ - extern void DarwinSysInit(void); - DarwinSysInit(); -#endif + } @@ -142,10 +102,7 @@ void SysInit(void) void SysExit(void) { -#if defined __MACOSX__ - extern void DarwinSysExit(void); - DarwinSysExit(); -#endif + } @@ -242,12 +199,7 @@ void SysMediaRemoved(const char *path, int type) fh->is_media_present = false; break; } -#if defined __MACOSX__ - if (fh->ioctl_name && strcmp(fh->ioctl_name, path) == 0) { - fh->is_media_present = false; - break; - } -#endif + } } @@ -270,26 +222,7 @@ void SysMountFirstFloppy(void) void SysAddFloppyPrefs(void) { -#if defined(__linux__) - DIR *fd_dir = opendir("/dev/floppy"); - if (fd_dir) { - struct dirent *floppy_dev; - while ((floppy_dev = readdir(fd_dir)) != NULL) { - if (strstr(floppy_dev->d_name, "u1440") != NULL) { - char fd_dev[20]; - sprintf(fd_dev, "/dev/floppy/%s", floppy_dev->d_name); - PrefsAddString("floppy", fd_dev); - } - } - closedir(fd_dir); - } else { - PrefsAddString("floppy", "/dev/fd0"); - PrefsAddString("floppy", "/dev/fd1"); - } -#elif defined(__NetBSD__) - PrefsAddString("floppy", "/dev/fd0a"); - PrefsAddString("floppy", "/dev/fd1a"); -#elif defined(__APPLE__) && defined(__MACH__) +#if defined(__APPLE__) && defined(__MACH__) #if defined(AQUA) || defined(HAVE_FRAMEWORK_COREFOUNDATION) extern void DarwinAddFloppyPrefs(void); @@ -316,28 +249,7 @@ void SysAddFloppyPrefs(void) void SysAddDiskPrefs(void) { -#ifdef __linux__ - FILE *f = fopen("/etc/fstab", "r"); - if (f) { - char line[256]; - while(fgets(line, 255, f)) { - // Read line - int len = strlen(line); - if (len == 0 || line[0] == '#') - continue; - line[len-1] = 0; - // Parse line - char *dev = NULL, *mnt_point = NULL, *fstype = NULL; - if (sscanf(line, "%as %as %as", &dev, &mnt_point, &fstype) == 3) { - if (strcmp(fstype, "hfs") == 0) - PrefsAddString("disk", dev); - } - free(dev); free(mnt_point); free(fstype); - } - fclose(f); - } -#endif } @@ -352,32 +264,6 @@ void SysAddCDROMPrefs(void) if (PrefsFindBool("nocdrom")) return; -#if defined(__linux__) - if (access("/dev/.devfsd", F_OK) < 0) - PrefsAddString("cdrom", "/dev/cdrom"); - else { - DIR *cd_dir = opendir("/dev/cdroms"); - if (cd_dir) { - struct dirent *cdrom_dev; - while ((cdrom_dev = readdir(cd_dir)) != NULL) { - if (strcmp(cdrom_dev->d_name, ".") != 0 && strcmp(cdrom_dev->d_name, "..") != 0) { - char cd_dev[20]; - sprintf(cd_dev, "/dev/cdroms/%s", cdrom_dev->d_name); - PrefsAddString("cdrom", cd_dev); - } - } - closedir(cd_dir); - } - } -#elif defined __MACOSX__ - // There is no predefined path for CD-ROMs on MacOS X. Rather, we - // define a single fake CD-ROM entry for the emulated MacOS. - // XXX this means we handle only CD-ROM drive at a time, wherever - // the disk is, the latest one is used. - PrefsAddString("cdrom", "/dev/poll/cdrom"); -#elif defined(__FreeBSD__) || defined(__NetBSD__) - PrefsAddString("cdrom", "/dev/cd0c"); -#endif } @@ -387,21 +273,7 @@ void SysAddCDROMPrefs(void) void SysAddSerialPrefs(void) { -#if defined(__linux__) - if (access("/dev/.devfsd", F_OK) < 0) { - PrefsAddString("seriala", "/dev/ttyS0"); - PrefsAddString("serialb", "/dev/ttyS1"); - } else { - PrefsAddString("seriala", "/dev/tts/0"); - PrefsAddString("serialb", "/dev/tts/1"); - } -#elif defined(__FreeBSD__) - PrefsAddString("seriala", "/dev/cuaa0"); - PrefsAddString("serialb", "/dev/cuaa1"); -#elif defined(__NetBSD__) - PrefsAddString("seriala", "/dev/tty00"); - PrefsAddString("serialb", "/dev/tty01"); -#elif defined(__APPLE__) && defined(__MACH__) +#if defined(__APPLE__) && defined(__MACH__) #if defined(AQUA) || defined(HAVE_FRAMEWORK_COREFOUNDATION) extern void DarwinAddSerialPrefs(void); @@ -422,26 +294,7 @@ void SysAddSerialPrefs(void) static bool cdrom_open_1(mac_file_handle *fh) { -#if defined __MACOSX__ - // In OS X, the device name is OK for sending ioctls to, - // but not for reading raw CDROM data from. - // (it seems to have extra data padded in) - // - // So, we keep the already opened file handle, - // and open a slightly different file for CDROM data - // - fh->ioctl_fd = fh->fd; - fh->ioctl_name = fh->name; - fh->fd = -1; - fh->name = (char *)malloc(strlen(fh->ioctl_name) + 3); - if (fh->name) { - strcpy(fh->name, fh->ioctl_name); - strcat(fh->name, "s1"); - fh->fd = open(fh->name, O_RDONLY, O_NONBLOCK); - } - if (fh->ioctl_fd < 0) - return false; -#endif + return true; } @@ -472,16 +325,7 @@ void cdrom_close(mac_file_handle *fh) free(fh->name); fh->name = NULL; } -#if defined __MACOSX__ - if (fh->ioctl_fd >= 0) { - close(fh->ioctl_fd); - fh->ioctl_fd = -1; - } - if (fh->ioctl_name) { - free(fh->ioctl_name); - fh->ioctl_name = NULL; - } -#endif + } @@ -491,30 +335,7 @@ void cdrom_close(mac_file_handle *fh) static bool is_drive_mounted(const char *dev_name, char *mount_name) { -#ifdef __linux__ - FILE *f = fopen("/proc/mounts", "r"); - if (f) { - char line[256]; - while(fgets(line, 255, f)) { - // Read line - int len = strlen(line); - if (len == 0) - continue; - line[len-1] = 0; - // Parse line - if (strncmp(line, dev_name, strlen(dev_name)) == 0) { - mount_name[0] = 0; - char *dummy; - sscanf(line, "%as %s", &dummy, mount_name); - free(dummy); - fclose(f); - return true; - } - } - fclose(f); - } -#endif return false; } @@ -530,51 +351,29 @@ static mac_file_handle *open_filehandle(const char *name) fh->name = strdup(name); fh->fd = -1; fh->generic_disk = NULL; -#if defined __MACOSX__ - fh->ioctl_fd = -1; - fh->ioctl_name = NULL; -#endif + return fh; } void *Sys_open(const char *name, bool read_only) { bool is_file = strncmp(name, "/dev/", 5) != 0; -#if defined(__FreeBSD__) - // SCSI IDE - bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0 || strncmp(name, "/dev/acd", 8) == 0; -#else + bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0; -#endif + bool is_floppy = strncmp(name, "/dev/fd", 7) == 0; bool is_polled_media = strncmp(name, "/dev/poll/", 10) == 0; if (is_floppy) // Floppy open fails if there's no disk inserted is_polled_media = true; -#if defined __MACOSX__ - // There is no set filename in /dev which is the cdrom, - // so we have to see if it is any of the devices that we found earlier - { - int index = 0; - const char *str; - while ((str = PrefsFindString("cdrom", index++)) != NULL) { - if (is_polled_media || strcmp(str, name) == 0) { - is_cdrom = true; - read_only = true; - break; - } - } - } -#endif - D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write")); // Check if write access is allowed, set read-only flag if not if (!read_only && access(name, W_OK)) read_only = true; - // Print warning message and eventually unmount drive when this is an HFS volume mounted under Linux (double mounting will corrupt the volume) + // Print warning message and eventually unmount drive when this is an HFS volume mounted under (double mounting will corrupt the volume) char mount_name[256]; if (!is_file && !read_only && is_drive_mounted(name, mount_name)) { char str[512]; @@ -590,19 +389,6 @@ void *Sys_open(const char *name, bool read_only) // Open file/device -#if defined(BINCUE) - void *binfd = open_bincue(name); - if (binfd) { - mac_file_handle *fh = open_filehandle(name); - D(bug("opening %s as bincue\n", name)); - fh->bincue_fd = binfd; - fh->is_bincue = true; - fh->read_only = true; - fh->is_media_present = true; - sys_add_mac_file_handle(fh); - return fh; - } -#endif for (int i = 0; disk_factories[i]; ++i) { @@ -623,26 +409,9 @@ void *Sys_open(const char *name, bool read_only) } int open_flags = (read_only ? O_RDONLY : O_RDWR); -#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__MACOSX__) - open_flags |= (is_cdrom ? O_NONBLOCK : 0); -#endif -#if defined(__MACOSX__) - open_flags |= (is_file ? O_EXLOCK | O_NONBLOCK : 0); -#endif + int fd = open(name, open_flags); -#if defined(__MACOSX__) - if (fd < 0 && (open_flags & O_EXLOCK)) { - if (errno == EOPNOTSUPP) { - // File system does not support locking. Try again without. - open_flags &= ~O_EXLOCK; - fd = open(name, open_flags); - } else if (errno == EAGAIN) { - // File is likely already locked by another process. - printf("WARNING: Cannot open %s (%s)\n", name, strerror(errno)); - return NULL; - } - } -#endif + if (fd < 0 && !read_only) { // Read-write failed, try read-only read_only = true; @@ -670,35 +439,8 @@ void *Sys_open(const char *name, bool read_only) fh->is_media_present = true; if (S_ISBLK(st.st_mode)) { fh->is_cdrom = is_cdrom; -#if defined(__linux__) - fh->is_floppy = (MAJOR(st.st_rdev) == FLOPPY_MAJOR); -#ifdef CDROM_GET_CAPABILITY - if (is_cdrom) { - fh->cdrom_cap = ioctl(fh->fd, CDROM_GET_CAPABILITY); - if (fh->cdrom_cap < 0) - fh->cdrom_cap = 0; - } -#endif -#elif defined(__FreeBSD__) - fh->is_floppy = ((st.st_rdev >> 16) == 2); -#ifdef CDIOCCAPABILITY - if (is_cdrom) { - if (ioctl(fh->fd, CDIOCCAPABILITY, &fh->cdrom_cap) < 0) - memset(&fh->cdrom_cap, 0, sizeof(fh->cdrom_cap)); - } -#endif -#elif defined(__NetBSD__) - fh->is_floppy = ((st.st_rdev >> 16) == 2); -#endif } -#if defined __MACOSX__ - if (is_cdrom) { - fh->is_cdrom = true; - fh->is_floppy = false; - if (cdrom_open_1(fh)) - fh->is_media_present = true; - } -#endif + } } if (fh->is_floppy && first_floppy == NULL) @@ -724,10 +466,6 @@ void Sys_close(void *arg) sys_remove_mac_file_handle(fh); -#if defined(BINCUE) - if (fh->is_bincue) - close_bincue(fh->bincue_fd); -#endif if (fh->generic_disk) delete fh->generic_disk; @@ -752,10 +490,6 @@ size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length) if (!fh) return 0; -#if defined(BINCUE) - if (fh->is_bincue) - return read_bincue(fh->bincue_fd, buffer, offset, length); -#endif if (fh->generic_disk) return fh->generic_disk->read(buffer, offset, length); @@ -802,10 +536,6 @@ loff_t SysGetFileSize(void *arg) if (!fh) return true; -#if defined(BINCUE) - if (fh->is_bincue) - return size_bincue(fh->bincue_fd); -#endif if (fh->generic_disk) return fh->file_size; @@ -813,25 +543,9 @@ loff_t SysGetFileSize(void *arg) if (fh->is_file) return fh->file_size; else { -#if defined(__linux__) - long blocks; - if (ioctl(fh->fd, BLKGETSIZE, &blocks) < 0) - return 0; - D(bug(" BLKGETSIZE returns %d blocks\n", blocks)); - return (loff_t)blocks * 512; -#elif defined __MACOSX__ - uint32 block_size; - if (ioctl(fh->ioctl_fd, DKIOCGETBLOCKSIZE, &block_size) < 0) - return 0; - D(bug(" DKIOCGETBLOCKSIZE returns %lu bytes\n", (unsigned long)block_size)); - uint64 block_count; - if (ioctl(fh->ioctl_fd, DKIOCGETBLOCKCOUNT, &block_count) < 0) - return 0; - D(bug(" DKIOCGETBLOCKCOUNT returns %llu blocks\n", (unsigned long long)block_count)); - return block_count * block_size; -#else + return lseek(fh->fd, 0, SEEK_END) - fh->start_byte; -#endif + } } @@ -846,29 +560,7 @@ void SysEject(void *arg) if (!fh) return; -#if defined(__linux__) - if (fh->is_floppy) { - if (fh->fd >= 0) { - fsync(fh->fd); - ioctl(fh->fd, FDFLUSH); - ioctl(fh->fd, FDEJECT); - close(fh->fd); // Close and reopen so the driver will see the media change - } - fh->fd = open(fh->name, fh->read_only ? O_RDONLY : O_RDWR); - } else if (fh->is_cdrom) { - ioctl(fh->fd, CDROMEJECT); - close(fh->fd); // Close and reopen so the driver will see the media change - fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK); - } -#elif defined(__FreeBSD__) || defined(__NetBSD__) - if (fh->is_floppy) { - fsync(fh->fd); - } else if (fh->is_cdrom) { - ioctl(fh->fd, CDIOCEJECT); - close(fh->fd); // Close and reopen so the driver will see the media change - fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK); - } -#elif defined(__APPLE__) && defined(__MACH__) +#if defined(__APPLE__) && defined(__MACH__) if (fh->is_cdrom && fh->is_media_present) { close(fh->fd); fh->fd = -1; @@ -919,16 +611,6 @@ bool SysIsReadOnly(void *arg) if (!fh) return true; -#if defined(__linux__) - if (fh->is_floppy) { - if (fh->fd >= 0) { - struct floppy_drive_struct stat; - ioctl(fh->fd, FDGETDRVSTAT, &stat); - return !(stat.flags & FD_DISK_WRITABLE); - } else - return true; - } else -#endif return fh->read_only; } @@ -971,47 +653,6 @@ bool SysIsDiskInserted(void *arg) if (fh->is_file) { return true; -#if defined(__linux__) - } else if (fh->is_floppy) { - char block[512]; - lseek(fh->fd, 0, SEEK_SET); - ssize_t actual = read(fh->fd, block, 512); - if (actual < 0) { - close(fh->fd); // Close and reopen so the driver will see the media change - fh->fd = open(fh->name, fh->read_only ? O_RDONLY : O_RDWR); - actual = read(fh->fd, block, 512); - } - return actual == 512; - } else if (fh->is_cdrom) { -#ifdef CDROM_MEDIA_CHANGED - if (fh->cdrom_cap & CDC_MEDIA_CHANGED) { - // If we don't do this, all attempts to read from a disc fail - // once the tray has been opened (altough the TOC reads fine). - // Can somebody explain this to me? - if (ioctl(fh->fd, CDROM_MEDIA_CHANGED) == 1) { - close(fh->fd); - fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK); - } - } -#endif -#ifdef CDROM_DRIVE_STATUS - if (fh->cdrom_cap & CDC_DRIVE_STATUS) { - return ioctl(fh->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK; - } -#endif - cdrom_tochdr header; - return ioctl(fh->fd, CDROMREADTOCHDR, &header) == 0; -#elif defined(__FreeBSD__) || defined(__NetBSD__) - } else if (fh->is_floppy) { - return false; //!! - } else if (fh->is_cdrom) { - struct ioc_toc_header header; - return ioctl(fh->fd, CDIOREADTOCHEADER, &header) == 0; -#elif defined __MACOSX__ - } else if (fh->is_cdrom || fh->is_floppy) { - return fh->is_media_present; -#endif - } else return true; } @@ -1027,10 +668,6 @@ void SysPreventRemoval(void *arg) if (!fh) return; -#if defined(__linux__) && defined(CDROM_LOCKDOOR) - if (fh->is_cdrom) - ioctl(fh->fd, CDROM_LOCKDOOR, 1); -#endif } @@ -1044,10 +681,6 @@ void SysAllowRemoval(void *arg) if (!fh) return; -#if defined(__linux__) && defined(CDROM_LOCKDOOR) - if (fh->is_cdrom) - ioctl(fh->fd, CDROM_LOCKDOOR, 0); -#endif } @@ -1061,138 +694,10 @@ bool SysCDReadTOC(void *arg, uint8 *toc) if (!fh) return false; -#if defined(BINCUE) - if (fh->is_bincue) - return readtoc_bincue(fh->bincue_fd, toc); -#endif - if (fh->is_cdrom) { -#if defined(__linux__) - uint8 *p = toc + 2; - - // Header - cdrom_tochdr header; - if (ioctl(fh->fd, CDROMREADTOCHDR, &header) < 0) - return false; - *p++ = header.cdth_trk0; - *p++ = header.cdth_trk1; - - // Tracks - cdrom_tocentry entry; - for (int i=header.cdth_trk0; i<=header.cdth_trk1; i++) { - entry.cdte_track = i; - entry.cdte_format = CDROM_MSF; - if (ioctl(fh->fd, CDROMREADTOCENTRY, &entry) < 0) - return false; - *p++ = 0; - *p++ = (entry.cdte_adr << 4) | entry.cdte_ctrl; - *p++ = entry.cdte_track; - *p++ = 0; - *p++ = 0; - *p++ = entry.cdte_addr.msf.minute; - *p++ = entry.cdte_addr.msf.second; - *p++ = entry.cdte_addr.msf.frame; - } - - // Leadout track - entry.cdte_track = CDROM_LEADOUT; - entry.cdte_format = CDROM_MSF; - if (ioctl(fh->fd, CDROMREADTOCENTRY, &entry) < 0) - return false; - *p++ = 0; - *p++ = (entry.cdte_adr << 4) | entry.cdte_ctrl; - *p++ = entry.cdte_track; - *p++ = 0; - *p++ = 0; - *p++ = entry.cdte_addr.msf.minute; - *p++ = entry.cdte_addr.msf.second; - *p++ = entry.cdte_addr.msf.frame; - - // TOC size - int toc_size = p - toc; - *toc++ = toc_size >> 8; - *toc++ = toc_size & 0xff; - return true; -#elif defined __MACOSX__ && defined MAC_OS_X_VERSION_10_2 - if (fh->is_media_present) { - extern bool DarwinCDReadTOC(char *name, uint8 *toc); - return DarwinCDReadTOC(fh->name, toc); - } return false; -#elif defined(__FreeBSD__) - uint8 *p = toc + 2; - // Header - struct ioc_toc_header header; - if (ioctl(fh->fd, CDIOREADTOCHEADER, &header) < 0) - return false; - *p++ = header.starting_track; - *p++ = header.ending_track; - - // Tracks - struct ioc_read_toc_single_entry entry; - for (int i=header.starting_track; i<=header.ending_track; i++) { - entry.track = i; - entry.address_format = CD_MSF_FORMAT; - if (ioctl(fh->fd, CDIOREADTOCENTRY, &entry) < 0) - return false; - *p++ = 0; - *p++ = (entry.entry.addr_type << 4) | entry.entry.control; - *p++ = entry.entry.track; - *p++ = 0; - *p++ = 0; - *p++ = entry.entry.addr.msf.minute; - *p++ = entry.entry.addr.msf.second; - *p++ = entry.entry.addr.msf.frame; - } - - // Leadout track - entry.track = CD_TRACK_INFO; - entry.address_format = CD_MSF_FORMAT; - if (ioctl(fh->fd, CDIOREADTOCENTRY, &entry) < 0) - return false; - *p++ = 0; - *p++ = (entry.entry.addr_type << 4) | entry.entry.control; - *p++ = entry.entry.track; - *p++ = 0; - *p++ = 0; - *p++ = entry.entry.addr.msf.minute; - *p++ = entry.entry.addr.msf.second; - *p++ = entry.entry.addr.msf.frame; - - // TOC size - int toc_size = p - toc; - *toc++ = toc_size >> 8; - *toc++ = toc_size & 0xff; - return true; -#elif defined(__NetBSD__) - uint8 *p = toc + 2; - - // Header - struct ioc_toc_header header; - if (ioctl(fh->fd, CDIOREADTOCHEADER, &header) < 0) - return false; - *p++ = header.starting_track; - *p++ = header.ending_track; - - // Tracks (this is nice... :-) - struct ioc_read_toc_entry entries; - entries.address_format = CD_MSF_FORMAT; - entries.starting_track = 1; - entries.data_len = 800; - entries.data = (cd_toc_entry *)p; - if (ioctl(fh->fd, CDIOREADTOCENTRIES, &entries) < 0) - return false; - - // TOC size - int toc_size = p - toc; - *toc++ = toc_size >> 8; - *toc++ = toc_size & 0xff; - return true; -#else - return false; -#endif } else return false; } @@ -1208,61 +713,10 @@ bool SysCDGetPosition(void *arg, uint8 *pos) if (!fh) return false; -#if defined(BINCUE) - if (fh->is_bincue) - return GetPosition_bincue(fh->bincue_fd, pos); -#endif - if (fh->is_cdrom) { -#if defined(__linux__) - cdrom_subchnl chan; - chan.cdsc_format = CDROM_MSF; - if (ioctl(fh->fd, CDROMSUBCHNL, &chan) < 0) - return false; - *pos++ = 0; - *pos++ = chan.cdsc_audiostatus; - *pos++ = 0; - *pos++ = 12; // Sub-Q data length - *pos++ = 0; - *pos++ = (chan.cdsc_adr << 4) | chan.cdsc_ctrl; - *pos++ = chan.cdsc_trk; - *pos++ = chan.cdsc_ind; - *pos++ = 0; - *pos++ = chan.cdsc_absaddr.msf.minute; - *pos++ = chan.cdsc_absaddr.msf.second; - *pos++ = chan.cdsc_absaddr.msf.frame; - *pos++ = 0; - *pos++ = chan.cdsc_reladdr.msf.minute; - *pos++ = chan.cdsc_reladdr.msf.second; - *pos++ = chan.cdsc_reladdr.msf.frame; - return true; -#elif defined(__FreeBSD__) || defined(__NetBSD__) - struct ioc_read_subchannel chan; - chan.data_format = CD_MSF_FORMAT; - chan.address_format = CD_MSF_FORMAT; - chan.track = CD_CURRENT_POSITION; - if (ioctl(fh->fd, CDIOCREADSUBCHANNEL, &chan) < 0) - return false; - *pos++ = 0; - *pos++ = chan.data->header.audio_status; - *pos++ = 0; - *pos++ = 12; // Sub-Q data length - *pos++ = 0; - *pos++ = (chan.data->what.position.addr_type << 4) | chan.data->what.position.control; - *pos++ = chan.data->what.position.track_number; - *pos++ = chan.data->what.position.index_number; - *pos++ = 0; - *pos++ = chan.data->what.position.absaddr.msf.minute; - *pos++ = chan.data->what.position.absaddr.msf.second; - *pos++ = chan.data->what.position.absaddr.msf.frame; - *pos++ = 0; - *pos++ = chan.data->what.position.reladdr.msf.minute; - *pos++ = chan.data->what.position.reladdr.msf.second; - *pos++ = chan.data->what.position.reladdr.msf.frame; - return true; -#else + return false; -#endif + } else return false; } @@ -1278,33 +732,11 @@ bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end if (!fh) return false; -#if defined(BINCUE) - if (fh->is_bincue) - return CDPlay_bincue(fh->bincue_fd, start_m, start_s, start_f, end_m, end_s, end_f); -#endif if (fh->is_cdrom) { -#if defined(__linux__) - cdrom_msf play; - play.cdmsf_min0 = start_m; - play.cdmsf_sec0 = start_s; - play.cdmsf_frame0 = start_f; - play.cdmsf_min1 = end_m; - play.cdmsf_sec1 = end_s; - play.cdmsf_frame1 = end_f; - return ioctl(fh->fd, CDROMPLAYMSF, &play) == 0; -#elif defined(__FreeBSD__) || defined(__NetBSD__) - struct ioc_play_msf play; - play.start_m = start_m; - play.start_s = start_s; - play.start_f = start_f; - play.end_m = end_m; - play.end_s = end_s; - play.end_f = end_f; - return ioctl(fh->fd, CDIOCPLAYMSF, &play) == 0; -#else + return false; -#endif + } else return false; } @@ -1320,19 +752,10 @@ bool SysCDPause(void *arg) if (!fh) return false; -#if defined(BINCUE) - if (fh->is_bincue) - return CDPause_bincue(fh->bincue_fd); -#endif - if (fh->is_cdrom) { -#if defined(__linux__) - return ioctl(fh->fd, CDROMPAUSE) == 0; -#elif defined(__FreeBSD__) || defined(__NetBSD__) - return ioctl(fh->fd, CDIOCPAUSE) == 0; -#else + return false; -#endif + } else return false; } @@ -1348,20 +771,11 @@ bool SysCDResume(void *arg) if (!fh) return false; -#if defined(BINCUE) - if (fh->is_bincue) - return CDResume_bincue(fh->bincue_fd); -#endif - if (fh->is_cdrom) { -#if defined(__linux__) - return ioctl(fh->fd, CDROMRESUME) == 0; -#elif defined(__FreeBSD__) || defined(__NetBSD__) - return ioctl(fh->fd, CDIOCRESUME) == 0; -#else + return false; -#endif + } else return false; } @@ -1377,20 +791,10 @@ bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f) if (!fh) return false; -#if defined(BINCUE) - if (fh->is_bincue) - return CDStop_bincue(fh->bincue_fd); -#endif - - if (fh->is_cdrom) { -#if defined(__linux__) - return ioctl(fh->fd, CDROMSTOP) == 0; -#elif defined(__FreeBSD__) || defined(__NetBSD__) - return ioctl(fh->fd, CDIOCSTOP) == 0; -#else + return false; -#endif + } else return false; } @@ -1406,7 +810,6 @@ bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reve if (!fh) return false; - // Not supported under Linux return false; } @@ -1422,17 +825,7 @@ void SysCDSetVolume(void *arg, uint8 left, uint8 right) return; if (fh->is_cdrom) { -#if defined(__linux__) - cdrom_volctrl vol; - vol.channel0 = vol.channel2 = left; - vol.channel1 = vol.channel3 = right; - ioctl(fh->fd, CDROMVOLCTRL, &vol); -#elif defined(__FreeBSD__) || defined(__NetBSD__) - struct ioc_vol vol; - vol.vol[0] = vol.vol[2] = left; - vol.vol[1] = vol.vol[3] = right; - ioctl(fh->fd, CDIOCSETVOL, &vol); -#endif + } } @@ -1449,16 +842,6 @@ void SysCDGetVolume(void *arg, uint8 &left, uint8 &right) left = right = 0; if (fh->is_cdrom) { -#if defined(__linux__) - cdrom_volctrl vol; - ioctl(fh->fd, CDROMVOLREAD, &vol); - left = vol.channel0; - right = vol.channel1; -#elif defined(__FreeBSD__) || defined(__NetBSD__) - struct ioc_vol vol; - ioctl(fh->fd, CDIOCGETVOL, &vol); - left = vol.vol[0]; - right = vol.vol[1]; -#endif + } } diff --git a/BasiliskII/src/Unix/sysdeps.h b/BasiliskII/src/Unix/sysdeps.h index df291939..285b5e63 100644 --- a/BasiliskII/src/Unix/sysdeps.h +++ b/BasiliskII/src/Unix/sysdeps.h @@ -66,25 +66,6 @@ #include #endif -#ifdef ENABLE_NATIVE_M68K - -/* Mac and host address space are the same */ -#define REAL_ADDRESSING 1 - -/* Using 68k natively */ -#define EMULATED_68K 0 - -/* Mac ROM is not write protected */ -#define ROM_IS_WRITE_PROTECTED 0 -#define USE_SCRATCHMEM_SUBTERFUGE 1 - -#else - -/* Mac and host address space are distinct */ -#ifndef REAL_ADDRESSING -#define REAL_ADDRESSING 0 -#endif - /* Using 68k emulator */ #define EMULATED_68K 1 @@ -92,21 +73,13 @@ #define USE_PREFETCH_BUFFER 0 /* Mac ROM is write protected when banked memory is used */ -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING # define ROM_IS_WRITE_PROTECTED 0 # define USE_SCRATCHMEM_SUBTERFUGE 1 #else # define ROM_IS_WRITE_PROTECTED 1 #endif -#endif - -/* Direct Addressing requires Video on SEGV signals in plain X11 mode */ -#if DIRECT_ADDRESSING && (!ENABLE_VOSF && !USE_SDL_VIDEO) -# undef ENABLE_VOSF -# define ENABLE_VOSF 1 -#endif - /* ExtFS is supported */ #define SUPPORTS_EXTFS 1 @@ -117,11 +90,6 @@ #ifdef HAVE_PTHREADS #define USE_PTHREADS_SERVICES #endif -#if EMULATED_68K -#if defined(__NetBSD__) -#define USE_CPU_EMUL_SERVICES -#endif -#endif #ifdef USE_CPU_EMUL_SERVICES #undef USE_PTHREADS_SERVICES #endif @@ -185,10 +153,11 @@ typedef char * caddr_t; #endif /* Time data type for Time Manager emulation */ -#ifdef HAVE_CLOCK_GETTIME -typedef struct timespec tm_time_t; -#elif defined(__MACH__) + +#if defined(__MACH__) typedef mach_timespec_t tm_time_t; +#elif defined(HAVE_CLOCK_GETTIME) +typedef struct timespec tm_time_t; #else typedef struct timeval tm_time_t; #endif @@ -221,107 +190,6 @@ typedef uae_u32 uaecptr; extern uint64 GetTicks_usec(void); extern void Delay_usec(uint32 usec); -/* Spinlocks */ -#ifdef __GNUC__ - -#if defined(__powerpc__) || defined(__ppc__) -#define HAVE_TEST_AND_SET 1 -static inline int testandset(volatile int *p) -{ - int ret; - __asm__ __volatile__("0: lwarx %0,0,%1\n" - " xor. %0,%3,%0\n" - " bne 1f\n" - " stwcx. %2,0,%1\n" - " bne- 0b\n" - "1: " - : "=&r" (ret) - : "r" (p), "r" (1), "r" (0) - : "cr0", "memory"); - return ret; -} -#endif - -/* FIXME: SheepShaver occasionnally hangs with those locks */ -#if 0 && (defined(__i386__) || defined(__x86_64__)) -#define HAVE_TEST_AND_SET 1 -static inline int testandset(volatile int *p) -{ - long int ret; - /* Note: the "xchg" instruction does not need a "lock" prefix */ - __asm__ __volatile__("xchgl %k0, %1" - : "=r" (ret), "=m" (*p) - : "0" (1), "m" (*p) - : "memory"); - return ret; -} -#endif - -#ifdef __s390__ -#define HAVE_TEST_AND_SET 1 -static inline int testandset(volatile int *p) -{ - int ret; - - __asm__ __volatile__("0: cs %0,%1,0(%2)\n" - " jl 0b" - : "=&d" (ret) - : "r" (1), "a" (p), "0" (*p) - : "cc", "memory" ); - return ret; -} -#endif - -#ifdef __alpha__ -#define HAVE_TEST_AND_SET 1 -static inline int testandset(volatile int *p) -{ - int ret; - unsigned long one; - - __asm__ __volatile__("0: mov 1,%2\n" - " ldl_l %0,%1\n" - " stl_c %2,%1\n" - " beq %2,1f\n" - ".subsection 2\n" - "1: br 0b\n" - ".previous" - : "=r" (ret), "=m" (*p), "=r" (one) - : "m" (*p)); - return ret; -} -#endif - -#ifdef __sparc__ -#define HAVE_TEST_AND_SET 1 -static inline int testandset(volatile int *p) -{ - int ret; - - __asm__ __volatile__("ldstub [%1], %0" - : "=r" (ret) - : "r" (p) - : "memory"); - - return (ret ? 1 : 0); -} -#endif - -#ifdef __arm__ -#define HAVE_TEST_AND_SET 1 -static inline int testandset(volatile int *p) -{ - register unsigned int ret; - __asm__ __volatile__("swp %0, %1, [%2]" - : "=r"(ret) - : "0"(1), "r"(p)); - - return ret; -} -#endif - -#endif /* __GNUC__ */ - typedef volatile int spinlock_t; static const spinlock_t SPIN_LOCK_UNLOCKED = 0; @@ -357,25 +225,6 @@ static inline int spin_trylock(spinlock_t *lock) } #endif -/* X11 display fast locks */ -#ifdef HAVE_SPINLOCKS -#define X11_LOCK_TYPE spinlock_t -#define X11_LOCK_INIT SPIN_LOCK_UNLOCKED -#define XDisplayLock() spin_lock(&x_display_lock) -#define XDisplayUnlock() spin_unlock(&x_display_lock) -#elif defined(HAVE_PTHREADS) -#define X11_LOCK_TYPE pthread_mutex_t -#define X11_LOCK_INIT PTHREAD_MUTEX_INITIALIZER -#define XDisplayLock() pthread_mutex_lock(&x_display_lock); -#define XDisplayUnlock() pthread_mutex_unlock(&x_display_lock); -#else -#define XDisplayLock() -#define XDisplayUnlock() -#endif -#ifdef X11_LOCK_TYPE -extern X11_LOCK_TYPE x_display_lock; -#endif - #ifdef HAVE_PTHREADS /* Centralized pthread attribute setup */ void Set_pthread_attr(pthread_attr_t *attr, int priority); diff --git a/BasiliskII/src/Unix/timer_unix.cpp b/BasiliskII/src/Unix/timer_unix.cpp index 9e227d02..a73e4280 100644 --- a/BasiliskII/src/Unix/timer_unix.cpp +++ b/BasiliskII/src/Unix/timer_unix.cpp @@ -27,11 +27,6 @@ #define DEBUG 0 #include "debug.h" -// For NetBSD with broken pthreads headers -#ifndef CLOCK_REALTIME -#define CLOCK_REALTIME 0 -#endif - #if defined(__MACH__) #include #include @@ -57,14 +52,14 @@ static inline void mach_current_time(tm_time_t &t) { void Microseconds(uint32 &hi, uint32 &lo) { D(bug("Microseconds\n")); -#if defined(HAVE_CLOCK_GETTIME) - struct timespec t; - clock_gettime(CLOCK_REALTIME, &t); - uint64 tl = (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000; -#elif defined(__MACH__) +#if defined(__MACH__) tm_time_t t; mach_current_time(t); uint64 tl = (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000; +#elif defined(HAVE_CLOCK_GETTIME) + struct timespec t; + clock_gettime(CLOCK_REALTIME, &t); + uint64 tl = (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000; #else struct timeval t; gettimeofday(&t, NULL); @@ -91,10 +86,10 @@ uint32 TimerDateTime(void) void timer_current_time(tm_time_t &t) { -#ifdef HAVE_CLOCK_GETTIME - clock_gettime(CLOCK_REALTIME, &t); -#elif defined(__MACH__) +#if defined(__MACH__) mach_current_time(t); +#elif defined(HAVE_CLOCK_GETTIME) + clock_gettime(CLOCK_REALTIME, &t); #else gettimeofday(&t, NULL); #endif @@ -229,14 +224,14 @@ int32 timer_host2mac_time(tm_time_t hosttime) uint64 GetTicks_usec(void) { -#ifdef HAVE_CLOCK_GETTIME - struct timespec t; - clock_gettime(CLOCK_REALTIME, &t); - return (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000; -#elif defined(__MACH__) +#if defined(__MACH__) tm_time_t t; mach_current_time(t); return (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000; +#elif defined(HAVE_CLOCK_GETTIME) + struct timespec t; + clock_gettime(CLOCK_REALTIME, &t); + return (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000; #else struct timeval t; gettimeofday(&t, NULL); @@ -251,17 +246,8 @@ uint64 GetTicks_usec(void) * the highest accuracy possible) */ -#if defined(linux) -// Linux select() changes its timeout parameter upon return to contain -// the remaining time. Most other unixen leave it unchanged or undefined. -#define SELECT_SETS_REMAINING -#elif defined(__FreeBSD__) || defined(__sun__) || (defined(__MACH__) && defined(__APPLE__)) +#if (defined(__MACH__) && defined(__APPLE__)) #define USE_NANOSLEEP -#elif defined(HAVE_PTHREADS) && defined(sgi) -// SGI pthreads has a bug when using pthreads+signals+nanosleep, -// so instead of using nanosleep, wait on a CV which is never signalled. -#include -#define USE_COND_TIMEDWAIT #endif void Delay_usec(uint32 usec) @@ -283,7 +269,6 @@ void Delay_usec(uint32 usec) #endif #endif - // Set the timeout interval - Linux only needs to do this once #if defined(SELECT_SETS_REMAINING) tv.tv_sec = 0; tv.tv_usec = usec; diff --git a/BasiliskII/src/Unix/tinyxml2.cpp b/BasiliskII/src/Unix/tinyxml2.cpp deleted file mode 100755 index 4cd8695d..00000000 --- a/BasiliskII/src/Unix/tinyxml2.cpp +++ /dev/null @@ -1,2095 +0,0 @@ -/* -Original code by Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#include "tinyxml2.h" - -#include // yes, this one new style header, is in the Android SDK. -# ifdef ANDROID_NDK -# include -#else -# include -#endif - -static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF -static const char LF = LINE_FEED; -static const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out -static const char CR = CARRIAGE_RETURN; -static const char SINGLE_QUOTE = '\''; -static const char DOUBLE_QUOTE = '\"'; - -// Bunch of unicode info at: -// http://www.unicode.org/faq/utf_bom.html -// ef bb bf (Microsoft "lead bytes") - designates UTF-8 - -static const unsigned char TIXML_UTF_LEAD_0 = 0xefU; -static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; -static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - - -#define DELETE_NODE( node ) { \ - if ( node ) { \ - MemPool* pool = node->_memPool; \ - node->~XMLNode(); \ - pool->Free( node ); \ - } \ - } -#define DELETE_ATTRIBUTE( attrib ) { \ - if ( attrib ) { \ - MemPool* pool = attrib->_memPool; \ - attrib->~XMLAttribute(); \ - pool->Free( attrib ); \ - } \ - } - -namespace tinyxml2 -{ - -struct Entity { - const char* pattern; - int length; - char value; -}; - -static const int NUM_ENTITIES = 5; -static const Entity entities[NUM_ENTITIES] = { - { "quot", 4, DOUBLE_QUOTE }, - { "amp", 3, '&' }, - { "apos", 4, SINGLE_QUOTE }, - { "lt", 2, '<' }, - { "gt", 2, '>' } -}; - - -StrPair::~StrPair() -{ - Reset(); -} - - -void StrPair::Reset() -{ - if ( _flags & NEEDS_DELETE ) { - delete [] _start; - } - _flags = 0; - _start = 0; - _end = 0; -} - - -void StrPair::SetStr( const char* str, int flags ) -{ - Reset(); - size_t len = strlen( str ); - _start = new char[ len+1 ]; - memcpy( _start, str, len+1 ); - _end = _start + len; - _flags = flags | NEEDS_DELETE; -} - - -char* StrPair::ParseText( char* p, const char* endTag, int strFlags ) -{ - TIXMLASSERT( endTag && *endTag ); - - char* start = p; // fixme: hides a member - char endChar = *endTag; - size_t length = strlen( endTag ); - - // Inner loop of text parsing. - while ( *p ) { - if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) { - Set( start, p, strFlags ); - return p + length; - } - ++p; - } - return 0; -} - - -char* StrPair::ParseName( char* p ) -{ - char* start = p; - - if ( !start || !(*start) ) { - return 0; - } - - while( *p && ( p == start ? XMLUtil::IsNameStartChar( *p ) : XMLUtil::IsNameChar( *p ) )) { - ++p; - } - - if ( p > start ) { - Set( start, p, 0 ); - return p; - } - return 0; -} - - -void StrPair::CollapseWhitespace() -{ - // Trim leading space. - _start = XMLUtil::SkipWhiteSpace( _start ); - - if ( _start && *_start ) { - char* p = _start; // the read pointer - char* q = _start; // the write pointer - - while( *p ) { - if ( XMLUtil::IsWhiteSpace( *p )) { - p = XMLUtil::SkipWhiteSpace( p ); - if ( *p == 0 ) { - break; // don't write to q; this trims the trailing space. - } - *q = ' '; - ++q; - } - *q = *p; - ++q; - ++p; - } - *q = 0; - } -} - - -const char* StrPair::GetStr() -{ - if ( _flags & NEEDS_FLUSH ) { - *_end = 0; - _flags ^= NEEDS_FLUSH; - - if ( _flags ) { - char* p = _start; // the read pointer - char* q = _start; // the write pointer - - while( p < _end ) { - if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) { - // CR-LF pair becomes LF - // CR alone becomes LF - // LF-CR becomes LF - if ( *(p+1) == LF ) { - p += 2; - } - else { - ++p; - } - *q++ = LF; - } - else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) { - if ( *(p+1) == CR ) { - p += 2; - } - else { - ++p; - } - *q++ = LF; - } - else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) { - // Entities handled by tinyXML2: - // - special entities in the entity table [in/out] - // - numeric character reference [in] - // 中 or 中 - - if ( *(p+1) == '#' ) { - char buf[10] = { 0 }; - int len; - p = const_cast( XMLUtil::GetCharacterRef( p, buf, &len ) ); - for( int i=0; i(p); - // Check for BOM: - if ( *(pu+0) == TIXML_UTF_LEAD_0 - && *(pu+1) == TIXML_UTF_LEAD_1 - && *(pu+2) == TIXML_UTF_LEAD_2 ) { - *bom = true; - p += 3; - } - return p; -} - - -void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) -{ - const unsigned long BYTE_MASK = 0xBF; - const unsigned long BYTE_MARK = 0x80; - const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - - if (input < 0x80) { - *length = 1; - } - else if ( input < 0x800 ) { - *length = 2; - } - else if ( input < 0x10000 ) { - *length = 3; - } - else if ( input < 0x200000 ) { - *length = 4; - } - else { - *length = 0; // This code won't covert this correctly anyway. - return; - } - - output += *length; - - // Scary scary fall throughs. - switch (*length) { - case 4: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 3: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 2: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 1: - --output; - *output = (char)(input | FIRST_BYTE_MARK[*length]); - default: - break; - } -} - - -const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) -{ - // Presume an entity, and pull it out. - *length = 0; - - if ( *(p+1) == '#' && *(p+2) ) { - unsigned long ucs = 0; - ptrdiff_t delta = 0; - unsigned mult = 1; - - if ( *(p+2) == 'x' ) { - // Hexadecimal. - if ( !*(p+3) ) { - return 0; - } - - const char* q = p+3; - q = strchr( q, ';' ); - - if ( !q || !*q ) { - return 0; - } - - delta = q-p; - --q; - - while ( *q != 'x' ) { - if ( *q >= '0' && *q <= '9' ) { - ucs += mult * (*q - '0'); - } - else if ( *q >= 'a' && *q <= 'f' ) { - ucs += mult * (*q - 'a' + 10); - } - else if ( *q >= 'A' && *q <= 'F' ) { - ucs += mult * (*q - 'A' + 10 ); - } - else { - return 0; - } - mult *= 16; - --q; - } - } - else { - // Decimal. - if ( !*(p+2) ) { - return 0; - } - - const char* q = p+2; - q = strchr( q, ';' ); - - if ( !q || !*q ) { - return 0; - } - - delta = q-p; - --q; - - while ( *q != '#' ) { - if ( *q >= '0' && *q <= '9' ) { - ucs += mult * (*q - '0'); - } - else { - return 0; - } - mult *= 10; - --q; - } - } - // convert the UCS to UTF-8 - ConvertUTF32ToUTF8( ucs, value, length ); - return p + delta + 1; - } - return p+1; -} - - -void XMLUtil::ToStr( int v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%d", v ); -} - - -void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%u", v ); -} - - -void XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 ); -} - - -void XMLUtil::ToStr( float v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%g", v ); -} - - -void XMLUtil::ToStr( double v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%g", v ); -} - - -bool XMLUtil::ToInt( const char* str, int* value ) -{ - if ( TIXML_SSCANF( str, "%d", value ) == 1 ) { - return true; - } - return false; -} - -bool XMLUtil::ToUnsigned( const char* str, unsigned *value ) -{ - if ( TIXML_SSCANF( str, "%u", value ) == 1 ) { - return true; - } - return false; -} - -bool XMLUtil::ToBool( const char* str, bool* value ) -{ - int ival = 0; - if ( ToInt( str, &ival )) { - *value = (ival==0) ? false : true; - return true; - } - if ( StringEqual( str, "true" ) ) { - *value = true; - return true; - } - else if ( StringEqual( str, "false" ) ) { - *value = false; - return true; - } - return false; -} - - -bool XMLUtil::ToFloat( const char* str, float* value ) -{ - if ( TIXML_SSCANF( str, "%f", value ) == 1 ) { - return true; - } - return false; -} - -bool XMLUtil::ToDouble( const char* str, double* value ) -{ - if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) { - return true; - } - return false; -} - - -char* XMLDocument::Identify( char* p, XMLNode** node ) -{ - XMLNode* returnNode = 0; - char* start = p; - p = XMLUtil::SkipWhiteSpace( p ); - if( !p || !*p ) { - return p; - } - - // What is this thing? - // - Elements start with a letter or underscore, but xml is reserved. - // - Comments: - // - // With a special case: - // - // - // - // - // Where the closing element (/foo) *must* be the next thing after the opening - // element, and the names must match. BUT the tricky bit is that the closing - // element will be read by the child. - // - // 'endTag' is the end tag for this node, it is returned by a call to a child. - // 'parentEnd' is the end tag for the parent, which is filled in and returned. - - while( p && *p ) { - XMLNode* node = 0; - - p = _document->Identify( p, &node ); - if ( p == 0 || node == 0 ) { - break; - } - - StrPair endTag; - p = node->ParseDeep( p, &endTag ); - if ( !p ) { - DELETE_NODE( node ); - node = 0; - if ( !_document->Error() ) { - _document->SetError( XML_ERROR_PARSING, 0, 0 ); - } - break; - } - - // We read the end tag. Return it to the parent. - if ( node->ToElement() && node->ToElement()->ClosingType() == XMLElement::CLOSING ) { - if ( parentEnd ) { - *parentEnd = static_cast(node)->_value; - } - node->_memPool->SetTracked(); // created and then immediately deleted. - DELETE_NODE( node ); - return p; - } - - // Handle an end tag returned to this level. - // And handle a bunch of annoying errors. - XMLElement* ele = node->ToElement(); - if ( ele ) { - if ( endTag.Empty() && ele->ClosingType() == XMLElement::OPEN ) { - _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); - p = 0; - } - else if ( !endTag.Empty() && ele->ClosingType() != XMLElement::OPEN ) { - _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); - p = 0; - } - else if ( !endTag.Empty() ) { - if ( !XMLUtil::StringEqual( endTag.GetStr(), node->Value() )) { - _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); - p = 0; - } - } - } - if ( p == 0 ) { - DELETE_NODE( node ); - node = 0; - } - if ( node ) { - this->InsertEndChild( node ); - } - } - return 0; -} - -// --------- XMLText ---------- // -char* XMLText::ParseDeep( char* p, StrPair* ) -{ - const char* start = p; - if ( this->CData() ) { - p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_CDATA, start, 0 ); - } - return p; - } - else { - int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES; - if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) { - flags |= StrPair::COLLAPSE_WHITESPACE; - } - - p = _value.ParseText( p, "<", flags ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_TEXT, start, 0 ); - } - if ( p && *p ) { - return p-1; - } - } - return 0; -} - - -XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern? - text->SetCData( this->CData() ); - return text; -} - - -bool XMLText::ShallowEqual( const XMLNode* compare ) const -{ - return ( compare->ToText() && XMLUtil::StringEqual( compare->ToText()->Value(), Value() )); -} - - -bool XMLText::Accept( XMLVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -// --------- XMLComment ---------- // - -XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLComment::~XMLComment() -{ -} - - -char* XMLComment::ParseDeep( char* p, StrPair* ) -{ - // Comment parses as text. - const char* start = p; - p = _value.ParseText( p, "-->", StrPair::COMMENT ); - if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_COMMENT, start, 0 ); - } - return p; -} - - -XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern? - return comment; -} - - -bool XMLComment::ShallowEqual( const XMLNode* compare ) const -{ - return ( compare->ToComment() && XMLUtil::StringEqual( compare->ToComment()->Value(), Value() )); -} - - -bool XMLComment::Accept( XMLVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -// --------- XMLDeclaration ---------- // - -XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLDeclaration::~XMLDeclaration() -{ - //printf( "~XMLDeclaration\n" ); -} - - -char* XMLDeclaration::ParseDeep( char* p, StrPair* ) -{ - // Declaration parses as text. - const char* start = p; - p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); - if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_DECLARATION, start, 0 ); - } - return p; -} - - -XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern? - return dec; -} - - -bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const -{ - return ( compare->ToDeclaration() && XMLUtil::StringEqual( compare->ToDeclaration()->Value(), Value() )); -} - - - -bool XMLDeclaration::Accept( XMLVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - -// --------- XMLUnknown ---------- // - -XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLUnknown::~XMLUnknown() -{ -} - - -char* XMLUnknown::ParseDeep( char* p, StrPair* ) -{ - // Unknown parses as text. - const char* start = p; - - p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_UNKNOWN, start, 0 ); - } - return p; -} - - -XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern? - return text; -} - - -bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const -{ - return ( compare->ToUnknown() && XMLUtil::StringEqual( compare->ToUnknown()->Value(), Value() )); -} - - -bool XMLUnknown::Accept( XMLVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - -// --------- XMLAttribute ---------- // -char* XMLAttribute::ParseDeep( char* p, bool processEntities ) -{ - // Parse using the name rules: bug fix, was using ParseText before - p = _name.ParseName( p ); - if ( !p || !*p ) { - return 0; - } - - // Skip white space before = - p = XMLUtil::SkipWhiteSpace( p ); - if ( !p || *p != '=' ) { - return 0; - } - - ++p; // move up to opening quote - p = XMLUtil::SkipWhiteSpace( p ); - if ( *p != '\"' && *p != '\'' ) { - return 0; - } - - char endTag[2] = { *p, 0 }; - ++p; // move past opening quote - - p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES ); - return p; -} - - -void XMLAttribute::SetName( const char* n ) -{ - _name.SetStr( n ); -} - - -XMLError XMLAttribute::QueryIntValue( int* value ) const -{ - if ( XMLUtil::ToInt( Value(), value )) { - return XML_NO_ERROR; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const -{ - if ( XMLUtil::ToUnsigned( Value(), value )) { - return XML_NO_ERROR; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryBoolValue( bool* value ) const -{ - if ( XMLUtil::ToBool( Value(), value )) { - return XML_NO_ERROR; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryFloatValue( float* value ) const -{ - if ( XMLUtil::ToFloat( Value(), value )) { - return XML_NO_ERROR; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryDoubleValue( double* value ) const -{ - if ( XMLUtil::ToDouble( Value(), value )) { - return XML_NO_ERROR; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -void XMLAttribute::SetAttribute( const char* v ) -{ - _value.SetStr( v ); -} - - -void XMLAttribute::SetAttribute( int v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -void XMLAttribute::SetAttribute( unsigned v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -void XMLAttribute::SetAttribute( bool v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - -void XMLAttribute::SetAttribute( double v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - -void XMLAttribute::SetAttribute( float v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -// --------- XMLElement ---------- // -XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), - _closingType( 0 ), - _rootAttribute( 0 ) -{ -} - - -XMLElement::~XMLElement() -{ - while( _rootAttribute ) { - XMLAttribute* next = _rootAttribute->_next; - DELETE_ATTRIBUTE( _rootAttribute ); - _rootAttribute = next; - } -} - - -XMLAttribute* XMLElement::FindAttribute( const char* name ) -{ - XMLAttribute* a = 0; - for( a=_rootAttribute; a; a = a->_next ) { - if ( XMLUtil::StringEqual( a->Name(), name ) ) { - return a; - } - } - return 0; -} - - -const XMLAttribute* XMLElement::FindAttribute( const char* name ) const -{ - XMLAttribute* a = 0; - for( a=_rootAttribute; a; a = a->_next ) { - if ( XMLUtil::StringEqual( a->Name(), name ) ) { - return a; - } - } - return 0; -} - - -const char* XMLElement::Attribute( const char* name, const char* value ) const -{ - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return 0; - } - if ( !value || XMLUtil::StringEqual( a->Value(), value )) { - return a->Value(); - } - return 0; -} - - -const char* XMLElement::GetText() const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - return FirstChild()->ToText()->Value(); - } - return 0; -} - - -XMLError XMLElement::QueryIntText( int* ival ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->ToText()->Value(); - if ( XMLUtil::ToInt( t, ival ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->ToText()->Value(); - if ( XMLUtil::ToUnsigned( t, uval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryBoolText( bool* bval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->ToText()->Value(); - if ( XMLUtil::ToBool( t, bval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryDoubleText( double* dval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->ToText()->Value(); - if ( XMLUtil::ToDouble( t, dval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryFloatText( float* fval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->ToText()->Value(); - if ( XMLUtil::ToFloat( t, fval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - - -XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) -{ - XMLAttribute* last = 0; - XMLAttribute* attrib = 0; - for( attrib = _rootAttribute; - attrib; - last = attrib, attrib = attrib->_next ) { - if ( XMLUtil::StringEqual( attrib->Name(), name ) ) { - break; - } - } - if ( !attrib ) { - attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); - attrib->_memPool = &_document->_attributePool; - if ( last ) { - last->_next = attrib; - } - else { - _rootAttribute = attrib; - } - attrib->SetName( name ); - attrib->_memPool->SetTracked(); // always created and linked. - } - return attrib; -} - - -void XMLElement::DeleteAttribute( const char* name ) -{ - XMLAttribute* prev = 0; - for( XMLAttribute* a=_rootAttribute; a; a=a->_next ) { - if ( XMLUtil::StringEqual( name, a->Name() ) ) { - if ( prev ) { - prev->_next = a->_next; - } - else { - _rootAttribute = a->_next; - } - DELETE_ATTRIBUTE( a ); - break; - } - prev = a; - } -} - - -char* XMLElement::ParseAttributes( char* p ) -{ - const char* start = p; - XMLAttribute* prevAttribute = 0; - - // Read the attributes. - while( p ) { - p = XMLUtil::SkipWhiteSpace( p ); - if ( !p || !(*p) ) { - _document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); - return 0; - } - - // attribute. - if (XMLUtil::IsNameStartChar( *p ) ) { - XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); - attrib->_memPool = &_document->_attributePool; - attrib->_memPool->SetTracked(); - - p = attrib->ParseDeep( p, _document->ProcessEntities() ); - if ( !p || Attribute( attrib->Name() ) ) { - DELETE_ATTRIBUTE( attrib ); - _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); - return 0; - } - // There is a minor bug here: if the attribute in the source xml - // document is duplicated, it will not be detected and the - // attribute will be doubly added. However, tracking the 'prevAttribute' - // avoids re-scanning the attribute list. Preferring performance for - // now, may reconsider in the future. - if ( prevAttribute ) { - prevAttribute->_next = attrib; - } - else { - _rootAttribute = attrib; - } - prevAttribute = attrib; - } - // end of the tag - else if ( *p == '/' && *(p+1) == '>' ) { - _closingType = CLOSED; - return p+2; // done; sealed element. - } - // end of the tag - else if ( *p == '>' ) { - ++p; - break; - } - else { - _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); - return 0; - } - } - return p; -} - - -// -// -// foobar -// -char* XMLElement::ParseDeep( char* p, StrPair* strPair ) -{ - // Read the element name. - p = XMLUtil::SkipWhiteSpace( p ); - if ( !p ) { - return 0; - } - - // The closing element is the form. It is - // parsed just like a regular element then deleted from - // the DOM. - if ( *p == '/' ) { - _closingType = CLOSING; - ++p; - } - - p = _value.ParseName( p ); - if ( _value.Empty() ) { - return 0; - } - - p = ParseAttributes( p ); - if ( !p || !*p || _closingType ) { - return p; - } - - p = XMLNode::ParseDeep( p, strPair ); - return p; -} - - - -XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern? - for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) { - element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern? - } - return element; -} - - -bool XMLElement::ShallowEqual( const XMLNode* compare ) const -{ - const XMLElement* other = compare->ToElement(); - if ( other && XMLUtil::StringEqual( other->Value(), Value() )) { - - const XMLAttribute* a=FirstAttribute(); - const XMLAttribute* b=other->FirstAttribute(); - - while ( a && b ) { - if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) { - return false; - } - a = a->Next(); - b = b->Next(); - } - if ( a || b ) { - // different count - return false; - } - return true; - } - return false; -} - - -bool XMLElement::Accept( XMLVisitor* visitor ) const -{ - if ( visitor->VisitEnter( *this, _rootAttribute ) ) { - for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { - if ( !node->Accept( visitor ) ) { - break; - } - } - } - return visitor->VisitExit( *this ); -} - - -// --------- XMLDocument ----------- // -XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) : - XMLNode( 0 ), - _writeBOM( false ), - _processEntities( processEntities ), - _errorID( XML_NO_ERROR ), - _whitespace( whitespace ), - _errorStr1( 0 ), - _errorStr2( 0 ), - _charBuffer( 0 ) -{ - _document = this; // avoid warning about 'this' in initializer list -} - - -XMLDocument::~XMLDocument() -{ - DeleteChildren(); - delete [] _charBuffer; - -#if 0 - _textPool.Trace( "text" ); - _elementPool.Trace( "element" ); - _commentPool.Trace( "comment" ); - _attributePool.Trace( "attribute" ); -#endif - -#ifdef DEBUG - if ( Error() == false ) { - TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() ); - TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() ); - TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() ); - TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() ); - } -#endif -} - - -void XMLDocument::Clear() -{ - DeleteChildren(); - - _errorID = XML_NO_ERROR; - _errorStr1 = 0; - _errorStr2 = 0; - - delete [] _charBuffer; - _charBuffer = 0; -} - - -XMLElement* XMLDocument::NewElement( const char* name ) -{ - XMLElement* ele = new (_elementPool.Alloc()) XMLElement( this ); - ele->_memPool = &_elementPool; - ele->SetName( name ); - return ele; -} - - -XMLComment* XMLDocument::NewComment( const char* str ) -{ - XMLComment* comment = new (_commentPool.Alloc()) XMLComment( this ); - comment->_memPool = &_commentPool; - comment->SetValue( str ); - return comment; -} - - -XMLText* XMLDocument::NewText( const char* str ) -{ - XMLText* text = new (_textPool.Alloc()) XMLText( this ); - text->_memPool = &_textPool; - text->SetValue( str ); - return text; -} - - -XMLDeclaration* XMLDocument::NewDeclaration( const char* str ) -{ - XMLDeclaration* dec = new (_commentPool.Alloc()) XMLDeclaration( this ); - dec->_memPool = &_commentPool; - dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" ); - return dec; -} - - -XMLUnknown* XMLDocument::NewUnknown( const char* str ) -{ - XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown( this ); - unk->_memPool = &_commentPool; - unk->SetValue( str ); - return unk; -} - - -XMLError XMLDocument::LoadFile( const char* filename ) -{ - Clear(); - FILE* fp = 0; - -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - errno_t err = fopen_s(&fp, filename, "rb" ); - if ( !fp || err) { -#else - fp = fopen( filename, "rb" ); - if ( !fp) { -#endif - SetError( XML_ERROR_FILE_NOT_FOUND, filename, 0 ); - return _errorID; - } - LoadFile( fp ); - fclose( fp ); - return _errorID; -} - - -XMLError XMLDocument::LoadFile( FILE* fp ) -{ - Clear(); - - fseek( fp, 0, SEEK_END ); - size_t size = ftell( fp ); - fseek( fp, 0, SEEK_SET ); - - if ( size == 0 ) { - return _errorID; - } - - _charBuffer = new char[size+1]; - size_t read = fread( _charBuffer, 1, size, fp ); - if ( read != size ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - - _charBuffer[size] = 0; - - const char* p = _charBuffer; - p = XMLUtil::SkipWhiteSpace( p ); - p = XMLUtil::ReadBOM( p, &_writeBOM ); - if ( !p || !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - - ParseDeep( _charBuffer + (p-_charBuffer), 0 ); - return _errorID; -} - - -XMLError XMLDocument::SaveFile( const char* filename, bool compact ) -{ - FILE* fp = 0; -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - errno_t err = fopen_s(&fp, filename, "w" ); - if ( !fp || err) { -#else - fp = fopen( filename, "w" ); - if ( !fp) { -#endif - SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 ); - return _errorID; - } - SaveFile(fp, compact); - fclose( fp ); - return _errorID; -} - - -XMLError XMLDocument::SaveFile( FILE* fp, bool compact ) -{ - XMLPrinter stream( fp, compact ); - Print( &stream ); - return _errorID; -} - - -XMLError XMLDocument::Parse( const char* p, size_t len ) -{ - Clear(); - - if ( !p || !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - if ( len == (size_t)(-1) ) { - len = strlen( p ); - } - _charBuffer = new char[ len+1 ]; - memcpy( _charBuffer, p, len ); - _charBuffer[len] = 0; - - p = XMLUtil::SkipWhiteSpace( p ); - p = XMLUtil::ReadBOM( p, &_writeBOM ); - if ( !p || !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - - ParseDeep( _charBuffer, 0 ); - return _errorID; -} - - -void XMLDocument::Print( XMLPrinter* streamer ) -{ - XMLPrinter stdStreamer( stdout ); - if ( !streamer ) { - streamer = &stdStreamer; - } - Accept( streamer ); -} - - -void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 ) -{ - _errorID = error; - _errorStr1 = str1; - _errorStr2 = str2; -} - - -void XMLDocument::PrintError() const -{ - if ( _errorID ) { - static const int LEN = 20; - char buf1[LEN] = { 0 }; - char buf2[LEN] = { 0 }; - - if ( _errorStr1 ) { - TIXML_SNPRINTF( buf1, LEN, "%s", _errorStr1 ); - } - if ( _errorStr2 ) { - TIXML_SNPRINTF( buf2, LEN, "%s", _errorStr2 ); - } - - printf( "XMLDocument error id=%d str1=%s str2=%s\n", - _errorID, buf1, buf2 ); - } -} - - -XMLPrinter::XMLPrinter( FILE* file, bool compact ) : - _elementJustOpened( false ), - _firstElement( true ), - _fp( file ), - _depth( 0 ), - _textDepth( -1 ), - _processEntities( true ), - _compactMode( compact ) -{ - for( int i=0; i'] = true; // not required, but consistency is nice - _buffer.Push( 0 ); -} - - -void XMLPrinter::Print( const char* format, ... ) -{ - va_list va; - va_start( va, format ); - - if ( _fp ) { - vfprintf( _fp, format, va ); - } - else { - // This seems brutally complex. Haven't figured out a better - // way on windows. -#ifdef _MSC_VER - int len = -1; - int expand = 1000; - while ( len < 0 ) { - len = vsnprintf_s( _accumulator.Mem(), _accumulator.Capacity(), _TRUNCATE, format, va ); - if ( len < 0 ) { - expand *= 3/2; - _accumulator.PushArr( expand ); - } - } - char* p = _buffer.PushArr( len ) - 1; - memcpy( p, _accumulator.Mem(), len+1 ); -#else - int len = vsnprintf( 0, 0, format, va ); - // Close out and re-start the va-args - va_end( va ); - va_start( va, format ); - char* p = _buffer.PushArr( len ) - 1; - vsnprintf( p, len+1, format, va ); -#endif - } - va_end( va ); -} - - -void XMLPrinter::PrintSpace( int depth ) -{ - for( int i=0; i 0 && *q < ENTITY_RANGE ) { - // Check for entities. If one is found, flush - // the stream up until the entity, write the - // entity, and keep looking. - if ( flag[(unsigned)(*q)] ) { - while ( p < q ) { - Print( "%c", *p ); - ++p; - } - for( int i=0; i 0) ) { - Print( "%s", p ); - } -} - - -void XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) -{ - static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 }; - if ( writeBOM ) { - Print( "%s", bom ); - } - if ( writeDec ) { - PushDeclaration( "xml version=\"1.0\"" ); - } -} - - -void XMLPrinter::OpenElement( const char* name ) -{ - if ( _elementJustOpened ) { - SealElement(); - } - _stack.Push( name ); - - if ( _textDepth < 0 && !_firstElement && !_compactMode ) { - Print( "\n" ); - PrintSpace( _depth ); - } - - Print( "<%s", name ); - _elementJustOpened = true; - _firstElement = false; - ++_depth; -} - - -void XMLPrinter::PushAttribute( const char* name, const char* value ) -{ - TIXMLASSERT( _elementJustOpened ); - Print( " %s=\"", name ); - PrintString( value, false ); - Print( "\"" ); -} - - -void XMLPrinter::PushAttribute( const char* name, int v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute( const char* name, unsigned v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute( const char* name, bool v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute( const char* name, double v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::CloseElement() -{ - --_depth; - const char* name = _stack.Pop(); - - if ( _elementJustOpened ) { - Print( "/>" ); - } - else { - if ( _textDepth < 0 && !_compactMode) { - Print( "\n" ); - PrintSpace( _depth ); - } - Print( "", name ); - } - - if ( _textDepth == _depth ) { - _textDepth = -1; - } - if ( _depth == 0 && !_compactMode) { - Print( "\n" ); - } - _elementJustOpened = false; -} - - -void XMLPrinter::SealElement() -{ - _elementJustOpened = false; - Print( ">" ); -} - - -void XMLPrinter::PushText( const char* text, bool cdata ) -{ - _textDepth = _depth-1; - - if ( _elementJustOpened ) { - SealElement(); - } - if ( cdata ) { - Print( "" ); - } - else { - PrintString( text, true ); - } -} - -void XMLPrinter::PushText( int value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( unsigned value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( bool value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( float value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( double value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushComment( const char* comment ) -{ - if ( _elementJustOpened ) { - SealElement(); - } - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Print( "\n" ); - PrintSpace( _depth ); - } - _firstElement = false; - Print( "", comment ); -} - - -void XMLPrinter::PushDeclaration( const char* value ) -{ - if ( _elementJustOpened ) { - SealElement(); - } - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Print( "\n" ); - PrintSpace( _depth ); - } - _firstElement = false; - Print( "", value ); -} - - -void XMLPrinter::PushUnknown( const char* value ) -{ - if ( _elementJustOpened ) { - SealElement(); - } - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Print( "\n" ); - PrintSpace( _depth ); - } - _firstElement = false; - Print( "", value ); -} - - -bool XMLPrinter::VisitEnter( const XMLDocument& doc ) -{ - _processEntities = doc.ProcessEntities(); - if ( doc.HasBOM() ) { - PushHeader( true, false ); - } - return true; -} - - -bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) -{ - OpenElement( element.Name() ); - while ( attribute ) { - PushAttribute( attribute->Name(), attribute->Value() ); - attribute = attribute->Next(); - } - return true; -} - - -bool XMLPrinter::VisitExit( const XMLElement& ) -{ - CloseElement(); - return true; -} - - -bool XMLPrinter::Visit( const XMLText& text ) -{ - PushText( text.Value(), text.CData() ); - return true; -} - - -bool XMLPrinter::Visit( const XMLComment& comment ) -{ - PushComment( comment.Value() ); - return true; -} - -bool XMLPrinter::Visit( const XMLDeclaration& declaration ) -{ - PushDeclaration( declaration.Value() ); - return true; -} - - -bool XMLPrinter::Visit( const XMLUnknown& unknown ) -{ - PushUnknown( unknown.Value() ); - return true; -} - -} // namespace tinyxml2 - diff --git a/BasiliskII/src/Unix/tinyxml2.h b/BasiliskII/src/Unix/tinyxml2.h deleted file mode 100755 index 11fceb23..00000000 --- a/BasiliskII/src/Unix/tinyxml2.h +++ /dev/null @@ -1,1968 +0,0 @@ -/* -Original code by Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#ifndef TINYXML2_INCLUDED -#define TINYXML2_INCLUDED - -#if defined(ANDROID_NDK) || defined(__BORLANDC__) -# include -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include -# include -# include -#endif - -/* - TODO: intern strings instead of allocation. -*/ -/* - gcc: - g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe - - Formatting, Artistic Style: - AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h -*/ - -#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__) -# ifndef DEBUG -# define DEBUG -# endif -#endif - - -#if defined(DEBUG) -# if defined(_MSC_VER) -# define TIXMLASSERT( x ) if ( !(x)) { __debugbreak(); } //if ( !(x)) WinDebugBreak() -# elif defined (ANDROID_NDK) -# include -# define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } -# else -# include -# define TIXMLASSERT assert -# endif -# else -# define TIXMLASSERT( x ) {} -#endif - - -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) -// Microsoft visual studio, version 2005 and higher. -/*int _snprintf_s( - char *buffer, - size_t sizeOfBuffer, - size_t count, - const char *format [, - argument] ... -);*/ -inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) -{ - va_list va; - va_start( va, format ); - int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); - va_end( va ); - return result; -} -#define TIXML_SSCANF sscanf_s -#else -// GCC version 3 and higher -//#warning( "Using sn* functions." ) -#define TIXML_SNPRINTF snprintf -#define TIXML_SSCANF sscanf -#endif - -static const int TIXML2_MAJOR_VERSION = 1; -static const int TIXML2_MINOR_VERSION = 0; -static const int TIXML2_PATCH_VERSION = 11; - -namespace tinyxml2 -{ -class XMLDocument; -class XMLElement; -class XMLAttribute; -class XMLComment; -class XMLNode; -class XMLText; -class XMLDeclaration; -class XMLUnknown; - -class XMLPrinter; - -/* - A class that wraps strings. Normally stores the start and end - pointers into the XML file itself, and will apply normalization - and entity translation if actually read. Can also store (and memory - manage) a traditional char[] -*/ -class StrPair -{ -public: - enum { - NEEDS_ENTITY_PROCESSING = 0x01, - NEEDS_NEWLINE_NORMALIZATION = 0x02, - COLLAPSE_WHITESPACE = 0x04, - - TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, - TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_NAME = 0, - ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - COMMENT = NEEDS_NEWLINE_NORMALIZATION - }; - - StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {} - ~StrPair(); - - void Set( char* start, char* end, int flags ) { - Reset(); - _start = start; - _end = end; - _flags = flags | NEEDS_FLUSH; - } - - const char* GetStr(); - - bool Empty() const { - return _start == _end; - } - - void SetInternedStr( const char* str ) { - Reset(); - _start = const_cast(str); - } - - void SetStr( const char* str, int flags=0 ); - - char* ParseText( char* in, const char* endTag, int strFlags ); - char* ParseName( char* in ); - -private: - void Reset(); - void CollapseWhitespace(); - - enum { - NEEDS_FLUSH = 0x100, - NEEDS_DELETE = 0x200 - }; - - // After parsing, if *end != 0, it can be set to zero. - int _flags; - char* _start; - char* _end; -}; - - -/* - A dynamic array of Plain Old Data. Doesn't support constructors, etc. - Has a small initial memory pool, so that low or no usage will not - cause a call to new/delete -*/ -template -class DynArray -{ -public: - DynArray< T, INIT >() { - _mem = _pool; - _allocated = INIT; - _size = 0; - } - - ~DynArray() { - if ( _mem != _pool ) { - delete [] _mem; - } - } - - void Push( T t ) { - EnsureCapacity( _size+1 ); - _mem[_size++] = t; - } - - T* PushArr( int count ) { - EnsureCapacity( _size+count ); - T* ret = &_mem[_size]; - _size += count; - return ret; - } - - T Pop() { - return _mem[--_size]; - } - - void PopArr( int count ) { - TIXMLASSERT( _size >= count ); - _size -= count; - } - - bool Empty() const { - return _size == 0; - } - - T& operator[](int i) { - TIXMLASSERT( i>= 0 && i < _size ); - return _mem[i]; - } - - const T& operator[](int i) const { - TIXMLASSERT( i>= 0 && i < _size ); - return _mem[i]; - } - - int Size() const { - return _size; - } - - int Capacity() const { - return _allocated; - } - - const T* Mem() const { - return _mem; - } - - T* Mem() { - return _mem; - } - -private: - void EnsureCapacity( int cap ) { - if ( cap > _allocated ) { - int newAllocated = cap * 2; - T* newMem = new T[newAllocated]; - memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs - if ( _mem != _pool ) { - delete [] _mem; - } - _mem = newMem; - _allocated = newAllocated; - } - } - - T* _mem; - T _pool[INIT]; - int _allocated; // objects allocated - int _size; // number objects in use -}; - - -/* - Parent virtual class of a pool for fast allocation - and deallocation of objects. -*/ -class MemPool -{ -public: - MemPool() {} - virtual ~MemPool() {} - - virtual int ItemSize() const = 0; - virtual void* Alloc() = 0; - virtual void Free( void* ) = 0; - virtual void SetTracked() = 0; -}; - - -/* - Template child class to create pools of the correct type. -*/ -template< int SIZE > -class MemPoolT : public MemPool -{ -public: - MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} - ~MemPoolT() { - // Delete the blocks. - for( int i=0; i<_blockPtrs.Size(); ++i ) { - delete _blockPtrs[i]; - } - } - - virtual int ItemSize() const { - return SIZE; - } - int CurrentAllocs() const { - return _currentAllocs; - } - - virtual void* Alloc() { - if ( !_root ) { - // Need a new block. - Block* block = new Block(); - _blockPtrs.Push( block ); - - for( int i=0; ichunk[i].next = &block->chunk[i+1]; - } - block->chunk[COUNT-1].next = 0; - _root = block->chunk; - } - void* result = _root; - _root = _root->next; - - ++_currentAllocs; - if ( _currentAllocs > _maxAllocs ) { - _maxAllocs = _currentAllocs; - } - _nAllocs++; - _nUntracked++; - return result; - } - virtual void Free( void* mem ) { - if ( !mem ) { - return; - } - --_currentAllocs; - Chunk* chunk = (Chunk*)mem; -#ifdef DEBUG - memset( chunk, 0xfe, sizeof(Chunk) ); -#endif - chunk->next = _root; - _root = chunk; - } - void Trace( const char* name ) { - printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", - name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() ); - } - - void SetTracked() { - _nUntracked--; - } - - int Untracked() const { - return _nUntracked; - } - - // This number is perf sensitive. 4k seems like a good tradeoff on my machine. - // The test file is large, 170k. - // Release: VS2010 gcc(no opt) - // 1k: 4000 - // 2k: 4000 - // 4k: 3900 21000 - // 16k: 5200 - // 32k: 4300 - // 64k: 4000 21000 - enum { COUNT = (4*1024)/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private - -private: - union Chunk { - Chunk* next; - char mem[SIZE]; - }; - struct Block { - Chunk chunk[COUNT]; - }; - DynArray< Block*, 10 > _blockPtrs; - Chunk* _root; - - int _currentAllocs; - int _nAllocs; - int _maxAllocs; - int _nUntracked; -}; - - - -/** - Implements the interface to the "Visitor pattern" (see the Accept() method.) - If you call the Accept() method, it requires being passed a XMLVisitor - class to handle callbacks. For nodes that contain other nodes (Document, Element) - you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs - are simply called with Visit(). - - If you return 'true' from a Visit method, recursive parsing will continue. If you return - false, no children of this node or its sibilings will be visited. - - All flavors of Visit methods have a default implementation that returns 'true' (continue - visiting). You need to only override methods that are interesting to you. - - Generally Accept() is called on the TiXmlDocument, although all nodes support visiting. - - You should never change the document from a callback. - - @sa XMLNode::Accept() -*/ -class XMLVisitor -{ -public: - virtual ~XMLVisitor() {} - - /// Visit a document. - virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { - return true; - } - /// Visit a document. - virtual bool VisitExit( const XMLDocument& /*doc*/ ) { - return true; - } - - /// Visit an element. - virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) { - return true; - } - /// Visit an element. - virtual bool VisitExit( const XMLElement& /*element*/ ) { - return true; - } - - /// Visit a declaration. - virtual bool Visit( const XMLDeclaration& /*declaration*/ ) { - return true; - } - /// Visit a text node. - virtual bool Visit( const XMLText& /*text*/ ) { - return true; - } - /// Visit a comment node. - virtual bool Visit( const XMLComment& /*comment*/ ) { - return true; - } - /// Visit an unknown node. - virtual bool Visit( const XMLUnknown& /*unknown*/ ) { - return true; - } -}; - - -/* - Utility functionality. -*/ -class XMLUtil -{ -public: - // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't - // correct, but simple, and usually works. - static const char* SkipWhiteSpace( const char* p ) { - while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast(p) ) ) { - ++p; - } - return p; - } - static char* SkipWhiteSpace( char* p ) { - while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast(p) ) ) { - ++p; - } - return p; - } - static bool IsWhiteSpace( char p ) { - return !IsUTF8Continuation(p) && isspace( static_cast(p) ); - } - - inline static bool IsNameStartChar( unsigned char ch ) { - return ( ( ch < 128 ) ? isalpha( ch ) : 1 ) - || ch == ':' - || ch == '_'; - } - - inline static bool IsNameChar( unsigned char ch ) { - return IsNameStartChar( ch ) - || isdigit( ch ) - || ch == '.' - || ch == '-'; - } - - inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) { - int n = 0; - if ( p == q ) { - return true; - } - while( *p && *q && *p == *q && n(const_cast(this)->FirstChildElement( value )); - } - - /// Get the last child node, or null if none exists. - const XMLNode* LastChild() const { - return _lastChild; - } - - XMLNode* LastChild() { - return const_cast(const_cast(this)->LastChild() ); - } - - /** Get the last child element or optionally the last child - element with the specified name. - */ - const XMLElement* LastChildElement( const char* value=0 ) const; - - XMLElement* LastChildElement( const char* value=0 ) { - return const_cast(const_cast(this)->LastChildElement(value) ); - } - - /// Get the previous (left) sibling node of this node. - const XMLNode* PreviousSibling() const { - return _prev; - } - - XMLNode* PreviousSibling() { - return _prev; - } - - /// Get the previous (left) sibling element of this node, with an opitionally supplied name. - const XMLElement* PreviousSiblingElement( const char* value=0 ) const ; - - XMLElement* PreviousSiblingElement( const char* value=0 ) { - return const_cast(const_cast(this)->PreviousSiblingElement( value ) ); - } - - /// Get the next (right) sibling node of this node. - const XMLNode* NextSibling() const { - return _next; - } - - XMLNode* NextSibling() { - return _next; - } - - /// Get the next (right) sibling element of this node, with an opitionally supplied name. - const XMLElement* NextSiblingElement( const char* value=0 ) const; - - XMLElement* NextSiblingElement( const char* value=0 ) { - return const_cast(const_cast(this)->NextSiblingElement( value ) ); - } - - /** - Add a child node as the last (right) child. - */ - XMLNode* InsertEndChild( XMLNode* addThis ); - - XMLNode* LinkEndChild( XMLNode* addThis ) { - return InsertEndChild( addThis ); - } - /** - Add a child node as the first (left) child. - */ - XMLNode* InsertFirstChild( XMLNode* addThis ); - /** - Add a node after the specified child node. - */ - XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ); - - /** - Delete all the children of this node. - */ - void DeleteChildren(); - - /** - Delete a child of this node. - */ - void DeleteChild( XMLNode* node ); - - /** - Make a copy of this node, but not its children. - You may pass in a Document pointer that will be - the owner of the new Node. If the 'document' is - null, then the node returned will be allocated - from the current Document. (this->GetDocument()) - - Note: if called on a XMLDocument, this will return null. - */ - virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0; - - /** - Test if 2 nodes are the same, but don't test children. - The 2 nodes do not need to be in the same Document. - - Note: if called on a XMLDocument, this will return false. - */ - virtual bool ShallowEqual( const XMLNode* compare ) const = 0; - - /** Accept a hierarchical visit of the nodes in the TinyXML DOM. Every node in the - XML tree will be conditionally visited and the host will be called back - via the TiXmlVisitor interface. - - This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse - the XML for the callbacks, so the performance of TinyXML is unchanged by using this - interface versus any other.) - - The interface has been based on ideas from: - - - http://www.saxproject.org/ - - http://c2.com/cgi/wiki?HierarchicalVisitorPattern - - Which are both good references for "visiting". - - An example of using Accept(): - @verbatim - TiXmlPrinter printer; - tinyxmlDoc.Accept( &printer ); - const char* xmlcstr = printer.CStr(); - @endverbatim - */ - virtual bool Accept( XMLVisitor* visitor ) const = 0; - - // internal - virtual char* ParseDeep( char*, StrPair* ); - -protected: - XMLNode( XMLDocument* ); - virtual ~XMLNode(); - XMLNode( const XMLNode& ); // not supported - XMLNode& operator=( const XMLNode& ); // not supported - - XMLDocument* _document; - XMLNode* _parent; - mutable StrPair _value; - - XMLNode* _firstChild; - XMLNode* _lastChild; - - XMLNode* _prev; - XMLNode* _next; - -private: - MemPool* _memPool; - void Unlink( XMLNode* child ); -}; - - -/** XML text. - - Note that a text node can have child element nodes, for example: - @verbatim - This is bold - @endverbatim - - A text node can have 2 ways to output the next. "normal" output - and CDATA. It will default to the mode it was parsed from the XML file and - you generally want to leave it alone, but you can change the output mode with - SetCDATA() and query it with CDATA(). -*/ -class XMLText : public XMLNode -{ - friend class XMLBase; - friend class XMLDocument; -public: - virtual bool Accept( XMLVisitor* visitor ) const; - - virtual XMLText* ToText() { - return this; - } - virtual const XMLText* ToText() const { - return this; - } - - /// Declare whether this should be CDATA or standard text. - void SetCData( bool isCData ) { - _isCData = isCData; - } - /// Returns true if this is a CDATA text element. - bool CData() const { - return _isCData; - } - - char* ParseDeep( char*, StrPair* endTag ); - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} - virtual ~XMLText() {} - XMLText( const XMLText& ); // not supported - XMLText& operator=( const XMLText& ); // not supported - -private: - bool _isCData; -}; - - -/** An XML Comment. */ -class XMLComment : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLComment* ToComment() { - return this; - } - virtual const XMLComment* ToComment() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - char* ParseDeep( char*, StrPair* endTag ); - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLComment( XMLDocument* doc ); - virtual ~XMLComment(); - XMLComment( const XMLComment& ); // not supported - XMLComment& operator=( const XMLComment& ); // not supported - -private: -}; - - -/** In correct XML the declaration is the first entry in the file. - @verbatim - - @endverbatim - - TinyXML2 will happily read or write files without a declaration, - however. - - The text of the declaration isn't interpreted. It is parsed - and written as a string. -*/ -class XMLDeclaration : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLDeclaration* ToDeclaration() { - return this; - } - virtual const XMLDeclaration* ToDeclaration() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - char* ParseDeep( char*, StrPair* endTag ); - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLDeclaration( XMLDocument* doc ); - virtual ~XMLDeclaration(); - XMLDeclaration( const XMLDeclaration& ); // not supported - XMLDeclaration& operator=( const XMLDeclaration& ); // not supported -}; - - -/** Any tag that tinyXml doesn't recognize is saved as an - unknown. It is a tag of text, but should not be modified. - It will be written back to the XML, unchanged, when the file - is saved. - - DTD tags get thrown into TiXmlUnknowns. -*/ -class XMLUnknown : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLUnknown* ToUnknown() { - return this; - } - virtual const XMLUnknown* ToUnknown() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - char* ParseDeep( char*, StrPair* endTag ); - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLUnknown( XMLDocument* doc ); - virtual ~XMLUnknown(); - XMLUnknown( const XMLUnknown& ); // not supported - XMLUnknown& operator=( const XMLUnknown& ); // not supported -}; - - -enum XMLError { - XML_NO_ERROR = 0, - XML_SUCCESS = 0, - - XML_NO_ATTRIBUTE, - XML_WRONG_ATTRIBUTE_TYPE, - - XML_ERROR_FILE_NOT_FOUND, - XML_ERROR_FILE_COULD_NOT_BE_OPENED, - XML_ERROR_FILE_READ_ERROR, - XML_ERROR_ELEMENT_MISMATCH, - XML_ERROR_PARSING_ELEMENT, - XML_ERROR_PARSING_ATTRIBUTE, - XML_ERROR_IDENTIFYING_TAG, - XML_ERROR_PARSING_TEXT, - XML_ERROR_PARSING_CDATA, - XML_ERROR_PARSING_COMMENT, - XML_ERROR_PARSING_DECLARATION, - XML_ERROR_PARSING_UNKNOWN, - XML_ERROR_EMPTY_DOCUMENT, - XML_ERROR_MISMATCHED_ELEMENT, - XML_ERROR_PARSING, - - XML_CAN_NOT_CONVERT_TEXT, - XML_NO_TEXT_NODE -}; - - -/** An attribute is a name-value pair. Elements have an arbitrary - number of attributes, each with a unique name. - - @note The attributes are not XMLNodes. You may only query the - Next() attribute in a list. -*/ -class XMLAttribute -{ - friend class XMLElement; -public: - /// The name of the attribute. - const char* Name() const { - return _name.GetStr(); - } - /// The value of the attribute. - const char* Value() const { - return _value.GetStr(); - } - /// The next attribute in the list. - const XMLAttribute* Next() const { - return _next; - } - - /** IntAttribute interprets the attribute as an integer, and returns the value. - If the value isn't an integer, 0 will be returned. There is no error checking; - use QueryIntAttribute() if you need error checking. - */ - int IntValue() const { - int i=0; - QueryIntValue( &i ); - return i; - } - /// Query as an unsigned integer. See IntAttribute() - unsigned UnsignedValue() const { - unsigned i=0; - QueryUnsignedValue( &i ); - return i; - } - /// Query as a boolean. See IntAttribute() - bool BoolValue() const { - bool b=false; - QueryBoolValue( &b ); - return b; - } - /// Query as a double. See IntAttribute() - double DoubleValue() const { - double d=0; - QueryDoubleValue( &d ); - return d; - } - /// Query as a float. See IntAttribute() - float FloatValue() const { - float f=0; - QueryFloatValue( &f ); - return f; - } - - /** QueryIntAttribute interprets the attribute as an integer, and returns the value - in the provided paremeter. The function will return XML_NO_ERROR on success, - and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful. - */ - XMLError QueryIntValue( int* value ) const; - /// See QueryIntAttribute - XMLError QueryUnsignedValue( unsigned int* value ) const; - /// See QueryIntAttribute - XMLError QueryBoolValue( bool* value ) const; - /// See QueryIntAttribute - XMLError QueryDoubleValue( double* value ) const; - /// See QueryIntAttribute - XMLError QueryFloatValue( float* value ) const; - - /// Set the attribute to a string value. - void SetAttribute( const char* value ); - /// Set the attribute to value. - void SetAttribute( int value ); - /// Set the attribute to value. - void SetAttribute( unsigned value ); - /// Set the attribute to value. - void SetAttribute( bool value ); - /// Set the attribute to value. - void SetAttribute( double value ); - /// Set the attribute to value. - void SetAttribute( float value ); - -private: - enum { BUF_SIZE = 200 }; - - XMLAttribute() : _next( 0 ) {} - virtual ~XMLAttribute() {} - - XMLAttribute( const XMLAttribute& ); // not supported - void operator=( const XMLAttribute& ); // not supported - void SetName( const char* name ); - - char* ParseDeep( char* p, bool processEntities ); - - mutable StrPair _name; - mutable StrPair _value; - XMLAttribute* _next; - MemPool* _memPool; -}; - - -/** The element is a container class. It has a value, the element name, - and can contain other elements, text, comments, and unknowns. - Elements also contain an arbitrary number of attributes. -*/ -class XMLElement : public XMLNode -{ - friend class XMLBase; - friend class XMLDocument; -public: - /// Get the name of an element (which is the Value() of the node.) - const char* Name() const { - return Value(); - } - /// Set the name of the element. - void SetName( const char* str, bool staticMem=false ) { - SetValue( str, staticMem ); - } - - virtual XMLElement* ToElement() { - return this; - } - virtual const XMLElement* ToElement() const { - return this; - } - virtual bool Accept( XMLVisitor* visitor ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none - exists. For example: - - @verbatim - const char* value = ele->Attribute( "foo" ); - @endverbatim - - The 'value' parameter is normally null. However, if specified, - the attribute will only be returned if the 'name' and 'value' - match. This allow you to write code: - - @verbatim - if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar(); - @endverbatim - - rather than: - @verbatim - if ( ele->Attribute( "foo" ) ) { - if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar(); - } - @endverbatim - */ - const char* Attribute( const char* name, const char* value=0 ) const; - - /** Given an attribute name, IntAttribute() returns the value - of the attribute interpreted as an integer. 0 will be - returned if there is an error. For a method with error - checking, see QueryIntAttribute() - */ - int IntAttribute( const char* name ) const { - int i=0; - QueryIntAttribute( name, &i ); - return i; - } - /// See IntAttribute() - unsigned UnsignedAttribute( const char* name ) const { - unsigned i=0; - QueryUnsignedAttribute( name, &i ); - return i; - } - /// See IntAttribute() - bool BoolAttribute( const char* name ) const { - bool b=false; - QueryBoolAttribute( name, &b ); - return b; - } - /// See IntAttribute() - double DoubleAttribute( const char* name ) const { - double d=0; - QueryDoubleAttribute( name, &d ); - return d; - } - /// See IntAttribute() - float FloatAttribute( const char* name ) const { - float f=0; - QueryFloatAttribute( name, &f ); - return f; - } - - /** Given an attribute name, QueryIntAttribute() returns - XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion - can't be performed, or XML_NO_ATTRIBUTE if the attribute - doesn't exist. If successful, the result of the conversion - will be written to 'value'. If not successful, nothing will - be written to 'value'. This allows you to provide default - value: - - @verbatim - int value = 10; - QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 - @endverbatim - */ - XMLError QueryIntAttribute( const char* name, int* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryIntValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryUnsignedValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryBoolAttribute( const char* name, bool* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryBoolValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryDoubleAttribute( const char* name, double* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryDoubleValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryFloatAttribute( const char* name, float* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryFloatValue( value ); - } - - - /** Given an attribute name, QueryAttribute() returns - XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion - can't be performed, or XML_NO_ATTRIBUTE if the attribute - doesn't exist. It is overloaded for the primitive types, - and is a generally more convenient replacement of - QueryIntAttribute() and related functions. - - If successful, the result of the conversion - will be written to 'value'. If not successful, nothing will - be written to 'value'. This allows you to provide default - value: - - @verbatim - int value = 10; - QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 - @endverbatim - */ - int QueryAttribute( const char* name, int* value ) const { - return QueryIntAttribute( name, value ); - } - - int QueryAttribute( const char* name, unsigned int* value ) const { - return QueryUnsignedAttribute( name, value ); - } - - int QueryAttribute( const char* name, bool* value ) const { - return QueryBoolAttribute( name, value ); - } - - int QueryAttribute( const char* name, double* value ) const { - return QueryDoubleAttribute( name, value ); - } - - int QueryAttribute( const char* name, float* value ) const { - return QueryFloatAttribute( name, value ); - } - - /// Sets the named attribute to value. - void SetAttribute( const char* name, const char* value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, int value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, unsigned value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, bool value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, double value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - - /** - Delete an attribute. - */ - void DeleteAttribute( const char* name ); - - /// Return the first attribute in the list. - const XMLAttribute* FirstAttribute() const { - return _rootAttribute; - } - /// Query a specific attribute in the list. - const XMLAttribute* FindAttribute( const char* name ) const; - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, GetText() is limited compared to getting the TiXmlText child - and accessing it directly. - - If the first child of 'this' is a TiXmlText, the GetText() - returns the character string of the Text node, else null is returned. - - This is a convenient method for getting the text of simple contained text: - @verbatim - This is text - const char* str = fooElement->GetText(); - @endverbatim - - 'str' will be a pointer to "This is text". - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - This is text - @endverbatim - - then the value of str would be null. The first child node isn't a text node, it is - another element. From this XML: - @verbatim - This is text - @endverbatim - GetText() will return "This is ". - */ - const char* GetText() const; - - /** - Convenience method to query the value of a child text node. This is probably best - shown by example. Given you have a document is this form: - @verbatim - - 1 - 1.4 - - @endverbatim - - The QueryIntText() and similar functions provide a safe and easier way to get to the - "value" of x and y. - - @verbatim - int x = 0; - float y = 0; // types of x and y are contrived for example - const XMLElement* xElement = pointElement->FirstChildElement( "x" ); - const XMLElement* yElement = pointElement->FirstChildElement( "y" ); - xElement->QueryIntText( &x ); - yElement->QueryFloatText( &y ); - @endverbatim - - @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted - to the requested type, and XML_NO_TEXT_NODE if there is no child text to query. - - */ - XMLError QueryIntText( int* ival ) const; - /// See QueryIntText() - XMLError QueryUnsignedText( unsigned* uval ) const; - /// See QueryIntText() - XMLError QueryBoolText( bool* bval ) const; - /// See QueryIntText() - XMLError QueryDoubleText( double* dval ) const; - /// See QueryIntText() - XMLError QueryFloatText( float* fval ) const; - - // internal: - enum { - OPEN, // - CLOSED, // - CLOSING // - }; - int ClosingType() const { - return _closingType; - } - char* ParseDeep( char* p, StrPair* endTag ); - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -private: - XMLElement( XMLDocument* doc ); - virtual ~XMLElement(); - XMLElement( const XMLElement& ); // not supported - void operator=( const XMLElement& ); // not supported - - XMLAttribute* FindAttribute( const char* name ); - XMLAttribute* FindOrCreateAttribute( const char* name ); - //void LinkAttribute( XMLAttribute* attrib ); - char* ParseAttributes( char* p ); - - int _closingType; - // The attribute list is ordered; there is no 'lastAttribute' - // because the list needs to be scanned for dupes before adding - // a new attribute. - XMLAttribute* _rootAttribute; -}; - - -enum Whitespace { - PRESERVE_WHITESPACE, - COLLAPSE_WHITESPACE -}; - - -/** A Document binds together all the functionality. - It can be saved, loaded, and printed to the screen. - All Nodes are connected and allocated to a Document. - If the Document is deleted, all its Nodes are also deleted. -*/ -class XMLDocument : public XMLNode -{ - friend class XMLElement; -public: - /// constructor - XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE ); - ~XMLDocument(); - - virtual XMLDocument* ToDocument() { - return this; - } - virtual const XMLDocument* ToDocument() const { - return this; - } - - /** - Parse an XML file from a character string. - Returns XML_NO_ERROR (0) on success, or - an errorID. - - You may optionally pass in the 'nBytes', which is - the number of bytes which will be parsed. If not - specified, TinyXML will assume 'xml' points to a - null terminated string. - */ - XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) ); - - /** - Load an XML file from disk. - Returns XML_NO_ERROR (0) on success, or - an errorID. - */ - XMLError LoadFile( const char* filename ); - - /** - Load an XML file from disk. You are responsible - for providing and closing the FILE*. - - Returns XML_NO_ERROR (0) on success, or - an errorID. - */ - XMLError LoadFile( FILE* ); - - /** - Save the XML file to disk. - Returns XML_NO_ERROR (0) on success, or - an errorID. - */ - XMLError SaveFile( const char* filename, bool compact = false ); - - /** - Save the XML file to disk. You are responsible - for providing and closing the FILE*. - - Returns XML_NO_ERROR (0) on success, or - an errorID. - */ - XMLError SaveFile( FILE* fp, bool compact = false ); - - bool ProcessEntities() const { - return _processEntities; - } - Whitespace WhitespaceMode() const { - return _whitespace; - } - - /** - Returns true if this document has a leading Byte Order Mark of UTF8. - */ - bool HasBOM() const { - return _writeBOM; - } - /** Sets whether to write the BOM when writing the file. - */ - void SetBOM( bool useBOM ) { - _writeBOM = useBOM; - } - - /** Return the root element of DOM. Equivalent to FirstChildElement(). - To get the first node, use FirstChild(). - */ - XMLElement* RootElement() { - return FirstChildElement(); - } - const XMLElement* RootElement() const { - return FirstChildElement(); - } - - /** Print the Document. If the Printer is not provided, it will - print to stdout. If you provide Printer, this can print to a file: - @verbatim - XMLPrinter printer( fp ); - doc.Print( &printer ); - @endverbatim - - Or you can use a printer to print to memory: - @verbatim - XMLPrinter printer; - doc->Print( &printer ); - // printer.CStr() has a const char* to the XML - @endverbatim - */ - void Print( XMLPrinter* streamer=0 ); - virtual bool Accept( XMLVisitor* visitor ) const; - - /** - Create a new Element associated with - this Document. The memory for the Element - is managed by the Document. - */ - XMLElement* NewElement( const char* name ); - /** - Create a new Comment associated with - this Document. The memory for the Comment - is managed by the Document. - */ - XMLComment* NewComment( const char* comment ); - /** - Create a new Text associated with - this Document. The memory for the Text - is managed by the Document. - */ - XMLText* NewText( const char* text ); - /** - Create a new Declaration associated with - this Document. The memory for the object - is managed by the Document. - - If the 'text' param is null, the standard - declaration is used.: - @verbatim - - @endverbatim - */ - XMLDeclaration* NewDeclaration( const char* text=0 ); - /** - Create a new Unknown associated with - this Document. The memory forthe object - is managed by the Document. - */ - XMLUnknown* NewUnknown( const char* text ); - - /** - Delete a node associated with this document. - It will be unlinked from the DOM. - */ - void DeleteNode( XMLNode* node ) { - node->_parent->DeleteChild( node ); - } - - void SetError( XMLError error, const char* str1, const char* str2 ); - - /// Return true if there was an error parsing the document. - bool Error() const { - return _errorID != XML_NO_ERROR; - } - /// Return the errorID. - XMLError ErrorID() const { - return _errorID; - } - /// Return a possibly helpful diagnostic location or string. - const char* GetErrorStr1() const { - return _errorStr1; - } - /// Return a possibly helpful secondary diagnostic location or string. - const char* GetErrorStr2() const { - return _errorStr2; - } - /// If there is an error, print it to stdout. - void PrintError() const; - - /// Clear the document, resetting it to the initial state. - void Clear(); - - // internal - char* Identify( char* p, XMLNode** node ); - - virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const { - return 0; - } - virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const { - return false; - } - -private: - XMLDocument( const XMLDocument& ); // not supported - void operator=( const XMLDocument& ); // not supported - - bool _writeBOM; - bool _processEntities; - XMLError _errorID; - Whitespace _whitespace; - const char* _errorStr1; - const char* _errorStr2; - char* _charBuffer; - - MemPoolT< sizeof(XMLElement) > _elementPool; - MemPoolT< sizeof(XMLAttribute) > _attributePool; - MemPoolT< sizeof(XMLText) > _textPool; - MemPoolT< sizeof(XMLComment) > _commentPool; -}; - - -/** - A XMLHandle is a class that wraps a node pointer with null checks; this is - an incredibly useful thing. Note that XMLHandle is not part of the TinyXML - DOM structure. It is a separate utility class. - - Take an example: - @verbatim - - - - - - - @endverbatim - - Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very - easy to write a *lot* of code that looks like: - - @verbatim - XMLElement* root = document.FirstChildElement( "Document" ); - if ( root ) - { - XMLElement* element = root->FirstChildElement( "Element" ); - if ( element ) - { - XMLElement* child = element->FirstChildElement( "Child" ); - if ( child ) - { - XMLElement* child2 = child->NextSiblingElement( "Child" ); - if ( child2 ) - { - // Finally do something useful. - @endverbatim - - And that doesn't even cover "else" cases. XMLHandle addresses the verbosity - of such code. A XMLHandle checks for null pointers so it is perfectly safe - and correct to use: - - @verbatim - XMLHandle docHandle( &document ); - XMLElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild().NextSibling().ToElement(); - if ( child2 ) - { - // do something useful - @endverbatim - - Which is MUCH more concise and useful. - - It is also safe to copy handles - internally they are nothing more than node pointers. - @verbatim - XMLHandle handleCopy = handle; - @endverbatim - - See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects. -*/ -class XMLHandle -{ -public: - /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - XMLHandle( XMLNode* node ) { - _node = node; - } - /// Create a handle from a node. - XMLHandle( XMLNode& node ) { - _node = &node; - } - /// Copy constructor - XMLHandle( const XMLHandle& ref ) { - _node = ref._node; - } - /// Assignment - XMLHandle& operator=( const XMLHandle& ref ) { - _node = ref._node; - return *this; - } - - /// Get the first child of this handle. - XMLHandle FirstChild() { - return XMLHandle( _node ? _node->FirstChild() : 0 ); - } - /// Get the first child element of this handle. - XMLHandle FirstChildElement( const char* value=0 ) { - return XMLHandle( _node ? _node->FirstChildElement( value ) : 0 ); - } - /// Get the last child of this handle. - XMLHandle LastChild() { - return XMLHandle( _node ? _node->LastChild() : 0 ); - } - /// Get the last child element of this handle. - XMLHandle LastChildElement( const char* _value=0 ) { - return XMLHandle( _node ? _node->LastChildElement( _value ) : 0 ); - } - /// Get the previous sibling of this handle. - XMLHandle PreviousSibling() { - return XMLHandle( _node ? _node->PreviousSibling() : 0 ); - } - /// Get the previous sibling element of this handle. - XMLHandle PreviousSiblingElement( const char* _value=0 ) { - return XMLHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 ); - } - /// Get the next sibling of this handle. - XMLHandle NextSibling() { - return XMLHandle( _node ? _node->NextSibling() : 0 ); - } - /// Get the next sibling element of this handle. - XMLHandle NextSiblingElement( const char* _value=0 ) { - return XMLHandle( _node ? _node->NextSiblingElement( _value ) : 0 ); - } - - /// Safe cast to XMLNode. This can return null. - XMLNode* ToNode() { - return _node; - } - /// Safe cast to XMLElement. This can return null. - XMLElement* ToElement() { - return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 ); - } - /// Safe cast to XMLText. This can return null. - XMLText* ToText() { - return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 ); - } - /// Safe cast to XMLUnknown. This can return null. - XMLUnknown* ToUnknown() { - return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 ); - } - /// Safe cast to XMLDeclaration. This can return null. - XMLDeclaration* ToDeclaration() { - return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 ); - } - -private: - XMLNode* _node; -}; - - -/** - A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the - same in all regards, except for the 'const' qualifiers. See XMLHandle for API. -*/ -class XMLConstHandle -{ -public: - XMLConstHandle( const XMLNode* node ) { - _node = node; - } - XMLConstHandle( const XMLNode& node ) { - _node = &node; - } - XMLConstHandle( const XMLConstHandle& ref ) { - _node = ref._node; - } - - XMLConstHandle& operator=( const XMLConstHandle& ref ) { - _node = ref._node; - return *this; - } - - const XMLConstHandle FirstChild() const { - return XMLConstHandle( _node ? _node->FirstChild() : 0 ); - } - const XMLConstHandle FirstChildElement( const char* value=0 ) const { - return XMLConstHandle( _node ? _node->FirstChildElement( value ) : 0 ); - } - const XMLConstHandle LastChild() const { - return XMLConstHandle( _node ? _node->LastChild() : 0 ); - } - const XMLConstHandle LastChildElement( const char* _value=0 ) const { - return XMLConstHandle( _node ? _node->LastChildElement( _value ) : 0 ); - } - const XMLConstHandle PreviousSibling() const { - return XMLConstHandle( _node ? _node->PreviousSibling() : 0 ); - } - const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const { - return XMLConstHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 ); - } - const XMLConstHandle NextSibling() const { - return XMLConstHandle( _node ? _node->NextSibling() : 0 ); - } - const XMLConstHandle NextSiblingElement( const char* _value=0 ) const { - return XMLConstHandle( _node ? _node->NextSiblingElement( _value ) : 0 ); - } - - - const XMLNode* ToNode() const { - return _node; - } - const XMLElement* ToElement() const { - return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 ); - } - const XMLText* ToText() const { - return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 ); - } - const XMLUnknown* ToUnknown() const { - return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 ); - } - const XMLDeclaration* ToDeclaration() const { - return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 ); - } - -private: - const XMLNode* _node; -}; - - -/** - Printing functionality. The XMLPrinter gives you more - options than the XMLDocument::Print() method. - - It can: - -# Print to memory. - -# Print to a file you provide. - -# Print XML without a XMLDocument. - - Print to Memory - - @verbatim - XMLPrinter printer; - doc->Print( &printer ); - SomeFunction( printer.CStr() ); - @endverbatim - - Print to a File - - You provide the file pointer. - @verbatim - XMLPrinter printer( fp ); - doc.Print( &printer ); - @endverbatim - - Print without a XMLDocument - - When loading, an XML parser is very useful. However, sometimes - when saving, it just gets in the way. The code is often set up - for streaming, and constructing the DOM is just overhead. - - The Printer supports the streaming case. The following code - prints out a trivially simple XML file without ever creating - an XML document. - - @verbatim - XMLPrinter printer( fp ); - printer.OpenElement( "foo" ); - printer.PushAttribute( "foo", "bar" ); - printer.CloseElement(); - @endverbatim -*/ -class XMLPrinter : public XMLVisitor -{ -public: - /** Construct the printer. If the FILE* is specified, - this will print to the FILE. Else it will print - to memory, and the result is available in CStr(). - If 'compact' is set to true, then output is created - with only required whitespace and newlines. - */ - XMLPrinter( FILE* file=0, bool compact = false ); - ~XMLPrinter() {} - - /** If streaming, write the BOM and declaration. */ - void PushHeader( bool writeBOM, bool writeDeclaration ); - /** If streaming, start writing an element. - The element must be closed with CloseElement() - */ - void OpenElement( const char* name ); - /// If streaming, add an attribute to an open element. - void PushAttribute( const char* name, const char* value ); - void PushAttribute( const char* name, int value ); - void PushAttribute( const char* name, unsigned value ); - void PushAttribute( const char* name, bool value ); - void PushAttribute( const char* name, double value ); - /// If streaming, close the Element. - void CloseElement(); - - /// Add a text node. - void PushText( const char* text, bool cdata=false ); - /// Add a text node from an integer. - void PushText( int value ); - /// Add a text node from an unsigned. - void PushText( unsigned value ); - /// Add a text node from a bool. - void PushText( bool value ); - /// Add a text node from a float. - void PushText( float value ); - /// Add a text node from a double. - void PushText( double value ); - - /// Add a comment - void PushComment( const char* comment ); - - void PushDeclaration( const char* value ); - void PushUnknown( const char* value ); - - virtual bool VisitEnter( const XMLDocument& /*doc*/ ); - virtual bool VisitExit( const XMLDocument& /*doc*/ ) { - return true; - } - - virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ); - virtual bool VisitExit( const XMLElement& element ); - - virtual bool Visit( const XMLText& text ); - virtual bool Visit( const XMLComment& comment ); - virtual bool Visit( const XMLDeclaration& declaration ); - virtual bool Visit( const XMLUnknown& unknown ); - - /** - If in print to memory mode, return a pointer to - the XML file in memory. - */ - const char* CStr() const { - return _buffer.Mem(); - } - /** - If in print to memory mode, return the size - of the XML file in memory. (Note the size returned - includes the terminating null.) - */ - int CStrSize() const { - return _buffer.Size(); - } - -private: - void SealElement(); - void PrintSpace( int depth ); - void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities. - void Print( const char* format, ... ); - - bool _elementJustOpened; - bool _firstElement; - FILE* _fp; - int _depth; - int _textDepth; - bool _processEntities; - bool _compactMode; - - enum { - ENTITY_RANGE = 64, - BUF_SIZE = 200 - }; - bool _entityFlag[ENTITY_RANGE]; - bool _restrictedEntityFlag[ENTITY_RANGE]; - - DynArray< const char*, 10 > _stack; - DynArray< char, 20 > _buffer; -#ifdef _MSC_VER - DynArray< char, 20 > _accumulator; -#endif -}; - - -} // tinyxml2 - - -#endif // TINYXML2_INCLUDED diff --git a/BasiliskII/src/Unix/user_strings_unix.cpp b/BasiliskII/src/Unix/user_strings_unix.cpp index f095e06c..5c86a02f 100644 --- a/BasiliskII/src/Unix/user_strings_unix.cpp +++ b/BasiliskII/src/Unix/user_strings_unix.cpp @@ -59,14 +59,6 @@ user_string_def platform_strings[] = { {STR_KEYCODE_FILE_WARN, "Cannot open keycode translation file %s (%s)."}, {STR_KEYCODE_VENDOR_WARN, "Cannot find vendor '%s' in keycode translation file %s."}, - {STR_PREFS_MENU_FILE_GTK, "/_File"}, - {STR_PREFS_ITEM_START_GTK, "/File/_Start Basilisk II"}, - {STR_PREFS_ITEM_ZAP_PRAM_GTK, "/File/_Zap PRAM File"}, - {STR_PREFS_ITEM_SEPL_GTK, "/File/sepl"}, - {STR_PREFS_ITEM_QUIT_GTK, "/File/_Quit Basilisk II"}, - {STR_HELP_MENU_GTK, "/_Help"}, - {STR_HELP_ITEM_ABOUT_GTK, "/Help/_About Basilisk II"}, - {STR_FBDEV_NAME_CTRL, "Frame Buffer Name"}, {STR_FBDEVICE_FILE_CTRL, "Frame Buffer Spec File"}, {STR_DSPDEVICE_FILE_CTRL, "Audio Output Device"}, diff --git a/BasiliskII/src/Unix/user_strings_unix.h b/BasiliskII/src/Unix/user_strings_unix.h index 9bdb9f62..0c26dc2a 100644 --- a/BasiliskII/src/Unix/user_strings_unix.h +++ b/BasiliskII/src/Unix/user_strings_unix.h @@ -50,14 +50,6 @@ enum { STR_KEYCODE_FILE_WARN, STR_KEYCODE_VENDOR_WARN, - STR_PREFS_MENU_FILE_GTK, - STR_PREFS_ITEM_START_GTK, - STR_PREFS_ITEM_ZAP_PRAM_GTK, - STR_PREFS_ITEM_SEPL_GTK, - STR_PREFS_ITEM_QUIT_GTK, - STR_HELP_MENU_GTK, - STR_HELP_ITEM_ABOUT_GTK, - STR_FBDEV_NAME_CTRL, STR_FBDEVICE_FILE_CTRL, STR_DSPDEVICE_FILE_CTRL, diff --git a/BasiliskII/src/Unix/vhd_unix.cpp b/BasiliskII/src/Unix/vhd_unix.cpp deleted file mode 100644 index 45f04e85..00000000 --- a/BasiliskII/src/Unix/vhd_unix.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * vhd_unix.cpp -- support for disk images in vhd format - * - * (C) 2010 Geoffrey Brown - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "disk_unix.h" -#include -#include -#include -#include -extern "C" { -#include -} -// libvhd.h defines DEBUG -#undef DEBUG -#define DEBUG 0 -#include "debug.h" - -static disk_generic::status vhd_unix_open(const char *name, int *size, - bool read_only, vhd_context_t **ctx) -{ - int amode = read_only ? R_OK : (R_OK | W_OK); - int fid; - vhd_context_t *vhd; - - D(bug("vhd open %s\n", name)); - - if (access(name, amode)) { - D(bug("vhd open -- incorrect permissions %s\n", name)); - return disk_generic::DISK_UNKNOWN; - } - - if (! (fid = open(name, O_RDONLY))) { - D(bug("vhd open -- couldn't open file %s\n", name)); - return disk_generic::DISK_UNKNOWN; - } - else { - char buf[9]; - read(fid, buf, sizeof(buf)-1); - buf[8] = 0; - close(fid); - if (strcmp("conectix", buf) != 0) { - D(bug("vhd open -- not vhd magic = %s\n", buf)); - return disk_generic::DISK_UNKNOWN; - } - if (vhd = (vhd_context_t *) malloc(sizeof(vhd_context_t))) { - int err; - if (err = vhd_open(vhd, name, read_only ? - VHD_OPEN_RDONLY : VHD_OPEN_RDWR)) { - D(bug("vhd_open failed (%d)\n", err)); - free(vhd); - return disk_generic::DISK_INVALID; - } - else { - *size = (int) vhd->footer.curr_size; - printf("VHD Open %s\n", name); - *ctx = vhd; - return disk_generic::DISK_VALID; - } - } - else { - D(bug("vhd open -- malloc failed\n")); - return disk_generic::DISK_INVALID; - } - } -} - -static int vhd_unix_read(vhd_context_t *ctx, void *buffer, loff_t offset, - size_t length) -{ - int err; - if ((offset % VHD_SECTOR_SIZE) || (length % VHD_SECTOR_SIZE)) { - printf("vhd read only supported on sector boundaries (%d)\n", - VHD_SECTOR_SIZE); - return 0; - } - if (err = vhd_io_read(ctx, (char *) buffer, offset / VHD_SECTOR_SIZE, - length / VHD_SECTOR_SIZE)){ - D(bug("vhd read error %d\n", err)); - return err; - } - else - return length; -} - -static int vhd_unix_write(vhd_context_t *ctx, void *buffer, loff_t offset, - size_t length) -{ - int err; - - if ((offset % VHD_SECTOR_SIZE) || (length % VHD_SECTOR_SIZE)) { - printf("vhd write only supported on sector boundaries (%d)\n", - VHD_SECTOR_SIZE); - return 0; - } - if (err = vhd_io_write(ctx, (char *) buffer, offset/VHD_SECTOR_SIZE, - length/VHD_SECTOR_SIZE)) { - D(bug("vhd write error %d\n", err)); - return err; - } - else - return length; -} - - -static void vhd_unix_close(vhd_context_t *ctx) -{ - D(bug("vhd close\n")); - vhd_close(ctx); - free(ctx); -} - - -struct disk_vhd : disk_generic { - disk_vhd(vhd_context_t *ctx, bool read_only, loff_t size) - : ctx(ctx), read_only(read_only), file_size(size) { } - - virtual ~disk_vhd() { vhd_unix_close(ctx); } - virtual bool is_read_only() { return read_only; } - virtual loff_t size() { return file_size; } - - virtual size_t read(void *buf, loff_t offset, size_t length) { - return vhd_unix_read(ctx, buf, offset, length); - } - - virtual size_t write(void *buf, loff_t offset, size_t length) { - return vhd_unix_write(ctx, buf, offset, length); - } - -protected: - vhd_context_t *ctx; - bool read_only; - loff_t file_size; -}; - -disk_generic::status disk_vhd_factory(const char *path, - bool read_only, disk_generic **disk) { - int size; - vhd_context_t *ctx = NULL; - disk_generic::status st = vhd_unix_open(path, &size, read_only, &ctx); - if (st == disk_generic::DISK_VALID) - *disk = new disk_vhd(ctx, read_only, size); - return st; -} diff --git a/BasiliskII/src/Unix/video_x.cpp b/BasiliskII/src/Unix/video_x.cpp deleted file mode 100644 index 6f8ef67f..00000000 --- a/BasiliskII/src/Unix/video_x.cpp +++ /dev/null @@ -1,2686 +0,0 @@ -/* - * video_x.cpp - Video/graphics emulation, X11 specific stuff - * - * Basilisk II (C) Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * NOTES: - * The Ctrl key works like a qualifier for special actions: - * Ctrl-Tab = suspend DGA mode - * Ctrl-Esc = emergency quit - * Ctrl-F1 = mount floppy - * Ctrl-F5 = grab mouse (in windowed mode) - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_PTHREADS -# include -#endif - -#ifdef ENABLE_XF86_DGA -# include -#endif - -#ifdef ENABLE_XF86_VIDMODE -# include -#endif - -#ifdef ENABLE_FBDEV_DGA -# include -#endif - -#include "cpu_emulation.h" -#include "main.h" -#include "adb.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "video.h" -#include "video_blit.h" - -#define DEBUG 0 -#include "debug.h" - - -// Supported video modes -static vector VideoModes; - -// Display types -enum { - DISPLAY_WINDOW, // X11 window, using MIT SHM extensions if possible - DISPLAY_DGA // DGA fullscreen display -}; - -// Constants -const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes"; - -static const int win_eventmask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | ExposureMask | StructureNotifyMask; -static const int dga_eventmask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask; - - -// Global variables -static int32 frame_skip; // Prefs items -static int16 mouse_wheel_mode; -static int16 mouse_wheel_lines; - -static int display_type = DISPLAY_WINDOW; // See enum above -static bool local_X11; // Flag: X server running on local machine? -static uint8 *the_buffer = NULL; // Mac frame buffer (where MacOS draws into) -static uint8 *the_buffer_copy = NULL; // Copy of Mac frame buffer (for refreshed modes) -static uint32 the_buffer_size; // Size of allocated the_buffer - -static bool redraw_thread_active = false; // Flag: Redraw thread installed -#ifdef HAVE_PTHREADS -static pthread_attr_t redraw_thread_attr; // Redraw thread attributes -static volatile bool redraw_thread_cancel; // Flag: Cancel Redraw thread -static volatile bool redraw_thread_cancel_ack; // Flag: Acknowledge for redraw thread cancellation -static pthread_t redraw_thread; // Redraw thread -#endif - -static bool has_dga = false; // Flag: Video DGA capable -static bool has_vidmode = false; // Flag: VidMode extension available - -#ifdef ENABLE_VOSF -static bool use_vosf = true; // Flag: VOSF enabled -#else -static const bool use_vosf = false; // VOSF not possible -#endif - -static bool ctrl_down = false; // Flag: Ctrl key pressed -static bool caps_on = false; // Flag: Caps Lock on -static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread -static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread -static bool emul_suspended = false; // Flag: Emulator suspended - -static bool classic_mode = false; // Flag: Classic Mac video mode - -static bool use_keycodes = false; // Flag: Use keycodes rather than keysyms -static int keycode_table[256]; // X keycode -> Mac keycode translation table - -// X11 variables -char *x_display_name = NULL; // X11 display name -Display *x_display = NULL; // X11 display handle -static int screen; // Screen number -static Window rootwin; // Root window and our window -static int num_depths = 0; // Number of available X depths -static int *avail_depths = NULL; // List of available X depths -static XColor black, white; -static unsigned long black_pixel, white_pixel; -static int eventmask; - -static int xdepth; // Depth of X screen -static VisualFormat visualFormat; -static XVisualInfo visualInfo; -static Visual *vis; -static int color_class; - -static bool x_native_byte_order; // XImage has native byte order? -static int rshift, rloss, gshift, gloss, bshift, bloss; // Pixel format of DirectColor/TrueColor modes - -static Colormap cmap[2] = {0, 0}; // Colormaps for indexed modes (DGA needs two of them) - -static XColor x_palette[256]; // Color palette to be used as CLUT and gamma table -static bool x_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors - -#ifdef ENABLE_FBDEV_DGA -static int fbdev_fd = -1; -#endif - -#ifdef ENABLE_XF86_VIDMODE -static XF86VidModeModeInfo **x_video_modes = NULL; // Array of all available modes -static int num_x_video_modes; -#endif - -// Mutex to protect palette -#ifdef HAVE_PTHREADS -static pthread_mutex_t x_palette_lock = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_PALETTE pthread_mutex_lock(&x_palette_lock) -#define UNLOCK_PALETTE pthread_mutex_unlock(&x_palette_lock) -#else -#define LOCK_PALETTE -#define UNLOCK_PALETTE -#endif - -// Mutex to protect frame buffer -#ifdef HAVE_PTHREADS -static pthread_mutex_t frame_buffer_lock = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_FRAME_BUFFER pthread_mutex_lock(&frame_buffer_lock); -#define UNLOCK_FRAME_BUFFER pthread_mutex_unlock(&frame_buffer_lock); -#else -#define LOCK_FRAME_BUFFER -#define UNLOCK_FRAME_BUFFER -#endif - -// Variables for non-VOSF incremental refresh -static const int sm_uptd[] = {4,1,6,3,0,5,2,7}; -static int sm_no_boxes[] = {1,8,32,64,128,300}; -static bool updt_box[17][17]; -static int nr_boxes; - -// Video refresh function -static void VideoRefreshInit(void); -static void (*video_refresh)(void); - - -// Prototypes -static void *redraw_func(void *arg); - -// From main_unix.cpp -extern char *x_display_name; -extern Display *x_display; - -// From sys_unix.cpp -extern void SysMountFirstFloppy(void); - -// From clip_unix.cpp -extern void ClipboardSelectionClear(XSelectionClearEvent *); -extern void ClipboardSelectionRequest(XSelectionRequestEvent *); - - -/* - * monitor_desc subclass for X11 display - */ - -class X11_monitor_desc : public monitor_desc { -public: - X11_monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) : monitor_desc(available_modes, default_depth, default_id) {} - ~X11_monitor_desc() {} - - virtual void switch_to_current_mode(void); - virtual void set_palette(uint8 *pal, int num); - - bool video_open(void); - void video_close(void); -}; - - -/* - * Utility functions - */ - -// Map video_mode depth ID to numerical depth value -static inline int depth_of_video_mode(video_mode const & mode) -{ - int depth = -1; - switch (mode.depth) { - case VDEPTH_1BIT: - depth = 1; - break; - case VDEPTH_2BIT: - depth = 2; - break; - case VDEPTH_4BIT: - depth = 4; - break; - case VDEPTH_8BIT: - depth = 8; - break; - case VDEPTH_16BIT: - depth = 16; - break; - case VDEPTH_32BIT: - depth = 32; - break; - default: - abort(); - } - return depth; -} - -// Map RGB color to pixel value (this only works in TrueColor/DirectColor visuals) -static inline uint32 map_rgb(uint8 red, uint8 green, uint8 blue, bool fix_byte_order = false) -{ - uint32 val = ((red >> rloss) << rshift) | ((green >> gloss) << gshift) | ((blue >> bloss) << bshift); - if (fix_byte_order && !x_native_byte_order) { - // We have to fix byte order in the ExpandMap[] - // NOTE: this is only an optimization since Screen_blitter_init() - // could be arranged to choose an NBO or OBO (with - // byteswapping) Blit_Expand_X_To_Y() function - switch (visualFormat.depth) { - case 15: case 16: - val = do_byteswap_16(val); - break; - case 24: case 32: - val = do_byteswap_32(val); - break; - } - } - return val; -} - -// Do we have a visual for handling the specified Mac depth? If so, set the -// global variables "xdepth", "visualInfo", "vis" and "color_class". -static bool find_visual_for_depth(video_depth depth) -{ - D(bug("have_visual_for_depth(%d)\n", 1 << depth)); - - // 1-bit works always and uses default visual - if (depth == VDEPTH_1BIT) { - vis = DefaultVisual(x_display, screen); - visualInfo.visualid = XVisualIDFromVisual(vis); - int num = 0; - XVisualInfo *vi = XGetVisualInfo(x_display, VisualIDMask, &visualInfo, &num); - visualInfo = vi[0]; - XFree(vi); - xdepth = visualInfo.depth; - color_class = visualInfo.c_class; - D(bug(" found visual ID 0x%02x, depth %d\n", visualInfo.visualid, xdepth)); - return true; - } - - // Calculate minimum and maximum supported X depth - int min_depth = 1, max_depth = 32; - switch (depth) { -#ifdef ENABLE_VOSF - case VDEPTH_2BIT: - case VDEPTH_4BIT: // VOSF blitters can convert 2/4/8-bit -> 8/16/32-bit - case VDEPTH_8BIT: - min_depth = 8; - max_depth = 32; - break; -#else - case VDEPTH_2BIT: - case VDEPTH_4BIT: // 2/4-bit requires VOSF blitters - return false; - case VDEPTH_8BIT: // 8-bit without VOSF requires an 8-bit visual - min_depth = 8; - max_depth = 8; - break; -#endif - case VDEPTH_16BIT: // 16-bit requires a 15/16-bit visual - min_depth = 15; - max_depth = 16; - break; - case VDEPTH_32BIT: // 32-bit requires a 24/32-bit visual - min_depth = 24; - max_depth = 32; - break; - } - D(bug(" minimum required X depth is %d, maximum supported X depth is %d\n", min_depth, max_depth)); - - // Try to find a visual for one of the color depths - bool visual_found = false; - for (int i=0; i max_depth) - continue; - - // Determine best color class for this depth - switch (xdepth) { - case 1: // Try StaticGray or StaticColor - if (XMatchVisualInfo(x_display, screen, xdepth, StaticGray, &visualInfo) - || XMatchVisualInfo(x_display, screen, xdepth, StaticColor, &visualInfo)) - visual_found = true; - break; - case 8: // Need PseudoColor - if (XMatchVisualInfo(x_display, screen, xdepth, PseudoColor, &visualInfo)) - visual_found = true; - break; - case 15: - case 16: - case 24: - case 32: // Try DirectColor first, as this will allow gamma correction - if (XMatchVisualInfo(x_display, screen, xdepth, DirectColor, &visualInfo) - || XMatchVisualInfo(x_display, screen, xdepth, TrueColor, &visualInfo)) - visual_found = true; - break; - default: - D(bug(" not a supported depth\n")); - break; - } - } - if (!visual_found) - return false; - - // Visual was found - vis = visualInfo.visual; - color_class = visualInfo.c_class; - D(bug(" found visual ID 0x%02x, depth %d, class ", visualInfo.visualid, xdepth)); -#if DEBUG - switch (color_class) { - case StaticGray: D(bug("StaticGray\n")); break; - case GrayScale: D(bug("GrayScale\n")); break; - case StaticColor: D(bug("StaticColor\n")); break; - case PseudoColor: D(bug("PseudoColor\n")); break; - case TrueColor: D(bug("TrueColor\n")); break; - case DirectColor: D(bug("DirectColor\n")); break; - } -#endif - return true; -} - -// Add mode to list of supported modes -static void add_mode(uint32 width, uint32 height, uint32 resolution_id, uint32 bytes_per_row, video_depth depth) -{ - video_mode mode; - mode.x = width; - mode.y = height; - mode.resolution_id = resolution_id; - mode.bytes_per_row = bytes_per_row; - mode.depth = depth; - mode.user_data = 0; - VideoModes.push_back(mode); -} - -// Add standard list of windowed modes for given color depth -static void add_window_modes(video_depth depth) -{ - add_mode(512, 384, 0x80, TrivialBytesPerRow(512, depth), depth); - add_mode(640, 480, 0x81, TrivialBytesPerRow(640, depth), depth); - add_mode(800, 600, 0x82, TrivialBytesPerRow(800, depth), depth); - add_mode(1024, 768, 0x83, TrivialBytesPerRow(1024, depth), depth); - add_mode(1152, 870, 0x84, TrivialBytesPerRow(1152, depth), depth); - add_mode(1280, 1024, 0x85, TrivialBytesPerRow(1280, depth), depth); - add_mode(1600, 1200, 0x86, TrivialBytesPerRow(1600, depth), depth); -} - -// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) -static void set_mac_frame_buffer(X11_monitor_desc &monitor, video_depth depth, bool native_byte_order) -{ -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING - int layout = FLAYOUT_DIRECT; - if (depth == VDEPTH_16BIT) - layout = (xdepth == 15) ? FLAYOUT_HOST_555 : FLAYOUT_HOST_565; - else if (depth == VDEPTH_32BIT) - layout = (xdepth == 24) ? FLAYOUT_HOST_888 : FLAYOUT_DIRECT; - if (native_byte_order) - MacFrameLayout = layout; - else - MacFrameLayout = FLAYOUT_DIRECT; - monitor.set_mac_frame_base(MacFrameBaseMac); - - // Set variables used by UAE memory banking - const video_mode &mode = monitor.get_current_mode(); - MacFrameBaseHost = the_buffer; - MacFrameSize = mode.bytes_per_row * mode.y; - InitFrameBufferMapping(); -#else - monitor.set_mac_frame_base(Host2MacAddr(the_buffer)); -#endif - D(bug("monitor.mac_frame_base = %08x\n", monitor.get_mac_frame_base())); -} - -// Set window name and class -static void set_window_name(Window w, int name) -{ - const char *str = GetString(name); - XStoreName(x_display, w, str); - XSetIconName(x_display, w, str); - - XClassHint *hints; - hints = XAllocClassHint(); - if (hints) { - hints->res_name = "BasiliskII"; - hints->res_class = "BasiliskII"; - XSetClassHint(x_display, w, hints); - XFree(hints); - } -} - -// Set window input focus flag -static void set_window_focus(Window w) -{ - XWMHints *hints = XAllocWMHints(); - if (hints) { - hints->input = True; - hints->initial_state = NormalState; - hints->flags = InputHint | StateHint; - XSetWMHints(x_display, w, hints); - XFree(hints); - } -} - -// Set WM_DELETE_WINDOW protocol on window (preventing it from being destroyed by the WM when clicking on the "close" widget) -static Atom WM_DELETE_WINDOW = (Atom)0; -static void set_window_delete_protocol(Window w) -{ - WM_DELETE_WINDOW = XInternAtom(x_display, "WM_DELETE_WINDOW", false); - XSetWMProtocols(x_display, w, &WM_DELETE_WINDOW, 1); -} - -// Wait until window is mapped/unmapped -void wait_mapped(Window w) -{ - XEvent e; - do { - XMaskEvent(x_display, StructureNotifyMask, &e); - } while ((e.type != MapNotify) || (e.xmap.event != w)); -} - -void wait_unmapped(Window w) -{ - XEvent e; - do { - XMaskEvent(x_display, StructureNotifyMask, &e); - } while ((e.type != UnmapNotify) || (e.xmap.event != w)); -} - -// Trap SHM errors -static bool shm_error = false; -static int (*old_error_handler)(Display *, XErrorEvent *); - -static int error_handler(Display *d, XErrorEvent *e) -{ - if (e->error_code == BadAccess) { - shm_error = true; - return 0; - } else - return old_error_handler(d, e); -} - - -/* - * Framebuffer allocation routines - */ - -#ifdef ENABLE_VOSF -#include "vm_alloc.h" - -static void *vm_acquire_framebuffer(uint32 size) -{ - // always try to allocate framebuffer at the same address - static void *fb = VM_MAP_FAILED; - if (fb != VM_MAP_FAILED) { - if (vm_acquire_fixed(fb, size) < 0) - fb = VM_MAP_FAILED; - } - if (fb == VM_MAP_FAILED) - fb = vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); - return fb; -} - -static inline void vm_release_framebuffer(void *fb, uint32 size) -{ - vm_release(fb, size); -} -#endif - - -/* - * Display "driver" classes - */ - -class driver_base { -public: - driver_base(X11_monitor_desc &m); - virtual ~driver_base(); - - virtual void update_palette(void); - virtual void suspend(void) {} - virtual void resume(void) {} - virtual void toggle_mouse_grab(void) {} - virtual void mouse_moved(int x, int y) { ADBMouseMoved(x, y); } - - void disable_mouse_accel(void); - void restore_mouse_accel(void); - - virtual void grab_mouse(void) {} - virtual void ungrab_mouse(void) {} - -public: - X11_monitor_desc &monitor; // Associated video monitor - const video_mode &mode; // Video mode handled by the driver - - bool init_ok; // Initialization succeeded (we can't use exceptions because of -fomit-frame-pointer) - Window w; // The window we draw into - - int orig_accel_numer, orig_accel_denom, orig_threshold; // Original mouse acceleration -}; - -class driver_window; -static void update_display_window_vosf(driver_window *drv); -static void update_display_dynamic(int ticker, driver_window *drv); -static void update_display_static(driver_window *drv); - -class driver_window : public driver_base { - friend void update_display_window_vosf(driver_window *drv); - friend void update_display_dynamic(int ticker, driver_window *drv); - friend void update_display_static(driver_window *drv); - -public: - driver_window(X11_monitor_desc &monitor); - ~driver_window(); - - void toggle_mouse_grab(void); - void mouse_moved(int x, int y); - - void grab_mouse(void); - void ungrab_mouse(void); - -private: - GC gc; - XImage *img; - bool have_shm; // Flag: SHM extensions available - XShmSegmentInfo shminfo; - Cursor mac_cursor; - bool mouse_grabbed; // Flag: mouse pointer grabbed, using relative mouse mode - int mouse_last_x, mouse_last_y; // Last mouse position (for relative mode) -}; - -class driver_dga; -static void update_display_dga_vosf(driver_dga *drv); - -class driver_dga : public driver_base { - friend void update_display_dga_vosf(driver_dga *drv); - -public: - driver_dga(X11_monitor_desc &monitor); - ~driver_dga(); - - void suspend(void); - void resume(void); - -protected: - struct FakeXImage { - int width, height; // size of image - int depth; // depth of image - int bytes_per_line; // accelerator to next line - - FakeXImage(int w, int h, int d) - : width(w), height(h), depth(d) - { bytes_per_line = TrivialBytesPerRow(width, DepthModeForPixelDepth(depth)); } - }; - FakeXImage *img; - -private: - Window suspend_win; // "Suspend" information window - void *fb_save; // Saved frame buffer for suspend/resume -}; - -static driver_base *drv = NULL; // Pointer to currently used driver object - -#ifdef ENABLE_VOSF -# include "video_vosf.h" -#endif - -driver_base::driver_base(X11_monitor_desc &m) - : monitor(m), mode(m.get_current_mode()), init_ok(false), w(0) -{ - the_buffer = NULL; - the_buffer_copy = NULL; - XGetPointerControl(x_display, &orig_accel_numer, &orig_accel_denom, &orig_threshold); -} - -driver_base::~driver_base() -{ - ungrab_mouse(); - restore_mouse_accel(); - - if (w) { - XUnmapWindow(x_display, w); - wait_unmapped(w); - XDestroyWindow(x_display, w); - } - - XFlush(x_display); - XSync(x_display, false); - - // Free frame buffer(s) - if (!use_vosf) { - if (the_buffer) { - free(the_buffer); - the_buffer = NULL; - } - if (the_buffer_copy) { - free(the_buffer_copy); - the_buffer_copy = NULL; - } - } -#ifdef ENABLE_VOSF - else { - // the_buffer shall always be mapped through vm_acquire() so that we can vm_protect() it at will - if (the_buffer != VM_MAP_FAILED) { - D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size)); - vm_release_framebuffer(the_buffer, the_buffer_size); - the_buffer = NULL; - } - if (the_host_buffer) { - D(bug(" freeing the_host_buffer at %p\n", the_host_buffer)); - free(the_host_buffer); - the_host_buffer = NULL; - } - if (the_buffer_copy) { - D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy)); - free(the_buffer_copy); - the_buffer_copy = NULL; - } - } -#endif -} - -// Palette has changed -void driver_base::update_palette(void) -{ - if (color_class == PseudoColor || color_class == DirectColor) { - int num = vis->map_entries; - if (!IsDirectMode(monitor.get_current_mode()) && color_class == DirectColor) - return; // Indexed mode on true color screen, don't set CLUT - XStoreColors(x_display, cmap[0], x_palette, num); - XStoreColors(x_display, cmap[1], x_palette, num); - } - XSync(x_display, false); -} - -// Disable mouse acceleration -void driver_base::disable_mouse_accel(void) -{ - XChangePointerControl(x_display, True, False, 1, 1, 0); -} - -// Restore mouse acceleration to original value -void driver_base::restore_mouse_accel(void) -{ - XChangePointerControl(x_display, True, True, orig_accel_numer, orig_accel_denom, orig_threshold); -} - - -/* - * Windowed display driver - */ - -// Open display -driver_window::driver_window(X11_monitor_desc &m) - : driver_base(m), gc(0), img(NULL), have_shm(false), mac_cursor(0), - mouse_grabbed(false), mouse_last_x(0), mouse_last_y(0) -{ - int width = mode.x, height = mode.y; - int aligned_width = (width + 15) & ~15; - int aligned_height = (height + 15) & ~15; - - // Set absolute mouse mode - ADBSetRelMouseMode(mouse_grabbed); - - // Create window (setting background_pixel, border_pixel and colormap is - // mandatory when using a non-default visual; in 1-bit mode we use the - // default visual, so we can also use the default colormap) - XSetWindowAttributes wattr; - wattr.event_mask = eventmask = win_eventmask; - wattr.background_pixel = (vis == DefaultVisual(x_display, screen) ? black_pixel : 0); - wattr.border_pixel = 0; - wattr.colormap = (mode.depth == VDEPTH_1BIT ? DefaultColormap(x_display, screen) : cmap[0]); - w = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth, - InputOutput, vis, CWEventMask | CWBackPixel | CWBorderPixel | CWColormap, &wattr); - D(bug(" window created\n")); - - // Set window name/class - set_window_name(w, STR_WINDOW_TITLE); - - // Indicate that we want keyboard input - set_window_focus(w); - - // Set delete protocol property - set_window_delete_protocol(w); - - // Make window unresizable - { - XSizeHints *hints = XAllocSizeHints(); - if (hints) { - hints->min_width = width; - hints->max_width = width; - hints->min_height = height; - hints->max_height = height; - hints->flags = PMinSize | PMaxSize; - XSetWMNormalHints(x_display, w, hints); - XFree(hints); - } - } - D(bug(" window attributes set\n")); - - // Show window - XMapWindow(x_display, w); - wait_mapped(w); - D(bug(" window mapped\n")); - - // 1-bit mode is big-endian; if the X server is little-endian, we can't - // use SHM because that doesn't allow changing the image byte order - bool need_msb_image = (mode.depth == VDEPTH_1BIT && XImageByteOrder(x_display) == LSBFirst); - - // Try to create and attach SHM image - if (local_X11 && !need_msb_image && XShmQueryExtension(x_display)) { - - // Create SHM image ("height + 2" for safety) - img = XShmCreateImage(x_display, vis, mode.depth == VDEPTH_1BIT ? 1 : xdepth, mode.depth == VDEPTH_1BIT ? XYBitmap : ZPixmap, 0, &shminfo, width, height); - D(bug(" shm image created\n")); - shminfo.shmid = shmget(IPC_PRIVATE, (aligned_height + 2) * img->bytes_per_line, IPC_CREAT | 0777); - the_buffer_copy = (uint8 *)shmat(shminfo.shmid, 0, 0); - shminfo.shmaddr = img->data = (char *)the_buffer_copy; - shminfo.readOnly = False; - - // Try to attach SHM image, catching errors - shm_error = false; - old_error_handler = XSetErrorHandler(error_handler); - XShmAttach(x_display, &shminfo); - XSync(x_display, false); - XSetErrorHandler(old_error_handler); - if (shm_error) { - shmdt(shminfo.shmaddr); - XDestroyImage(img); - img = NULL; - shminfo.shmid = -1; - } else { - have_shm = true; - shmctl(shminfo.shmid, IPC_RMID, 0); - } - D(bug(" shm image attached\n")); - } - - // Create normal X image if SHM doesn't work ("height + 2" for safety) - if (!have_shm) { - int bytes_per_row = (mode.depth == VDEPTH_1BIT ? aligned_width/8 : TrivialBytesPerRow(aligned_width, DepthModeForPixelDepth(xdepth))); - the_buffer_copy = (uint8 *)malloc((aligned_height + 2) * bytes_per_row); - img = XCreateImage(x_display, vis, mode.depth == VDEPTH_1BIT ? 1 : xdepth, mode.depth == VDEPTH_1BIT ? XYBitmap : ZPixmap, 0, (char *)the_buffer_copy, aligned_width, aligned_height, 32, bytes_per_row); - D(bug(" X image created\n")); - } - - if (need_msb_image) { - img->byte_order = MSBFirst; - img->bitmap_bit_order = MSBFirst; - } - -#ifdef ENABLE_VOSF - use_vosf = true; - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - the_host_buffer = the_buffer_copy; - the_buffer_size = page_extend((aligned_height + 2) * img->bytes_per_line); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); -#else - // Allocate memory for frame buffer - the_buffer = (uint8 *)malloc((aligned_height + 2) * img->bytes_per_line); - D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy)); -#endif - - // Create GC - gc = XCreateGC(x_display, w, 0, 0); - XSetState(x_display, gc, black_pixel, white_pixel, GXcopy, AllPlanes); - - // Create no_cursor - mac_cursor = XCreatePixmapCursor(x_display, - XCreatePixmap(x_display, w, 1, 1, 1), - XCreatePixmap(x_display, w, 1, 1, 1), - &black, &white, 0, 0); - XDefineCursor(x_display, w, mac_cursor); - - // Init blitting routines -#ifdef ENABLE_VOSF - Screen_blitter_init(visualFormat, x_native_byte_order, depth_of_video_mode(mode)); -#endif - - // Set frame buffer base - set_mac_frame_buffer(monitor, mode.depth, x_native_byte_order); - - // Everything went well - init_ok = true; -} - -// Close display -driver_window::~driver_window() -{ - if (have_shm) { - XShmDetach(x_display, &shminfo); -#ifdef ENABLE_VOSF - the_host_buffer = NULL; // don't free() in driver_base dtor -#else - the_buffer_copy = NULL; // don't free() in driver_base dtor -#endif - } - if (img) { - if (!have_shm) - img->data = NULL; - XDestroyImage(img); - } - if (have_shm) { - shmdt(shminfo.shmaddr); - shmctl(shminfo.shmid, IPC_RMID, 0); - } - if (gc) - XFreeGC(x_display, gc); -} - -// Toggle mouse grab -void driver_window::toggle_mouse_grab(void) -{ - if (mouse_grabbed) - ungrab_mouse(); - else - grab_mouse(); -} - -// Grab mouse, switch to relative mouse mode -void driver_window::grab_mouse(void) -{ - int result; - for (int i=0; i<10; i++) { - result = XGrabPointer(x_display, w, True, 0, - GrabModeAsync, GrabModeAsync, w, None, CurrentTime); - if (result != AlreadyGrabbed) - break; - Delay_usec(100000); - } - if (result == GrabSuccess) { - XStoreName(x_display, w, GetString(STR_WINDOW_TITLE_GRABBED)); - ADBSetRelMouseMode(mouse_grabbed = true); - disable_mouse_accel(); - } -} - -// Ungrab mouse, switch to absolute mouse mode -void driver_window::ungrab_mouse(void) -{ - if (mouse_grabbed) { - XUngrabPointer(x_display, CurrentTime); - XStoreName(x_display, w, GetString(STR_WINDOW_TITLE)); - ADBSetRelMouseMode(mouse_grabbed = false); - restore_mouse_accel(); - } -} - -// Mouse moved -void driver_window::mouse_moved(int x, int y) -{ - if (!mouse_grabbed) { - mouse_last_x = x; mouse_last_y = y; - ADBMouseMoved(x, y); - return; - } - - // Warped mouse motion (this code is taken from SDL) - - // Post first mouse event - int width = monitor.get_current_mode().x, height = monitor.get_current_mode().y; - int delta_x = x - mouse_last_x, delta_y = y - mouse_last_y; - mouse_last_x = x; mouse_last_y = y; - ADBMouseMoved(delta_x, delta_y); - - // Only warp the pointer when it has reached the edge - const int MOUSE_FUDGE_FACTOR = 8; - if (x < MOUSE_FUDGE_FACTOR || x > (width - MOUSE_FUDGE_FACTOR) - || y < MOUSE_FUDGE_FACTOR || y > (height - MOUSE_FUDGE_FACTOR)) { - XEvent event; - while (XCheckTypedEvent(x_display, MotionNotify, &event)) { - delta_x = x - mouse_last_x; delta_y = y - mouse_last_y; - mouse_last_x = x; mouse_last_y = y; - ADBMouseMoved(delta_x, delta_y); - } - mouse_last_x = width/2; - mouse_last_y = height/2; - XWarpPointer(x_display, None, w, 0, 0, 0, 0, mouse_last_x, mouse_last_y); - for (int i=0; i<10; i++) { - XMaskEvent(x_display, PointerMotionMask, &event); - if (event.xmotion.x > (mouse_last_x - MOUSE_FUDGE_FACTOR) - && event.xmotion.x < (mouse_last_x + MOUSE_FUDGE_FACTOR) - && event.xmotion.y > (mouse_last_y - MOUSE_FUDGE_FACTOR) - && event.xmotion.y < (mouse_last_y + MOUSE_FUDGE_FACTOR)) - break; - } - } -} - - -#if defined(ENABLE_XF86_DGA) || defined(ENABLE_FBDEV_DGA) -/* - * DGA display driver base class - */ - -driver_dga::driver_dga(X11_monitor_desc &m) - : driver_base(m), suspend_win(0), fb_save(NULL), img(NULL) -{ -} - -driver_dga::~driver_dga() -{ - XUngrabPointer(x_display, CurrentTime); - XUngrabKeyboard(x_display, CurrentTime); - - if (img) - delete img; -} - -// Suspend emulation -void driver_dga::suspend(void) -{ - // Release ctrl key - ADBKeyUp(0x36); - ctrl_down = false; - - // Lock frame buffer (this will stop the MacOS thread) - LOCK_FRAME_BUFFER; - - // Save frame buffer - fb_save = malloc(mode.y * mode.bytes_per_row); - if (fb_save) - memcpy(fb_save, the_buffer, mode.y * mode.bytes_per_row); - - // Close full screen display -#ifdef ENABLE_XF86_DGA - XF86DGADirectVideo(x_display, screen, 0); -#endif - XUngrabPointer(x_display, CurrentTime); - XUngrabKeyboard(x_display, CurrentTime); - restore_mouse_accel(); - XUnmapWindow(x_display, w); - wait_unmapped(w); - - // Open "suspend" window - XSetWindowAttributes wattr; - wattr.event_mask = KeyPressMask; - wattr.background_pixel = black_pixel; - - suspend_win = XCreateWindow(x_display, rootwin, 0, 0, 512, 1, 0, xdepth, - InputOutput, vis, CWEventMask | CWBackPixel, &wattr); - set_window_name(suspend_win, STR_SUSPEND_WINDOW_TITLE); - set_window_focus(suspend_win); - XMapWindow(x_display, suspend_win); - emul_suspended = true; -} - -// Resume emulation -void driver_dga::resume(void) -{ - // Close "suspend" window - XDestroyWindow(x_display, suspend_win); - XSync(x_display, false); - - // Reopen full screen display - XMapRaised(x_display, w); - wait_mapped(w); - XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0); - XGrabKeyboard(x_display, rootwin, True, GrabModeAsync, GrabModeAsync, CurrentTime); - XGrabPointer(x_display, rootwin, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - disable_mouse_accel(); -#ifdef ENABLE_XF86_DGA - XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse); - XF86DGASetViewPort(x_display, screen, 0, 0); -#endif - XSync(x_display, false); - - // the_buffer already contains the data to restore. i.e. since a temporary - // frame buffer is used when VOSF is actually used, fb_save is therefore - // not necessary. -#ifdef ENABLE_VOSF - if (use_vosf) { - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y); - } -#endif - - // Restore frame buffer - if (fb_save) { -#ifdef ENABLE_VOSF - // Don't copy fb_save to the temporary frame buffer in VOSF mode - if (!use_vosf) -#endif - memcpy(the_buffer, fb_save, mode.y * mode.bytes_per_row); - free(fb_save); - fb_save = NULL; - } - - // Unlock frame buffer (and continue MacOS thread) - UNLOCK_FRAME_BUFFER; - emul_suspended = false; -} -#endif - - -#ifdef ENABLE_FBDEV_DGA -/* - * fbdev DGA display driver - */ - -const char FBDEVICES_FILE_NAME[] = DATADIR "/fbdevices"; -const char FBDEVICE_FILE_NAME[] = "/dev/fb"; - -class driver_fbdev : public driver_dga { -public: - driver_fbdev(X11_monitor_desc &monitor); - ~driver_fbdev(); -}; - -// Open display -driver_fbdev::driver_fbdev(X11_monitor_desc &m) : driver_dga(m) -{ - int width = mode.x, height = mode.y; - - // Set absolute mouse mode - ADBSetRelMouseMode(false); - - // Find the maximum depth available - int ndepths, max_depth(0); - int *depths = XListDepths(x_display, screen, &ndepths); - if (depths == NULL) { - printf("FATAL: Could not determine the maximal depth available\n"); - return; - } else { - while (ndepths-- > 0) { - if (depths[ndepths] > max_depth) - max_depth = depths[ndepths]; - } - } - - // Get fbdevices file path from preferences - const char *fbd_path = PrefsFindString("fbdevicefile"); - - // Open fbdevices file - FILE *fp = fopen(fbd_path ? fbd_path : FBDEVICES_FILE_NAME, "r"); - if (fp == NULL) { - char str[256]; - sprintf(str, GetString(STR_NO_FBDEVICE_FILE_ERR), fbd_path ? fbd_path : FBDEVICES_FILE_NAME, strerror(errno)); - ErrorAlert(str); - return; - } - - int fb_depth; // supported depth - uint32 fb_offset; // offset used for mmap(2) - char fb_name[20]; - char line[256]; - bool device_found = false; - while (fgets(line, 255, fp)) { - // Read line - int len = strlen(line); - if (len == 0) - continue; - line[len - 1] = '\0'; - - // Comments begin with "#" or ";" - if ((line[0] == '#') || (line[0] == ';') || (line[0] == '\0')) - continue; - - if ((sscanf(line, "%19s %d %x", fb_name, &fb_depth, &fb_offset) == 3) - && (strcmp(fb_name, fb_name) == 0) && (fb_depth == max_depth)) { - device_found = true; - break; - } - } - - // fbdevices file completely read - fclose(fp); - - // Frame buffer name not found ? Then, display warning - if (!device_found) { - char str[256]; - sprintf(str, GetString(STR_FBDEV_NAME_ERR), fb_name, max_depth); - ErrorAlert(str); - return; - } - - // Create window - XSetWindowAttributes wattr; - wattr.event_mask = eventmask = dga_eventmask; - wattr.background_pixel = white_pixel; - wattr.override_redirect = True; - wattr.colormap = cmap[0]; - - w = XCreateWindow(x_display, rootwin, - 0, 0, width, height, - 0, xdepth, InputOutput, vis, - CWEventMask | CWBackPixel | CWOverrideRedirect | (fb_depth <= 8 ? CWColormap : 0), - &wattr); - - // Set window name/class - set_window_name(w, STR_WINDOW_TITLE); - - // Indicate that we want keyboard input - set_window_focus(w); - - // Show window - XMapRaised(x_display, w); - wait_mapped(w); - - // Grab mouse and keyboard - XGrabKeyboard(x_display, w, True, - GrabModeAsync, GrabModeAsync, CurrentTime); - XGrabPointer(x_display, w, True, - PointerMotionMask | ButtonPressMask | ButtonReleaseMask, - GrabModeAsync, GrabModeAsync, w, None, CurrentTime); - disable_mouse_accel(); - - // Calculate bytes per row - int bytes_per_row = TrivialBytesPerRow(mode.x, mode.depth); - - // Map frame buffer - the_buffer_size = height * bytes_per_row; - if ((the_buffer = (uint8 *) mmap(NULL, the_buffer_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fbdev_fd, fb_offset)) == MAP_FAILED) { - if ((the_buffer = (uint8 *) mmap(NULL, the_buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fbdev_fd, fb_offset)) == MAP_FAILED) { - char str[256]; - sprintf(str, GetString(STR_FBDEV_MMAP_ERR), strerror(errno)); - ErrorAlert(str); - return; - } - } - -#if ENABLE_VOSF -#if REAL_ADDRESSING || DIRECT_ADDRESSING - // Screen_blitter_init() returns TRUE if VOSF is mandatory - // i.e. the framebuffer update function is not Blit_Copy_Raw - use_vosf = Screen_blitter_init(visualFormat, true, mode.depth); - - if (use_vosf) { - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - the_host_buffer = the_buffer; - the_buffer_size = page_extend((height + 2) * bytes_per_row); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - - // Fake image for DGA/VOSF mode to know about display bounds - img = new FakeXImage(width, height, depth_of_video_mode(mode)); - } -#else - use_vosf = false; -#endif -#endif - - // Set frame buffer base - const_cast(&mode)->bytes_per_row = bytes_per_row; - const_cast(&mode)->depth = DepthModeForPixelDepth(fb_depth); - set_mac_frame_buffer(monitor, mode.depth, true); - - // Everything went well - init_ok = true; -} - -// Close display -driver_fbdev::~driver_fbdev() -{ - if (!use_vosf) { - if (the_buffer != MAP_FAILED) { - // don't free() the screen buffer in driver_base dtor - munmap(the_buffer, the_buffer_size); - the_buffer = NULL; - } - } -#ifdef ENABLE_VOSF - else { - if (the_host_buffer != MAP_FAILED) { - // don't free() the screen buffer in driver_base dtor - munmap(the_host_buffer, the_buffer_size); - the_host_buffer = NULL; - } - } -#endif -} -#endif - - -#ifdef ENABLE_XF86_DGA -/* - * XFree86 DGA display driver - */ - -class driver_xf86dga : public driver_dga { -public: - driver_xf86dga(X11_monitor_desc &monitor); - ~driver_xf86dga(); - - void update_palette(void); - void resume(void); - -private: - int current_dga_cmap; // Number (0 or 1) of currently installed DGA colormap -}; - -// Open display -driver_xf86dga::driver_xf86dga(X11_monitor_desc &m) - : driver_dga(m), current_dga_cmap(0) -{ - int width = mode.x, height = mode.y; - - // Set relative mouse mode - ADBSetRelMouseMode(true); - -#ifdef ENABLE_XF86_VIDMODE - // Switch to best mode - if (has_vidmode) { - int best = 0; - for (int i=1; ihdisplay >= width && x_video_modes[i]->vdisplay >= height && - x_video_modes[i]->hdisplay <= x_video_modes[best]->hdisplay && x_video_modes[i]->vdisplay <= x_video_modes[best]->vdisplay) { - best = i; - } - } - XF86VidModeSwitchToMode(x_display, screen, x_video_modes[best]); - XF86VidModeSetViewPort(x_display, screen, 0, 0); - XSync(x_display, false); - } -#endif - - // Create window - XSetWindowAttributes wattr; - wattr.event_mask = eventmask = dga_eventmask; - wattr.override_redirect = True; - wattr.colormap = (mode.depth == VDEPTH_1BIT ? DefaultColormap(x_display, screen) : cmap[0]); - - w = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth, - InputOutput, vis, CWEventMask | CWOverrideRedirect | - (color_class == DirectColor ? CWColormap : 0), &wattr); - - // Set window name/class - set_window_name(w, STR_WINDOW_TITLE); - - // Indicate that we want keyboard input - set_window_focus(w); - - // Show window - XMapRaised(x_display, w); - wait_mapped(w); - - // Establish direct screen connection - XMoveResizeWindow(x_display, w, 0, 0, width, height); - XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0); - XGrabKeyboard(x_display, rootwin, True, GrabModeAsync, GrabModeAsync, CurrentTime); - XGrabPointer(x_display, rootwin, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - disable_mouse_accel(); - - int v_width, v_bank, v_size; - XF86DGAGetVideo(x_display, screen, (char **)&the_buffer, &v_width, &v_bank, &v_size); - XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse); - XF86DGASetViewPort(x_display, screen, 0, 0); - XF86DGASetVidPage(x_display, screen, 0); - - // Set colormap - if (!IsDirectMode(mode)) { - XSetWindowColormap(x_display, w, cmap[current_dga_cmap = 0]); - XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]); - } - XSync(x_display, false); - - // Init blitting routines - int bytes_per_row = TrivialBytesPerRow((v_width + 7) & ~7, mode.depth); -#if ENABLE_VOSF -#if REAL_ADDRESSING || DIRECT_ADDRESSING - // Screen_blitter_init() returns TRUE if VOSF is mandatory - // i.e. the framebuffer update function is not Blit_Copy_Raw - use_vosf = Screen_blitter_init(visualFormat, x_native_byte_order, depth_of_video_mode(mode)); - - if (use_vosf) { - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - the_host_buffer = the_buffer; - the_buffer_size = page_extend((height + 2) * bytes_per_row); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - - // Fake image for DGA/VOSF mode to know about display bounds - img = new FakeXImage((v_width + 7) & ~7, height, depth_of_video_mode(mode)); - } -#else - use_vosf = false; -#endif -#endif - - // Set frame buffer base - const_cast(&mode)->bytes_per_row = bytes_per_row; - set_mac_frame_buffer(monitor, mode.depth, true); - - // Everything went well - init_ok = true; -} - -// Close display -driver_xf86dga::~driver_xf86dga() -{ - XF86DGADirectVideo(x_display, screen, 0); - if (!use_vosf) { - // don't free() the screen buffer in driver_base dtor - the_buffer = NULL; - } -#ifdef ENABLE_VOSF - else { - // don't free() the screen buffer in driver_base dtor - the_host_buffer = NULL; - } -#endif -#ifdef ENABLE_XF86_VIDMODE - if (has_vidmode) - XF86VidModeSwitchToMode(x_display, screen, x_video_modes[0]); -#endif -} - -// Palette has changed -void driver_xf86dga::update_palette(void) -{ - driver_dga::update_palette(); - current_dga_cmap ^= 1; - if (!IsDirectMode(monitor.get_current_mode()) && cmap[current_dga_cmap]) - XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]); -} - -// Resume emulation -void driver_xf86dga::resume(void) -{ - driver_dga::resume(); - if (!IsDirectMode(monitor.get_current_mode())) - XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]); -} -#endif - - -/* - * Initialization - */ - -// Init keycode translation table -static void keycode_init(void) -{ - bool use_kc = PrefsFindBool("keycodes"); - if (use_kc) { - - // Get keycode file path from preferences - const char *kc_path = PrefsFindString("keycodefile"); - - // Open keycode table - FILE *f = fopen(kc_path ? kc_path : KEYCODE_FILE_NAME, "r"); - if (f == NULL) { - char str[256]; - sprintf(str, GetString(STR_KEYCODE_FILE_WARN), kc_path ? kc_path : KEYCODE_FILE_NAME, strerror(errno)); - WarningAlert(str); - return; - } - - // Default translation table - for (int i=0; i<256; i++) - keycode_table[i] = -1; - - // Search for server vendor string, then read keycodes - const char *vendor = ServerVendor(x_display); - // Force use of MacX mappings on MacOS X with Apple's X server - int dummy; - if (XQueryExtension(x_display, "Apple-DRI", &dummy, &dummy, &dummy)) - vendor = "MacX"; - bool vendor_found = false; - char line[256]; - while (fgets(line, 255, f)) { - // Read line - int len = strlen(line); - if (len == 0) - continue; - line[len-1] = 0; - - // Comments begin with "#" or ";" - if (line[0] == '#' || line[0] == ';' || line[0] == 0) - continue; - - if (vendor_found) { - // Read keycode - int x_code, mac_code; - if (sscanf(line, "%d %d", &x_code, &mac_code) == 2) - keycode_table[x_code & 0xff] = mac_code; - else - break; - } else { - // Search for vendor string - if (strstr(vendor, line) == vendor) - vendor_found = true; - } - } - - // Keycode file completely read - fclose(f); - use_keycodes = vendor_found; - - // Vendor not found? Then display warning - if (!vendor_found) { - char str[256]; - sprintf(str, GetString(STR_KEYCODE_VENDOR_WARN), vendor, kc_path ? kc_path : KEYCODE_FILE_NAME); - WarningAlert(str); - return; - } - } -} - -// Open display for current mode -bool X11_monitor_desc::video_open(void) -{ - D(bug("video_open()\n")); - const video_mode &mode = get_current_mode(); - - // Find best available X visual - if (!find_visual_for_depth(mode.depth)) { - ErrorAlert(STR_NO_XVISUAL_ERR); - return false; - } - - // Determine the byte order of an XImage content -#ifdef WORDS_BIGENDIAN - x_native_byte_order = (XImageByteOrder(x_display) == MSBFirst); -#else - x_native_byte_order = (XImageByteOrder(x_display) == LSBFirst); -#endif - - // Build up visualFormat structure - visualFormat.fullscreen = (display_type == DISPLAY_DGA); - visualFormat.depth = visualInfo.depth; - visualFormat.Rmask = visualInfo.red_mask; - visualFormat.Gmask = visualInfo.green_mask; - visualFormat.Bmask = visualInfo.blue_mask; - - // Create color maps - if (color_class == PseudoColor || color_class == DirectColor) { - cmap[0] = XCreateColormap(x_display, rootwin, vis, AllocAll); - cmap[1] = XCreateColormap(x_display, rootwin, vis, AllocAll); - } else { - cmap[0] = XCreateColormap(x_display, rootwin, vis, AllocNone); - cmap[1] = XCreateColormap(x_display, rootwin, vis, AllocNone); - } - - // Find pixel format of direct modes - if (color_class == DirectColor || color_class == TrueColor) { - rshift = gshift = bshift = 0; - rloss = gloss = bloss = 8; - uint32 mask; - for (mask=vis->red_mask; !(mask&1); mask>>=1) - ++rshift; - for (; mask&1; mask>>=1) - --rloss; - for (mask=vis->green_mask; !(mask&1); mask>>=1) - ++gshift; - for (; mask&1; mask>>=1) - --gloss; - for (mask=vis->blue_mask; !(mask&1); mask>>=1) - ++bshift; - for (; mask&1; mask>>=1) - --bloss; - } - - // Preset palette pixel values for CLUT or gamma table - if (color_class == DirectColor) { - int num = vis->map_entries; - for (int i=0; imap_entries : 256); - for (int i=0; i16/32 expand map - if (!IsDirectMode(mode) && xdepth > 8) - for (int i=0; i<256; i++) - ExpandMap[i] = map_rgb(i, i, i, true); -#endif - - // Create display driver object of requested type - switch (display_type) { - case DISPLAY_WINDOW: - drv = new driver_window(*this); - break; -#ifdef ENABLE_FBDEV_DGA - case DISPLAY_DGA: - drv = new driver_fbdev(*this); - break; -#endif -#ifdef ENABLE_XF86_DGA - case DISPLAY_DGA: - drv = new driver_xf86dga(*this); - break; -#endif - } - if (drv == NULL) - return false; - if (!drv->init_ok) { - delete drv; - drv = NULL; - return false; - } - -#ifdef ENABLE_VOSF - if (use_vosf) { - // Initialize the VOSF system - if (!video_vosf_init(*this)) { - ErrorAlert(STR_VOSF_INIT_ERR); - return false; - } - } -#endif - - // Initialize VideoRefresh function - VideoRefreshInit(); - - // Lock down frame buffer - XSync(x_display, false); - LOCK_FRAME_BUFFER; - - // Start redraw/input thread -#ifdef USE_PTHREADS_SERVICES - redraw_thread_cancel = false; - Set_pthread_attr(&redraw_thread_attr, 0); - redraw_thread_active = (pthread_create(&redraw_thread, &redraw_thread_attr, redraw_func, NULL) == 0); - if (!redraw_thread_active) { - printf("FATAL: cannot create redraw thread\n"); - return false; - } -#else - redraw_thread_active = true; -#endif - - return true; -} - -bool VideoInit(bool classic) -{ - classic_mode = classic; - -#ifdef ENABLE_VOSF - // Zero the mainBuffer structure - mainBuffer.dirtyPages = NULL; - mainBuffer.pageInfo = NULL; -#endif - - // Check if X server runs on local machine - local_X11 = (strncmp(XDisplayName(x_display_name), ":", 1) == 0) - || (strncmp(XDisplayName(x_display_name), "/", 1) == 0) - || (strncmp(XDisplayName(x_display_name), "unix:", 5) == 0); - - // Init keycode translation - keycode_init(); - - // Read prefs - frame_skip = PrefsFindInt32("frameskip"); - mouse_wheel_mode = PrefsFindInt32("mousewheelmode"); - mouse_wheel_lines = PrefsFindInt32("mousewheellines"); - - // Find screen and root window - screen = XDefaultScreen(x_display); - rootwin = XRootWindow(x_display, screen); - - // Get sorted list of available depths - avail_depths = XListDepths(x_display, screen, &num_depths); - if (avail_depths == NULL) { - ErrorAlert(STR_UNSUPP_DEPTH_ERR); - return false; - } - std::sort(avail_depths, avail_depths + num_depths); - -#ifdef ENABLE_FBDEV_DGA - // Frame buffer name - char fb_name[20]; - - // Could do fbdev DGA? - if ((fbdev_fd = open(FBDEVICE_FILE_NAME, O_RDWR)) != -1) - has_dga = true; - else - has_dga = false; -#endif - -#ifdef ENABLE_XF86_DGA - // DGA available? - int dga_event_base, dga_error_base; - if (local_X11 && XF86DGAQueryExtension(x_display, &dga_event_base, &dga_error_base)) { - int dga_flags = 0; - XF86DGAQueryDirectVideo(x_display, screen, &dga_flags); - has_dga = dga_flags & XF86DGADirectPresent; - } else - has_dga = false; -#endif - -#ifdef ENABLE_XF86_VIDMODE - // VidMode available? - int vm_event_base, vm_error_base; - has_vidmode = XF86VidModeQueryExtension(x_display, &vm_event_base, &vm_error_base); - if (has_vidmode) - XF86VidModeGetAllModeLines(x_display, screen, &num_x_video_modes, &x_video_modes); -#endif - - // Find black and white colors - XParseColor(x_display, DefaultColormap(x_display, screen), "rgb:00/00/00", &black); - XAllocColor(x_display, DefaultColormap(x_display, screen), &black); - XParseColor(x_display, DefaultColormap(x_display, screen), "rgb:ff/ff/ff", &white); - XAllocColor(x_display, DefaultColormap(x_display, screen), &white); - black_pixel = BlackPixel(x_display, screen); - white_pixel = WhitePixel(x_display, screen); - - // Get screen mode from preferences - const char *mode_str; - if (classic_mode) - mode_str = "win/512/342"; - else - mode_str = PrefsFindString("screen"); - - // Determine display type and default dimensions - int default_width = 512, default_height = 384; - display_type = DISPLAY_WINDOW; - if (mode_str) { - if (sscanf(mode_str, "win/%d/%d", &default_width, &default_height) == 2) { - display_type = DISPLAY_WINDOW; -#ifdef ENABLE_FBDEV_DGA - } else if (has_dga && sscanf(mode_str, "dga/%19s", fb_name) == 1) { - display_type = DISPLAY_DGA; - default_width = -1; default_height = -1; // use entire screen -#endif -#ifdef ENABLE_XF86_DGA - } else if (has_dga && sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) { - display_type = DISPLAY_DGA; -#endif - } - } - if (default_width <= 0) - default_width = DisplayWidth(x_display, screen); - else if (default_width > DisplayWidth(x_display, screen)) - default_width = DisplayWidth(x_display, screen); - if (default_height <= 0) - default_height = DisplayHeight(x_display, screen); - else if (default_height > DisplayHeight(x_display, screen)) - default_height = DisplayHeight(x_display, screen); - - // Mac screen depth follows X depth - video_depth default_depth = VDEPTH_1BIT; - switch (DefaultDepth(x_display, screen)) { - case 8: - default_depth = VDEPTH_8BIT; - break; - case 15: case 16: - default_depth = VDEPTH_16BIT; - break; - case 24: case 32: - default_depth = VDEPTH_32BIT; - break; - } - - // Construct list of supported modes - if (display_type == DISPLAY_WINDOW) { - if (classic) - add_mode(512, 342, 0x80, 64, VDEPTH_1BIT); - else { - for (unsigned d=VDEPTH_1BIT; d<=VDEPTH_32BIT; d++) { - if (find_visual_for_depth(video_depth(d))) - add_window_modes(video_depth(d)); - } - } - } else - add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth); - if (VideoModes.empty()) { - ErrorAlert(STR_NO_XVISUAL_ERR); - return false; - } - - // Find requested default mode with specified dimensions - uint32 default_id; - std::vector::const_iterator i, end = VideoModes.end(); - for (i = VideoModes.begin(); i != end; ++i) { - if (i->x == default_width && i->y == default_height && i->depth == default_depth) { - default_id = i->resolution_id; - break; - } - } - if (i == end) { // not found, use first available mode - default_depth = VideoModes[0].depth; - default_id = VideoModes[0].resolution_id; - } - -#if DEBUG - D(bug("Available video modes:\n")); - for (i = VideoModes.begin(); i != end; ++i) { - int bits = 1 << i->depth; - if (bits == 16) - bits = 15; - else if (bits == 32) - bits = 24; - D(bug(" %dx%d (ID %02x), %d colors\n", i->x, i->y, i->resolution_id, 1 << bits)); - } -#endif - - // Create X11_monitor_desc for this (the only) display - X11_monitor_desc *monitor = new X11_monitor_desc(VideoModes, default_depth, default_id); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); -} - - -/* - * Deinitialization - */ - -// Close display -void X11_monitor_desc::video_close(void) -{ - D(bug("video_close()\n")); - - // Stop redraw thread -#ifdef USE_PTHREADS_SERVICES - if (redraw_thread_active) { - redraw_thread_cancel = true; - redraw_thread_cancel_ack = false; - pthread_join(redraw_thread, NULL); - while (!redraw_thread_cancel_ack) ; - } -#endif - redraw_thread_active = false; - - // Unlock frame buffer - UNLOCK_FRAME_BUFFER; - XSync(x_display, false); - D(bug(" frame buffer unlocked\n")); - -#ifdef ENABLE_VOSF - if (use_vosf) { - // Deinitialize VOSF - video_vosf_exit(); - } -#endif - - // Close display - delete drv; - drv = NULL; - - // Free colormaps - if (cmap[0]) { - XFreeColormap(x_display, cmap[0]); - cmap[0] = 0; - } - if (cmap[1]) { - XFreeColormap(x_display, cmap[1]); - cmap[1] = 0; - } -} - -void VideoExit(void) -{ - // Close displays - vector::iterator i, end = VideoMonitors.end(); - for (i = VideoMonitors.begin(); i != end; ++i) - dynamic_cast(*i)->video_close(); - -#ifdef ENABLE_XF86_VIDMODE - // Free video mode list - if (x_video_modes) { - XFree(x_video_modes); - x_video_modes = NULL; - } -#endif - -#ifdef ENABLE_FBDEV_DGA - // Close framebuffer device - if (fbdev_fd >= 0) { - close(fbdev_fd); - fbdev_fd = -1; - } -#endif - - // Free depth list - if (avail_depths) { - XFree(avail_depths); - avail_depths = NULL; - } -} - - -/* - * Close down full-screen mode (if bringing up error alerts is unsafe while in full-screen mode) - */ - -void VideoQuitFullScreen(void) -{ - D(bug("VideoQuitFullScreen()\n")); - quit_full_screen = true; -} - - -/* - * Mac VBL interrupt - */ - -void VideoInterrupt(void) -{ - // Emergency quit requested? Then quit - if (emerg_quit) - QuitEmulator(); - - // Temporarily give up frame buffer lock (this is the point where - // we are suspended when the user presses Ctrl-Tab) - UNLOCK_FRAME_BUFFER; - LOCK_FRAME_BUFFER; -} - - -/* - * Set palette - */ - -void X11_monitor_desc::set_palette(uint8 *pal, int num_in) -{ - const video_mode &mode = get_current_mode(); - - LOCK_PALETTE; - - // Convert colors to XColor array - int num_out = 256; - bool stretch = false; - if (IsDirectMode(mode)) { - // If X is in 565 mode we have to stretch the gamma table from 32 to 64 entries - num_out = vis->map_entries; - stretch = true; - } - XColor *p = x_palette; - for (int i=0; ired = pal[c*3 + 0] * 0x0101; - p->green = pal[c*3 + 1] * 0x0101; - p->blue = pal[c*3 + 2] * 0x0101; - p++; - } - -#ifdef ENABLE_VOSF - // Recalculate pixel color expansion map - if (!IsDirectMode(mode) && xdepth > 8) { - for (int i=0; i<256; i++) { - int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier) - ExpandMap[i] = map_rgb(pal[c*3+0], pal[c*3+1], pal[c*3+2], true); - } - - // We have to redraw everything because the interpretation of pixel values changed - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y); - } -#endif - - // Tell redraw thread to change palette - x_palette_changed = true; - - UNLOCK_PALETTE; -} - - -/* - * Switch video mode - */ - -void X11_monitor_desc::switch_to_current_mode(void) -{ - // Close and reopen display - video_close(); - video_open(); - - if (drv == NULL) { - ErrorAlert(STR_OPEN_WINDOW_ERR); - QuitEmulator(); - } -} - - -/* - * Translate key event to Mac keycode, returns -1 if no keycode was found - * and -2 if the key was recognized as a hotkey - */ - -static int kc_decode(KeySym ks, bool key_down) -{ - switch (ks) { - case XK_A: case XK_a: return 0x00; - case XK_B: case XK_b: return 0x0b; - case XK_C: case XK_c: return 0x08; - case XK_D: case XK_d: return 0x02; - case XK_E: case XK_e: return 0x0e; - case XK_F: case XK_f: return 0x03; - case XK_G: case XK_g: return 0x05; - case XK_H: case XK_h: return 0x04; - case XK_I: case XK_i: return 0x22; - case XK_J: case XK_j: return 0x26; - case XK_K: case XK_k: return 0x28; - case XK_L: case XK_l: return 0x25; - case XK_M: case XK_m: return 0x2e; - case XK_N: case XK_n: return 0x2d; - case XK_O: case XK_o: return 0x1f; - case XK_P: case XK_p: return 0x23; - case XK_Q: case XK_q: return 0x0c; - case XK_R: case XK_r: return 0x0f; - case XK_S: case XK_s: return 0x01; - case XK_T: case XK_t: return 0x11; - case XK_U: case XK_u: return 0x20; - case XK_V: case XK_v: return 0x09; - case XK_W: case XK_w: return 0x0d; - case XK_X: case XK_x: return 0x07; - case XK_Y: case XK_y: return 0x10; - case XK_Z: case XK_z: return 0x06; - - case XK_1: case XK_exclam: return 0x12; - case XK_2: case XK_at: return 0x13; - case XK_3: case XK_numbersign: return 0x14; - case XK_4: case XK_dollar: return 0x15; - case XK_5: case XK_percent: return 0x17; - case XK_6: return 0x16; - case XK_7: return 0x1a; - case XK_8: return 0x1c; - case XK_9: return 0x19; - case XK_0: return 0x1d; - - case XK_grave: case XK_asciitilde: return 0x0a; - case XK_minus: case XK_underscore: return 0x1b; - case XK_equal: case XK_plus: return 0x18; - case XK_bracketleft: case XK_braceleft: return 0x21; - case XK_bracketright: case XK_braceright: return 0x1e; - case XK_backslash: case XK_bar: return 0x2a; - case XK_semicolon: case XK_colon: return 0x29; - case XK_apostrophe: case XK_quotedbl: return 0x27; - case XK_comma: case XK_less: return 0x2b; - case XK_period: case XK_greater: return 0x2f; - case XK_slash: case XK_question: return 0x2c; - - case XK_Tab: if (ctrl_down) {if (key_down) drv->suspend(); return -2;} else return 0x30; - case XK_Return: return 0x24; - case XK_space: return 0x31; - case XK_BackSpace: return 0x33; - - case XK_Delete: return 0x75; - case XK_Insert: return 0x72; - case XK_Home: case XK_Help: return 0x73; - case XK_End: return 0x77; -#ifdef __hpux - case XK_Prior: return 0x74; - case XK_Next: return 0x79; -#else - case XK_Page_Up: return 0x74; - case XK_Page_Down: return 0x79; -#endif - - case XK_Control_L: return 0x36; - case XK_Control_R: return 0x36; - case XK_Shift_L: return 0x38; - case XK_Shift_R: return 0x38; - case XK_Alt_L: return 0x37; - case XK_Alt_R: return 0x37; - case XK_Meta_L: return 0x3a; - case XK_Meta_R: return 0x3a; - case XK_Menu: return 0x32; - case XK_Caps_Lock: return 0x39; - case XK_Num_Lock: return 0x47; - - case XK_Up: return 0x3e; - case XK_Down: return 0x3d; - case XK_Left: return 0x3b; - case XK_Right: return 0x3c; - - case XK_Escape: if (ctrl_down) {if (key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35; - - case XK_F1: if (ctrl_down) {if (key_down) SysMountFirstFloppy(); return -2;} else return 0x7a; - case XK_F2: return 0x78; - case XK_F3: return 0x63; - case XK_F4: return 0x76; - case XK_F5: if (ctrl_down) {if (key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60; - case XK_F6: return 0x61; - case XK_F7: return 0x62; - case XK_F8: return 0x64; - case XK_F9: return 0x65; - case XK_F10: return 0x6d; - case XK_F11: return 0x67; - case XK_F12: return 0x6f; - - case XK_Print: return 0x69; - case XK_Scroll_Lock: return 0x6b; - case XK_Pause: return 0x71; - -#if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End) - case XK_KP_0: case XK_KP_Insert: return 0x52; - case XK_KP_1: case XK_KP_End: return 0x53; - case XK_KP_2: case XK_KP_Down: return 0x54; - case XK_KP_3: case XK_KP_Next: return 0x55; - case XK_KP_4: case XK_KP_Left: return 0x56; - case XK_KP_5: case XK_KP_Begin: return 0x57; - case XK_KP_6: case XK_KP_Right: return 0x58; - case XK_KP_7: case XK_KP_Home: return 0x59; - case XK_KP_8: case XK_KP_Up: return 0x5b; - case XK_KP_9: case XK_KP_Prior: return 0x5c; - case XK_KP_Decimal: case XK_KP_Delete: return 0x41; -#else - case XK_KP_0: return 0x52; - case XK_KP_1: return 0x53; - case XK_KP_2: return 0x54; - case XK_KP_3: return 0x55; - case XK_KP_4: return 0x56; - case XK_KP_5: return 0x57; - case XK_KP_6: return 0x58; - case XK_KP_7: return 0x59; - case XK_KP_8: return 0x5b; - case XK_KP_9: return 0x5c; - case XK_KP_Decimal: return 0x41; -#endif - case XK_KP_Add: return 0x45; - case XK_KP_Subtract: return 0x4e; - case XK_KP_Multiply: return 0x43; - case XK_KP_Divide: return 0x4b; - case XK_KP_Enter: return 0x4c; - case XK_KP_Equal: return 0x51; - } - return -1; -} - -static int event2keycode(XKeyEvent &ev, bool key_down) -{ - KeySym ks; - int i = 0; - - do { - ks = XLookupKeysym(&ev, i++); - int as = kc_decode(ks, key_down); - if (as >= 0) - return as; - if (as == -2) - return as; - } while (ks != NoSymbol); - - return -1; -} - - -/* - * X event handling - */ - -static void handle_events(void) -{ - for (;;) { - XEvent event; - XDisplayLock(); - - if (!XCheckMaskEvent(x_display, eventmask, &event)) { - // Handle clipboard events - if (XCheckTypedEvent(x_display, SelectionRequest, &event)) - ClipboardSelectionRequest(&event.xselectionrequest); - else if (XCheckTypedEvent(x_display, SelectionClear, &event)) - ClipboardSelectionClear(&event.xselectionclear); - - // Window "close" widget clicked - else if (XCheckTypedEvent(x_display, ClientMessage, &event)) { - if (event.xclient.format == 32 && event.xclient.data.l[0] == WM_DELETE_WINDOW) { - ADBKeyDown(0x7f); // Power key - ADBKeyUp(0x7f); - } - } - XDisplayUnlock(); - break; - } - - switch (event.type) { - - // Mouse button - case ButtonPress: { - unsigned int button = event.xbutton.button; - if (button < 4) - ADBMouseDown(button - 1); - else if (button < 6) { // Wheel mouse - if (mouse_wheel_mode == 0) { - int key = (button == 5) ? 0x79 : 0x74; // Page up/down - ADBKeyDown(key); - ADBKeyUp(key); - } else { - int key = (button == 5) ? 0x3d : 0x3e; // Cursor up/down - for(int i=0; imouse_moved(event.xmotion.x, event.xmotion.y); - break; - - // Mouse entered window - case EnterNotify: - if (event.xcrossing.mode != NotifyGrab && event.xcrossing.mode != NotifyUngrab) - drv->mouse_moved(event.xmotion.x, event.xmotion.y); - break; - - // Keyboard - case KeyPress: { - int code = -1; - if (use_keycodes) { - if (event2keycode(event.xkey, true) != -2) // This is called to process the hotkeys - code = keycode_table[event.xkey.keycode & 0xff]; - } else - code = event2keycode(event.xkey, true); - if (code >= 0) { - if (!emul_suspended) { - if (code == 0x39) { // Caps Lock pressed - if (caps_on) { - ADBKeyUp(code); - caps_on = false; - } else { - ADBKeyDown(code); - caps_on = true; - } - } else - ADBKeyDown(code); - if (code == 0x36) - ctrl_down = true; - } else { - if (code == 0x31) - drv->resume(); // Space wakes us up - } - } - break; - } - case KeyRelease: { - int code = -1; - if (use_keycodes) { - if (event2keycode(event.xkey, false) != -2) // This is called to process the hotkeys - code = keycode_table[event.xkey.keycode & 0xff]; - } else - code = event2keycode(event.xkey, false); - if (code >= 0 && code != 0x39) { // Don't propagate Caps Lock releases - ADBKeyUp(code); - if (code == 0x36) - ctrl_down = false; - } - break; - } - - // Hidden parts exposed, force complete refresh of window - case Expose: - if (display_type == DISPLAY_WINDOW) { - const video_mode &mode = VideoMonitors[0]->get_current_mode(); -#ifdef ENABLE_VOSF - if (use_vosf) { // VOSF refresh - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y); - } - else -#endif - if (frame_skip == 0) { // Dynamic refresh - int x1, y1; - for (y1=0; y1<16; y1++) - for (x1=0; x1<16; x1++) - updt_box[x1][y1] = true; - nr_boxes = 16 * 16; - } else // Static refresh - memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y); - } - break; - } - - XDisplayUnlock(); - } -} - - -/* - * Window display update - */ - -// Dynamic display update (variable frame rate for each box) -static void update_display_dynamic(int ticker, driver_window *drv) -{ - int y1, y2, y2s, y2a, i, x1, xm, xmo, ymo, yo, yi, yil, xi; - int xil = 0; - int rxm = 0, rxmo = 0; - const video_mode &mode = drv->monitor.get_current_mode(); - int bytes_per_row = mode.bytes_per_row; - int bytes_per_pixel = mode.bytes_per_row / mode.x; - int rx = mode.bytes_per_row / 16; - int ry = mode.y / 16; - int max_box; - - y2s = sm_uptd[ticker % 8]; - y2a = 8; - for (i = 0; i < 6; i++) { - if (ticker % (2 << i)) - break; - } - max_box = sm_no_boxes[i]; - - if (y2a) { - for (y1=0; y1<16; y1++) { - for (y2=y2s; y2 < ry; y2 += y2a) { - i = ((y1 * ry) + y2) * bytes_per_row; - for (x1=0; x1<16; x1++, i += rx) { - if (updt_box[x1][y1] == false) { - if (memcmp(&the_buffer_copy[i], &the_buffer[i], rx)) { - updt_box[x1][y1] = true; - nr_boxes++; - } - } - } - } - } - } - - XDisplayLock(); - if ((nr_boxes <= max_box) && (nr_boxes)) { - for (y1=0; y1<16; y1++) { - for (x1=0; x1<16; x1++) { - if (updt_box[x1][y1] == true) { - if (rxm == 0) - xm = x1; - rxm += rx; - updt_box[x1][y1] = false; - } - if (((updt_box[x1+1][y1] == false) || (x1 == 15)) && (rxm)) { - if ((rxmo != rxm) || (xmo != xm) || (yo != y1 - 1)) { - if (rxmo) { - xi = xmo * rx; - yi = ymo * ry; - xil = rxmo; - yil = (yo - ymo +1) * ry; - } - rxmo = rxm; - xmo = xm; - ymo = y1; - } - rxm = 0; - yo = y1; - } - if (xil) { - i = (yi * bytes_per_row) + xi; - for (y2=0; y2 < yil; y2++, i += bytes_per_row) - memcpy(&the_buffer_copy[i], &the_buffer[i], xil); - if (mode.depth == VDEPTH_1BIT) { - if (drv->have_shm) - XShmPutImage(x_display, drv->w, drv->gc, drv->img, xi * 8, yi, xi * 8, yi, xil * 8, yil, 0); - else - XPutImage(x_display, drv->w, drv->gc, drv->img, xi * 8, yi, xi * 8, yi, xil * 8, yil); - } else { - if (drv->have_shm) - XShmPutImage(x_display, drv->w, drv->gc, drv->img, xi / bytes_per_pixel, yi, xi / bytes_per_pixel, yi, xil / bytes_per_pixel, yil, 0); - else - XPutImage(x_display, drv->w, drv->gc, drv->img, xi / bytes_per_pixel, yi, xi / bytes_per_pixel, yi, xil / bytes_per_pixel, yil); - } - xil = 0; - } - if ((x1 == 15) && (y1 == 15) && (rxmo)) { - x1--; - xi = xmo * rx; - yi = ymo * ry; - xil = rxmo; - yil = (yo - ymo +1) * ry; - rxmo = 0; - } - } - } - nr_boxes = 0; - } - XDisplayUnlock(); -} - -// Static display update (fixed frame rate, but incremental) -static void update_display_static(driver_window *drv) -{ - // Incremental update code - unsigned wide = 0, high = 0, x1, x2, y1, y2, i, j; - const video_mode &mode = drv->monitor.get_current_mode(); - int bytes_per_row = mode.bytes_per_row; - int bytes_per_pixel = mode.bytes_per_row / mode.x; - uint8 *p, *p2; - - // Check for first line from top and first line from bottom that have changed - y1 = 0; - for (j=0; j=y1; j--) { - if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { - y2 = j; - break; - } - } - high = y2 - y1 + 1; - - // Check for first column from left and first column from right that have changed - if (high) { - if (mode.depth == VDEPTH_1BIT) { - x1 = mode.x - 1; - for (j=y1; j<=y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (i=0; i<(x1>>3); i++) { - if (*p != *p2) { - x1 = i << 3; - break; - } - p++; p2++; - } - } - x2 = x1; - for (j=y1; j<=y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - p += bytes_per_row; - p2 += bytes_per_row; - for (i=(mode.x>>3); i>(x2>>3); i--) { - p--; p2--; - if (*p != *p2) { - x2 = (i << 3) + 7; - break; - } - } - } - wide = x2 - x1 + 1; - - // Update copy of the_buffer - if (high && wide) { - for (j=y1; j<=y2; j++) { - i = j * bytes_per_row + (x1 >> 3); - memcpy(the_buffer_copy + i, the_buffer + i, wide >> 3); - } - } - - } else { - x1 = mode.x; - for (j=y1; j<=y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (i=0; ix2*bytes_per_pixel; i--) { - p--; - p2--; - if (*p != *p2) { - x2 = i / bytes_per_pixel; - break; - } - } - } - wide = x2 - x1; - - // Update copy of the_buffer - if (high && wide) { - for (j=y1; j<=y2; j++) { - i = j * bytes_per_row + x1 * bytes_per_pixel; - memcpy(the_buffer_copy + i, the_buffer + i, bytes_per_pixel * wide); - } - } - } - } - - // Refresh display - XDisplayLock(); - if (high && wide) { - if (drv->have_shm) - XShmPutImage(x_display, drv->w, drv->gc, drv->img, x1, y1, x1, y1, wide, high, 0); - else - XPutImage(x_display, drv->w, drv->gc, drv->img, x1, y1, x1, y1, wide, high); - } - XDisplayUnlock(); -} - - -/* - * Screen refresh functions - */ - -// We suggest the compiler to inline the next two functions so that it -// may specialise the code according to the current screen depth and -// display type. A clever compiler would do that job by itself though... - -// NOTE: update_display_vosf is inlined too - -static inline void possibly_quit_dga_mode() -{ - // Quit DGA mode if requested (something terrible has happened and we - // want to give control back to the user) - if (quit_full_screen) { - quit_full_screen = false; - delete drv; - drv = NULL; - } -} - -static inline void possibly_ungrab_mouse() -{ - // Ungrab mouse if requested (something terrible has happened and we - // want to give control back to the user) - if (quit_full_screen) { - quit_full_screen = false; - if (drv) - drv->ungrab_mouse(); - } -} - -static inline void handle_palette_changes(void) -{ - LOCK_PALETTE; - - if (x_palette_changed) { - x_palette_changed = false; - XDisplayLock(); - drv->update_palette(); - XDisplayUnlock(); - } - - UNLOCK_PALETTE; -} - -static void video_refresh_dga(void) -{ - // Quit DGA mode if requested - possibly_quit_dga_mode(); -} - -#ifdef ENABLE_VOSF -#if REAL_ADDRESSING || DIRECT_ADDRESSING -static void video_refresh_dga_vosf(void) -{ - // Quit DGA mode if requested - possibly_quit_dga_mode(); - - // Update display (VOSF variant) - static int tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - if (mainBuffer.dirty) { - LOCK_VOSF; - update_display_dga_vosf(static_cast(drv)); - UNLOCK_VOSF; - } - } -} -#endif - -static void video_refresh_window_vosf(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (VOSF variant) - static int tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - if (mainBuffer.dirty) { - XDisplayLock(); - LOCK_VOSF; - update_display_window_vosf(static_cast(drv)); - UNLOCK_VOSF; - XSync(x_display, false); // Let the server catch up - XDisplayUnlock(); - } - } -} -#endif // def ENABLE_VOSF - -static void video_refresh_window_static(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (static variant) - static int tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - update_display_static(static_cast(drv)); - } -} - -static void video_refresh_window_dynamic(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (dynamic variant) - static int tick_counter = 0; - tick_counter++; - update_display_dynamic(tick_counter, static_cast(drv)); -} - - -/* - * Thread for screen refresh, input handling etc. - */ - -static void VideoRefreshInit(void) -{ - // TODO: set up specialised 8bpp VideoRefresh handlers ? - if (display_type == DISPLAY_DGA) { -#if ENABLE_VOSF && (REAL_ADDRESSING || DIRECT_ADDRESSING) - if (use_vosf) - video_refresh = video_refresh_dga_vosf; - else -#endif - video_refresh = video_refresh_dga; - } - else { -#ifdef ENABLE_VOSF - if (use_vosf) - video_refresh = video_refresh_window_vosf; - else -#endif - if (frame_skip == 0) - video_refresh = video_refresh_window_dynamic; - else - video_refresh = video_refresh_window_static; - } -} - -// This function is called on non-threaded platforms from a timer interrupt -void VideoRefresh(void) -{ - // We need to check redraw_thread_active to inhibit refreshed during - // mode changes on non-threaded platforms - if (!redraw_thread_active) - return; - - // Handle X events - handle_events(); - - // Handle palette changes - handle_palette_changes(); - - // Update display - video_refresh(); -} - -const int VIDEO_REFRESH_HZ = 60; -const int VIDEO_REFRESH_DELAY = 1000000 / VIDEO_REFRESH_HZ; - -#ifdef USE_PTHREADS_SERVICES -static void *redraw_func(void *arg) -{ - int fd = ConnectionNumber(x_display); - - uint64 start = GetTicks_usec(); - int64 ticks = 0; - uint64 next = GetTicks_usec() + VIDEO_REFRESH_DELAY; - - while (!redraw_thread_cancel) { - - int64 delay = next - GetTicks_usec(); - if (delay < -VIDEO_REFRESH_DELAY) { - - // We are lagging far behind, so we reset the delay mechanism - next = GetTicks_usec(); - - } else if (delay <= 0) { - - // Delay expired, refresh display - handle_events(); - handle_palette_changes(); - video_refresh(); - next += VIDEO_REFRESH_DELAY; - ticks++; - - } else { - - // No display refresh pending, check for X events - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = delay; - if (select(fd+1, &readfds, NULL, NULL, &timeout) > 0) - handle_events(); - } - } - - uint64 end = GetTicks_usec(); - D(bug("%lld refreshes in %lld usec = %f refreshes/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start))); - - redraw_thread_cancel_ack = true; - return NULL; -} -#endif diff --git a/BasiliskII/src/Windows/BasiliskII.DebugJIT.props b/BasiliskII/src/Windows/BasiliskII.DebugJIT.props deleted file mode 100644 index 124285ea..00000000 --- a/BasiliskII/src/Windows/BasiliskII.DebugJIT.props +++ /dev/null @@ -1,14 +0,0 @@ - - - - - $(ProjectDir)Debug\ - - - - - - $(ToolsDir) - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/BasiliskII.ReleaseJIT.props b/BasiliskII/src/Windows/BasiliskII.ReleaseJIT.props deleted file mode 100644 index c67b5361..00000000 --- a/BasiliskII/src/Windows/BasiliskII.ReleaseJIT.props +++ /dev/null @@ -1,14 +0,0 @@ - - - - - $(ProjectDir)Release\ - - - - - - $(ToolsDir) - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/BasiliskII.ico b/BasiliskII/src/Windows/BasiliskII.ico deleted file mode 100755 index eb3ac0ef..00000000 Binary files a/BasiliskII/src/Windows/BasiliskII.ico and /dev/null differ diff --git a/BasiliskII/src/Windows/BasiliskII.props b/BasiliskII/src/Windows/BasiliskII.props deleted file mode 100644 index 345f9f06..00000000 --- a/BasiliskII/src/Windows/BasiliskII.props +++ /dev/null @@ -1,14 +0,0 @@ - - - - - $(OutDir) - - - - - - $(ToolsDir) - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/BasiliskII.rc b/BasiliskII/src/Windows/BasiliskII.rc deleted file mode 100644 index ae955c53..00000000 --- a/BasiliskII/src/Windows/BasiliskII.rc +++ /dev/null @@ -1,2 +0,0 @@ -BasiliskII ICON PRELOAD "BasiliskII.ico" - diff --git a/BasiliskII/src/Windows/BasiliskII.sln b/BasiliskII/src/Windows/BasiliskII.sln deleted file mode 100644 index 1c4b7a1f..00000000 --- a/BasiliskII/src/Windows/BasiliskII.sln +++ /dev/null @@ -1,140 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BasiliskII", "BasiliskII.vcxproj", "{1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}" - ProjectSection(ProjectDependencies) = postProject - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48} = {1A9EA738-8DA7-422F-9E0D-BE92893C0E48} - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04} = {95933FE9-C27C-41F0-B4AF-EAAADE94FD04} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "build68k", "build68k.vcxproj", "{7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencpu", "gencpu.vcxproj", "{1A9EA738-8DA7-422F-9E0D-BE92893C0E48}" - ProjectSection(ProjectDependencies) = postProject - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} = {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencomp", "gencomp.vcxproj", "{95933FE9-C27C-41F0-B4AF-EAAADE94FD04}" - ProjectSection(ProjectDependencies) = postProject - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} = {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDLmain", "..\..\..\..\SDL-1.2.15\VisualC\SDLmain\SDLmain.vcxproj", "{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL", "..\..\..\..\SDL-1.2.15\VisualC\SDL\SDL.vcxproj", "{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug JIT|x64 = Debug JIT|x64 - Debug JIT|x86 = Debug JIT|x86 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release JIT|x64 = Release JIT|x64 - Release JIT|x86 = Release JIT|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x64.ActiveCfg = Debug JIT|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x64.Build.0 = Debug JIT|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x86.ActiveCfg = Debug JIT|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x86.Build.0 = Debug JIT|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x64.ActiveCfg = Debug|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x64.Build.0 = Debug|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x86.ActiveCfg = Debug|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x86.Build.0 = Debug|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x64.ActiveCfg = Release JIT|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x64.Build.0 = Release JIT|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x86.ActiveCfg = Release JIT|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x86.Build.0 = Release JIT|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x64.ActiveCfg = Release|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x64.Build.0 = Release|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x86.ActiveCfg = Release|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x86.Build.0 = Release|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x64.ActiveCfg = Debug|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x64.Build.0 = Debug|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x86.ActiveCfg = Debug|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x86.Build.0 = Debug|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x64.ActiveCfg = Debug|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x64.Build.0 = Debug|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x86.ActiveCfg = Debug|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x86.Build.0 = Debug|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x64.ActiveCfg = Release|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x64.Build.0 = Release|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x86.ActiveCfg = Release|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x86.Build.0 = Release|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x64.ActiveCfg = Release|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x64.Build.0 = Release|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x86.ActiveCfg = Release|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x86.Build.0 = Release|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x64.ActiveCfg = Debug|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x64.Build.0 = Debug|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x86.ActiveCfg = Debug|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x86.Build.0 = Debug|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x64.ActiveCfg = Debug|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x64.Build.0 = Debug|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x86.ActiveCfg = Debug|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x86.Build.0 = Debug|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x64.ActiveCfg = Release|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x64.Build.0 = Release|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x86.ActiveCfg = Release|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x86.Build.0 = Release|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x64.ActiveCfg = Release|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x64.Build.0 = Release|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x86.ActiveCfg = Release|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x86.Build.0 = Release|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x64.ActiveCfg = Debug|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x64.Build.0 = Debug|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x86.ActiveCfg = Debug|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x86.Build.0 = Debug|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x64.ActiveCfg = Debug|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x64.Build.0 = Debug|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x86.ActiveCfg = Debug|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x86.Build.0 = Debug|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x64.ActiveCfg = Release|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x64.Build.0 = Release|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x86.ActiveCfg = Release|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x86.Build.0 = Release|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x64.ActiveCfg = Release|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x64.Build.0 = Release|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x86.ActiveCfg = Release|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x86.Build.0 = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x64.ActiveCfg = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x64.Build.0 = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x86.ActiveCfg = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x86.Build.0 = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.ActiveCfg = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.Build.0 = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x86.ActiveCfg = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x86.Build.0 = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x64.ActiveCfg = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x64.Build.0 = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x86.ActiveCfg = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x86.Build.0 = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.ActiveCfg = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.Build.0 = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x86.ActiveCfg = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x86.Build.0 = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x64.ActiveCfg = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x64.Build.0 = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x86.ActiveCfg = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x86.Build.0 = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.ActiveCfg = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.Build.0 = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x86.ActiveCfg = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x86.Build.0 = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x64.ActiveCfg = Release|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x64.Build.0 = Release|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x86.ActiveCfg = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x86.Build.0 = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.ActiveCfg = Release|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.Build.0 = Release|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x86.ActiveCfg = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/BasiliskII/src/Windows/BasiliskII.vcxproj b/BasiliskII/src/Windows/BasiliskII.vcxproj deleted file mode 100644 index cd05c309..00000000 --- a/BasiliskII/src/Windows/BasiliskII.vcxproj +++ /dev/null @@ -1,685 +0,0 @@ - - - - - Debug JIT - Win32 - - - Debug JIT - x64 - - - Debug - Win32 - - - Debug - x64 - - - Release JIT - Win32 - - - Release JIT - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {81ce8daf-ebb2-4761-8e45-b71abcca8c68} - - - {da956fd3-e142-46f2-9dd5-c78bebb56b7a} - - - - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0} - Win32Proj - BasiliskII - 8.1 - - - - Application - true - v140_xp - Unicode - - - Application - true - v140_xp - Unicode - - - Application - true - v140_xp - Unicode - - - Application - true - v140_xp - Unicode - - - Application - false - v140_xp - true - Unicode - - - Application - false - v140_xp - true - Unicode - - - Application - false - v140_xp - true - Unicode - - - Application - false - v140_xp - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - $(Configuration)\$(ProjectName)\ - ClCompile - - - ClCompile - true - - - true - $(Configuration)\$(ProjectName)\ - ClCompile - - - ClCompile - true - - - false - $(Configuration)\$(ProjectName)\ - ClCompile - - - ClCompile - false - - - false - $(Configuration)\$(ProjectName)\ - ClCompile - - - ClCompile - false - - - - - - Level3 - Disabled - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - - - Level3 - Disabled - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - - - Level3 - Disabled - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;USE_JIT;USE_JIT_FPU;JIT_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - - - Level3 - Disabled - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;USE_JIT;USE_JIT_FPU;JIT_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - Level3 - - - MaxSpeed - true - true - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - true - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - Level3 - - - MaxSpeed - true - true - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - true - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - Level3 - - - MaxSpeed - true - true - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;USE_JIT;USE_JIT_FPU;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - true - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - Level3 - - - MaxSpeed - true - true - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;USE_JIT;USE_JIT_FPU;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - true - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/BasiliskII.vcxproj.filters b/BasiliskII/src/Windows/BasiliskII.vcxproj.filters deleted file mode 100644 index 50eae3d1..00000000 --- a/BasiliskII/src/Windows/BasiliskII.vcxproj.filters +++ /dev/null @@ -1,589 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Resource Files - - - - - Resource Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/BasiliskIIGUI.ico b/BasiliskII/src/Windows/BasiliskIIGUI.ico deleted file mode 100755 index 67d4c55f..00000000 Binary files a/BasiliskII/src/Windows/BasiliskIIGUI.ico and /dev/null differ diff --git a/BasiliskII/src/Windows/BasiliskIIGUI.rc b/BasiliskII/src/Windows/BasiliskIIGUI.rc deleted file mode 100644 index 2a0e5586..00000000 --- a/BasiliskII/src/Windows/BasiliskIIGUI.rc +++ /dev/null @@ -1,2 +0,0 @@ -BasiliskIIGUI ICON PRELOAD "BasiliskIIGUI.ico" - diff --git a/BasiliskII/src/Windows/Makefile.in b/BasiliskII/src/Windows/Makefile.in deleted file mode 100755 index dfa59a60..00000000 --- a/BasiliskII/src/Windows/Makefile.in +++ /dev/null @@ -1,236 +0,0 @@ -# Windows Makefile for Basilisk II - -## System specific configuration - -SHELL = /bin/sh - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -datadir = @datadir@ -mandir = @mandir@ -man1dir = $(mandir)/man1 - -KEYCODES = ../SDL/keycodes - -DESTDIR = - -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_LIBS = @SDL_LIBS@ -WANT_GTK = @WANT_GTK@ -GTK_CFLAGS = @GTK_CFLAGS@ -GTK_LIBS = @GTK_LIBS@ - -SLIRP_CFLAGS = @SLIRP_CFLAGS@ -SLIRP_SRCS = \ - ../slirp/bootp.c ../slirp/ip_output.c ../slirp/tcp_input.c \ - ../slirp/cksum.c ../slirp/mbuf.c ../slirp/tcp_output.c \ - ../slirp/debug.c ../slirp/misc.c ../slirp/tcp_subr.c \ - ../slirp/if.c ../slirp/sbuf.c ../slirp/tcp_timer.c \ - ../slirp/ip_icmp.c ../slirp/slirp.c ../slirp/tftp.c \ - ../slirp/ip_input.c ../slirp/socket.c ../slirp/udp.c -SLIRP_OBJS = $(SLIRP_SRCS:../slirp/%.c=$(OBJ_DIR)/slirp-%.o) - -LN_S = @LN_S@ -WINDRES = @WINDRES@ -CC = @CC@ -CXX = @CXX@ -CFLAGS = @CFLAGS@ $(SDL_CFLAGS) -CXXFLAGS = @CXXFLAGS@ $(SDL_CFLAGS) -CPPFLAGS = @CPPFLAGS@ -I../include -I. -I../CrossPlatform @CPUINCLUDES@ -I../slirp -DEFS = @DEFS@ @DEFINES@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -lwsock32 -liphlpapi -CPUSRCS = @CPUSRCS@ - -HOST_CC = gcc -HOST_CXX = g++ -HOST_CFLAGS = -O2 -HOST_CXXFLAGS = -O2 -HOST_LDFLAGS = - -## Files -XPLATSRCS = vm_alloc.cpp vm_alloc.h sigsegv.cpp sigsegv.h video_vosf.h video_blit.cpp video_blit.h - -CDENABLESRCS = cdenable/cache.cpp cdenable/eject_nt.cpp cdenable/ntcd.cpp - -ROUTERSRCS = router/arp.cpp router/dump.cpp router/dynsockets.cpp router/ftp.cpp \ - router/icmp.cpp router/mib/interfaces.cpp router/iphelp.cpp router/ipsocket.cpp \ - router/mib/mibaccess.cpp router/router.cpp router/tcp.cpp router/udp.cpp b2ether/packet32.cpp - -SRCS = ../main.cpp main_windows.cpp ../prefs.cpp ../prefs_items.cpp prefs_windows.cpp \ - sys_windows.cpp ../rom_patches.cpp ../slot_rom.cpp ../rsrc_patches.cpp \ - ../emul_op.cpp ../macos_util.cpp ../xpram.cpp xpram_windows.cpp ../timer.cpp \ - timer_windows.cpp ../adb.cpp ../serial.cpp serial_windows.cpp \ - ../ether.cpp ether_windows.cpp ../sony.cpp ../disk.cpp ../cdrom.cpp \ - ../scsi.cpp ../dummy/scsi_dummy.cpp ../video.cpp ../SDL/video_sdl.cpp \ - video_blit.cpp ../audio.cpp ../SDL/audio_sdl.cpp clip_windows.cpp \ - ../extfs.cpp extfs_windows.cpp ../user_strings.cpp user_strings_windows.cpp \ - vm_alloc.cpp sigsegv.cpp posix_emu.cpp util_windows.cpp \ - ../dummy/prefs_editor_dummy.cpp BasiliskII.rc \ - $(CDENABLESRCS) $(ROUTERSRCS) $(CPUSRCS) $(SLIRP_OBJS) - -UI_SRCS = ../prefs.cpp prefs_windows.cpp prefs_editor_gtk.cpp xpram_windows.cpp \ - ../prefs_items.cpp ../user_strings.cpp user_strings_windows.cpp util_windows.cpp \ - b2ether/Packet32.cpp BasiliskIIGUI.rc - -UI_APP = BasiliskIIGUI.exe - -APP = BasiliskII.exe - -PROGS = $(APP) - -ifeq ($(WANT_GTK),yes) -PROGS += $(UI_APP) -endif - -## Rules -.PHONY: modules install installdirs uninstall mostlyclean clean distclean depend dep -.SUFFIXES: -.SUFFIXES: .c .cpp .s .o .h - -all: $(PROGS) - -$(XPLATSRCS): %: ../CrossPlatform/% - $(LN_S) $< $@ - -OBJ_DIR = obj -$(OBJ_DIR):: - @[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1 - -define SRCS_LIST_TO_OBJS - $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(foreach file, $(SRCS), \ - $(basename $(notdir $(file)))))) -endef -OBJS = $(SRCS_LIST_TO_OBJS) - -define UI_SRCS_LIST_TO_OBJS - $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(foreach file, $(UI_SRCS), \ - $(basename $(notdir $(file)))))) -endef -UI_OBJS = $(UI_SRCS_LIST_TO_OBJS) - -SRC_PATHS += $(sort $(foreach file, $(SRCS), $(dir $(file)))) -VPATH := -VPATH += $(addprefix :, $(subst ,:, $(filter-out $($(subst, :, ,$(VPATH))), $(SRC_PATHS)))) - -$(APP): $(XPLATSRCS) $(OBJ_DIR) $(OBJS) - $(CXX) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) $(SDL_LIBS) - -$(UI_APP): $(XPLATSRCS) $(OBJ_DIR) $(UI_OBJS) - $(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) $(GTK_LIBS) -mwindows -mno-cygwin - -mostlyclean: - rm -f $(APP) $(UI_APP) $(OBJ_DIR)/* core* *.core *~ *.bak - -clean: mostlyclean - rm -f $(XPLATSRCS) - rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h - -distclean: clean - rm -rf $(OBJ_DIR) - rm -rf autom4te.cache - rm -f Makefile - rm -f config.cache config.log config.status config.h - -depend dep: - makedepend $(CPPFLAGS) -Y. $(SRCS) 2>/dev/null - -$(OBJ_DIR)/%.ho : %.c - $(HOST_CC) $(CPPFLAGS) $(DEFS) $(HOST_CFLAGS) -c $< -o $@ -$(OBJ_DIR)/%.ho : %.cpp - $(HOST_CXX) $(CPPFLAGS) $(DEFS) $(HOST_CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/slirp-%.o : ../slirp/%.c - $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(SLIRP_CFLAGS) -c $< -o $@ -$(OBJ_DIR)/%.o : %.c - $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@ -$(OBJ_DIR)/%.o : %.cpp - $(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/%.o : %.s - $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@ -$(OBJ_DIR)/prefs_editor_gtk.o: prefs_editor_gtk.cpp - $(CXX) -O2 -mno-cygwin -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@ - -# Windows resources -$(OBJ_DIR)/%.o: %.rc - $(WINDRES) --include-dir ../Windows -i $< -o $@ -$(OBJ_DIR)/build68k.exe: $(OBJ_DIR)/build68k.ho - $(HOST_CC) $(HOST_LDFLAGS) -o $@ $< -$(OBJ_DIR)/gencpu.exe: $(OBJ_DIR)/gencpu.ho $(OBJ_DIR)/readcpu.ho $(OBJ_DIR)/cpudefs.ho - $(HOST_CXX) $(HOST_LDFLAGS) -o $@ $(OBJ_DIR)/gencpu.ho $(OBJ_DIR)/readcpu.ho $(OBJ_DIR)/cpudefs.ho -$(OBJ_DIR)/gencomp.exe: $(OBJ_DIR)/gencomp.ho $(OBJ_DIR)/readcpu.ho $(OBJ_DIR)/cpudefs.ho - $(HOST_CXX) $(HOST_LDFLAGS) -o $@ $(OBJ_DIR)/gencomp.ho $(OBJ_DIR)/readcpu.ho $(OBJ_DIR)/cpudefs.ho - -cpudefs.cpp: $(OBJ_DIR)/build68k.exe ../uae_cpu/table68k - $(OBJ_DIR)/build68k.exe ../uae_cpu/table68k >cpudefs.cpp -cpustbl.cpp: cpuemu.cpp -cpustbl_nf.cpp: cpustbl.cpp -compstbl.cpp: compemu.cpp -cputbl.h: cpuemu.cpp -comptbl.h: compemu.cpp - -cpuemu.cpp: $(OBJ_DIR)/gencpu.exe - $(OBJ_DIR)/gencpu.exe - -compemu.cpp: $(OBJ_DIR)/gencomp.exe - $(OBJ_DIR)/gencomp.exe - -$(OBJ_DIR)/cpustbl_nf.o: cpustbl.cpp - $(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -DNOFLAGS -c $< -o $@ - -$(OBJ_DIR)/compemu_support.o: compemu_support.cpp comptbl.h - $(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@ - -$(OBJ_DIR)/cpuemu1.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_1 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu2.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_2 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu3.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_3 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu4.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_4 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu5.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_5 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu6.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_6 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu7.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_7 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu8.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_8 $(CXXFLAGS) -c $< -o $@ - -$(OBJ_DIR)/cpuemu1_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_1 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu2_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_2 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu3_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_3 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu4_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_4 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu5_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_5 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu6_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_6 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu7_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_7 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuemu8_nf.o: cpuemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_8 -DNOFLAGS $(CXXFLAGS) -c $< -o $@ - -$(OBJ_DIR)/compemu1.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_1 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu2.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_2 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu3.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_3 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu4.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_4 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu5.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_5 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu6.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_6 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu7.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_7 $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/compemu8.o: compemu.cpp - $(CXX) $(CPPFLAGS) $(DEFS) -DPART_8 $(CXXFLAGS) -c $< -o $@ - -#------------------------------------------------------------------------- -# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/BasiliskII/src/Windows/b2ether/driver/DEBUG.H b/BasiliskII/src/Windows/b2ether/driver/DEBUG.H deleted file mode 100755 index 0a12c737..00000000 --- a/BasiliskII/src/Windows/b2ether/driver/DEBUG.H +++ /dev/null @@ -1,43 +0,0 @@ -/* - * b2ether driver -- derived from DDK packet driver sample - * - * Basilisk II (C) 1997-1999 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if DBG - -#define IF_PACKETDEBUG(f) if (PacketDebugFlag & (f)) -extern ULONG PacketDebugFlag; - -#define PACKET_DEBUG_LOUD 0x00000001 // debugging info -#define PACKET_DEBUG_VERY_LOUD 0x00000002 // excessive debugging info - -#define PACKET_DEBUG_INIT 0x00000100 // init debugging info - -#define IF_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_LOUD ) { A } -#define IF_VERY_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) { A } -#define IF_INIT_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_INIT ) { A } - -#else - -#define IF_LOUD(A) -#define IF_VERY_LOUD(A) -#define IF_INIT_LOUD(A) - -#endif diff --git a/BasiliskII/src/Windows/b2ether/driver/MAKEFILE b/BasiliskII/src/Windows/b2ether/driver/MAKEFILE deleted file mode 100755 index 9c985f57..00000000 --- a/BasiliskII/src/Windows/b2ether/driver/MAKEFILE +++ /dev/null @@ -1,7 +0,0 @@ -# -# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source -# file to this component. This file merely indirects to the real make file -# that is shared by all the driver components of the Windows NT DDK -# - -!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/BasiliskII/src/Windows/b2ether/driver/OEMSETUP.INF b/BasiliskII/src/Windows/b2ether/driver/OEMSETUP.INF deleted file mode 100755 index 18a21ce7..00000000 --- a/BasiliskII/src/Windows/b2ether/driver/OEMSETUP.INF +++ /dev/null @@ -1,430 +0,0 @@ -[Identification] -OptionType = NetService - -[Options] -B2ETHER - -[FileConstants] -UtilityInf = "UTILITY.INF" -subroutineinf = "SUBROUTN.INF" -SoftwareType = "service" -Exit_Code = 0 -NetEventDLL = "%SystemRoot%\System32\netevent.dll" -Manufacturer = "Microsoft" -ProductMajorVersion = "4" -ProductMinorVersion = "0" -ProductVersion = $(ProductMajorVersion)"."$(ProductMinorVersion) - -ProductSoftwareName = "B2Ether" -ProductSoftwareImagePath = "\SystemRoot\System32\drivers\B2Ether.sys" - -NetRuleSoftwareType = "B2Ether lmNetService ndisTransport" -NetRuleSoftwareClass = {"rasCapableTransport ndisTransport"} - -NetRuleSoftwareUse = "service yes yes" -NetRuleSoftwareBindForm = """B2Ether"" yes yes simple" - -ProductKeyName = $(!NTN_SoftwareBase)"\"$(Manufacturer)"\"$(ProductSoftwareName)"\CurrentVersion" -ParamKeyName = $(!NTN_ServiceBase)"\"$(ProductSoftwareName)"\Parameters" - -[GeneralConstants] -from = "" -to = "" -ExitCodeOk = 0 -ExitCodeCancel = 1 -ExitCodeFatal = 2 -KeyNull = "" -MAXIMUM_ALLOWED = 33554432 -RegistryErrorIndex = NO_ERROR -KeyProduct = "" -KeyParameters = "" -TRUE = 1 -FALSE = 0 -NoTitle = 0 -ExitState = "Active" -OldVersionExisted = $(FALSE) -DriverPath = $(!STF_NTPATH)\drivers - -[date] -Now = {} ? $(!LIBHANDLE) GetSystemDate - -[Identify] -read-syms Identification -set Status = STATUS_SUCCESSFUL -set Identifier = $(OptionType) -set Media = #("Source Media Descriptions", 1, 1) -Return $(Status) $(Identifier) $(Media) - -[ReturnOptions] - set Status = STATUS_FAILED - set OptionList = {} - set OptionTextList = {} - set LanguageList = ^(LanguagesSupported, 1) - Ifcontains(i) $($0) in $(LanguageList) - goto returnoptions - else - set Status = STATUS_NOLANGUAGE - goto finish_ReturnOptions - endif -returnoptions = + - set OptionList = ^(Options, 1) - set OptionTextList = ^(OptionsText$($0), 1) - set Status = STATUS_SUCCESSFUL -finish_ReturnOptions = + - Return $(Status) $(OptionList) $(OptionTextList) - -[InstallOption] - set Option = $($1) - set SrcDir = $($2) - set AddCopy = $($3) - set DoCopy = $($4) - set DoConfig = $($5) - set LanguageList = ^(LanguagesSupported, 1) - Ifcontains(i) $($0) NOT-IN $(LanguageList) - Return STATUS_NOLANGUAGE - endif - Debug-Output "OEMSETUP.INF: STF_CWDDIR is: "$(!STF_CWDDIR) - Debug-Output "OEMSETUP.INF: STF_LANGUAGE is: "$(!STF_LANGUAGE) - set-subst LF = "\n" - read-syms GeneralConstants - read-syms FileConstants - read-syms DialogConstants$(!STF_LANGUAGE) - ifstr(i) $(!NTN_Origination) == "NCPA" - set Continue = $(OK) - endif - read-syms FileConstants$(!STF_LANGUAGE) - detect date - set-title $(FunctionTitle) - set to = Begin - set from = Begin - set CommonStatus = STATUS_SUCCESSFUL - EndWait -Begin = + - Ifstr(i) $(!NTN_InstallMode) == deinstall - set StartLabel = removeadapter - else-Ifstr(i) $(!NTN_InstallMode) == Update - set StartLabel = UpgradeSoftware - else-Ifstr(i) $(!NTN_InstallMode) == bind - set StartLabel = bindingadapter - else-Ifstr(i) $(!NTN_InstallMode) == configure - Shell $(UtilityInf),RegistryErrorString,CANNOT_CONFIGURE_SOFTWARE - ifint $($ShellCode) != $(!SHELL_CODE_OK) - Debug-Output "OEMSETUP.INF: ShellCode error: cannot get an error string." - goto ShellCodeError - endif - set Error = $($R0) - set from = end - set to = end - goto nonfatalinfo - else - set StartLabel = installadapter - endif - set RadioDefault = 2 - set RadioIn = {$(RadioDefault)} - set from = $(fatal) - set to = $(fatal) - goto $(StartLabel) -installadapter = + - OpenRegKey $(!REG_H_LOCAL) "" $(ProductKeyName) $(MAXIMUM_ALLOWED) KeyProduct - Ifstr $(KeyProduct) != $(KeyNull) - CloseRegKey $(KeyProduct) - Shell $(UtilityInf), VerExistedDlg, $(ProductSoftwareTitle),+ - $(ProductVersion) - ifint $($ShellCode) != $(!SHELL_CODE_OK) - Debug-Output "ShellCode error: cannot get an error string." - goto ShellCodeError - endif - goto end - endif - CloseRegKey $(KeyProduct) - goto installproduct -installproduct = + - StartWait - ifint $(OldVersionExisted) == $(FALSE) - Ifstr(i) $(DoCopy) == "YES" - Shell $(UtilityInf), DoAskSource, $(!STF_CWDDIR), $(SrcDir) YES - Ifint $($ShellCode) != $(!SHELL_CODE_OK) - Goto ShellCodeError - Else-Ifstr(i) $($R0) == STATUS_FAILED - Shell $(UtilityInf) RegistryErrorString "ASK_SOURCE_FAIL" - ifint $($ShellCode) != $(!SHELL_CODE_OK) - goto ShellCodeError - endif - set Error = $($R0) - Goto fatal - Else-Ifstr(i) $($R0) == STATUS_USERCANCEL - Goto successful - Endif - Set SrcDir = $($R1) - Endif - install "Install-Option" - ifstr(i) $(STF_INSTALL_OUTCOME) != STF_SUCCESS - Shell $(UtilityInf) RegistryErrorString "UNABLE_COPY_FILE" - ifint $($ShellCode) != $(!SHELL_CODE_OK) - goto ShellCodeError - endif - set Error = $($R0) - goto fatal - endif - set OEM_ABANDON_ON = TRUE - Shell $(UtilityInf), AddSoftwareComponent, $(Manufacturer), + - $(ProductSoftwareName), + - $(ProductSoftwareName), + - $(ProductSoftwareDisplayName), $(STF_CONTEXTINFNAME), + - $(ProductSoftwareImagePath), "kernel", "TDI", {}, "",+ - $(NetEventDLL) - set RegistryErrorIndex = $($R0) - Ifstr(i) $(RegistryErrorIndex) != NO_ERROR - EndWait - CloseRegKey $($R1) - CloseRegKey $($R2) - CloseRegKey $($R3) - CloseRegKey $($R4) - CloseRegKey $($R5) - goto fatalRegistry - endif - Set SoftProductKey = $($R1) - Set SoftNetRuleKey = $($R2) - Set SoftServiceKey = $($R3) - set KeyParameters = $($R4) - Set SoftLinkageKey = $($R5) - set NewValueList = {{SoftwareType,$(NoTitle),$(!REG_VT_SZ),$(SoftwareType)},+ - {MajorVersion,$(NoTitle),$(!REG_VT_DWORD),$(ProductMajorVersion)},+ - {MinorVersion,$(NoTitle),$(!REG_VT_DWORD),$(ProductMinorVersion)},+ - {Title,$(NoTitle),$(!REG_VT_SZ),$(ProductSoftwareTitle)},+ - {Description,$(NoTitle),$(!REG_VT_SZ),$(ProductSoftwareDescription)},+ - {ServiceName,$(NoTitle),$(!REG_VT_SZ),$(ProductSoftwareName)},+ - {InstallDate,$(NoTitle),$(!REG_VT_DWORD),*($(Now),1)}} - Shell $(UtilityInf), AddValueList, $(SoftProductKey), $(NewValueList) - set RegistryErrorIndex = $($R0) - Ifstr $(RegistryErrorIndex) != NO_ERROR - CloseRegKey $(SoftProductKey) - CloseRegKey $(SoftNetRuleKey) - CloseRegKey $(SoftServiceKey) - CloseRegKey $(SoftLinkageKey) - CloseRegKey $(KeyParameters) - goto fatalRegistry - endif - set NewValueList = {{type ,$(NoTitle),$(!REG_VT_SZ),$(NetRuleSoftwareType)}, + - {use ,$(NoTitle),$(!REG_VT_SZ),$(NetRuleSoftwareUse)}, + - {bindform,$(NoTitle),$(!REG_VT_SZ),$(NetRuleSoftwareBindForm)}, + - {InfOption,$(NoTitle),$(!REG_VT_SZ),$(Option)}} - Shell $(UtilityInf), AddValueList, $(SoftNetRuleKey), $(NewValueList) - set RegistryErrorIndex = $($R0) - Ifstr $(RegistryErrorIndex) != NO_ERROR - CloseRegKey $(SoftProductKey) - CloseRegKey $(SoftNetRuleKey) - CloseRegKey $(SoftServiceKey) - CloseRegKey $(SoftLinkageKey) - CloseRegKey $(KeyParameters) - goto fatalRegistry - endif - Set NewValueList = {{Author,$(NoTitle),$(!REG_VT_SZ),"Lauri Pesonen"}} - Shell $(UtilityInf), AddValueList, $(KeyParameters), $(NewValueList) - Ifstr $(RegistryErrorIndex) != NO_ERROR - CloseRegKey $(SoftProductKey) - CloseRegKey $(SoftNetRuleKey) - CloseRegKey $(SoftServiceKey) - CloseRegKey $(SoftLinkageKey) - goto fatalRegistry - endif - CloseRegKey $(SoftProductKey) - CloseRegKey $(SoftNetRuleKey) - CloseRegKey $(SoftServiceKey) - CloseRegKey $(SoftLinkageKey) - endif - goto writeparameters -writeparameters = + - CloseRegKey $(KeyParameters) - EndWait - goto successful -bindingadapter =+ - set Error = "Binding: Sorry, not yet implemented." - goto fatal -removeadapter = + - Shell $(UtilityInf), RemoveSoftwareComponent, $(Manufacturer), + - $(ProductSoftwareName) - ifint $($ShellCode) != $(!SHELL_CODE_OK) - Debug-Output "ShellCode error" - goto ShellCodeError - endif - set RegistryErrorIndex = $($R0) - Ifstr(i) $(RegistryErrorIndex) != NO_ERROR - goto fatalregistry - endif - goto end -UpgradeSoftware = + - ifstr(i) $(ProductKeyName) == $(!NTN_RegBase) - OpenRegKey $(!REG_H_LOCAL) "" $(ProductKeyName) $(MAXIMUM_ALLOWED) KeyProduct - Ifstr $(KeyProduct) != $(KeyNull) - GetRegValue $(KeyProduct),"MajorVersion", VersionInfo - set Version = *($(VersionInfo), 4) - Shell $(UtilityInf), GetInfFileNameFromRegistry, $(KeyProduct) - ifint $($ShellCode) != $(!SHELL_CODE_OK) - Debug-Output "ShellCode error" - goto ShellCodeError - endif - set !UG_Filename = $($R0) - ifstr(i) $(!UG_Filename) != "" - install "Install-Update" - ifstr(i) $(STF_INSTALL_OUTCOME) != STF_SUCCESS - goto fatal - endif - endif - SetRegValue $(KeyProduct) {MajorVersion,$(NoTitle),$(!REG_VT_SZ),$(ProductMajorVersion)} - SetRegValue $(KeyProduct) {MinorVersion,$(NoTitle),$(!REG_VT_SZ),$(ProductMinorVersion)} - ifint $(Version) != $(ProductVersion) - endif - CloseRegKey $(KeyProduct) - else - goto fatalregistry - endif - endif - goto end -successful = + - goto end -warning = + - Shell $(subroutineinf) SetupMessage, $(!STF_LANGUAGE), "WARNING", $(Error) - ifint $($ShellCode) != $(!SHELL_CODE_OK) - goto ShellCodeError - endif - ifstr(i) $($R1) == "OK" - goto $(to) - else-ifstr(i) $($R1) == "CANCEL" - goto $(from) - else - goto "end" - endif -nonfatalinfo = + - Set CommonStatus = STATUS_USERCANCEL - Set Severity = STATUS - goto nonfatalmsg -nonfatal = + - Set Severity = NONFATAL - goto nonfatalmsg -nonfatalmsg = + - ifstr(i) $(Error) == "" - Shell $(UtilityInf) RegistryErrorString "SETUP_FAIL" - ifint $($ShellCode) != $(!SHELL_CODE_OK) - goto ShellCodeError - endif - set Error = $($R0) - endif - Shell $(subroutineinf) SetupMessage, $(!STF_LANGUAGE), $(Severity), $(Error) - ifint $($ShellCode) != $(!SHELL_CODE_OK) - goto ShellCodeError - endif - ifstr(i) $($R1) == "OK" - goto $(from) - else - goto "end" - endif -fatalregistry = + - Shell $(UtilityInf) RegistryErrorString $(RegistryErrorIndex) - ifint $($ShellCode) != $(!SHELL_CODE_OK) - goto ShellCodeError - endif - set Error = $($R0) - goto fatal -fatal = + - ifstr(i) $(Error) == "" - Shell $(UtilityInf) RegistryErrorString "SETUP_FAIL" - ifint $($ShellCode) != $(!SHELL_CODE_OK) - goto ShellCodeError - endif - set Error = $($R0) - endif - Shell $(subroutineinf) SetupMessage, $(!STF_LANGUAGE), "FATAL", $(Error) - ifint $($ShellCode) != $(!SHELL_CODE_OK) - goto ShellCodeError - endif - goto setfailed -ShellCodeError = + - set DlgType = "MessageBox" - set STF_MB_TITLE = $(ShellCodeErrorTitle) - set STF_MB_TEXT = $(ShellCodeErrorText) - set STF_MB_TYPE = 1 - set STF_MB_ICON = 3 - set STF_MB_DEF = 1 - ui start "Error Message" - goto setfailed -setfailed = + - set CommonStatus = STATUS_FAILED - ifstr(i) $(OEM_ABANDON_ON) == TRUE - set OEM_ABANDON_ON = FALSE - goto removeadapter - endif - goto end -end = + - goto term -term = + - Return $(CommonStatus) - -[Install-Option] - set STF_VITAL = "" - ifstr(i) $(AddCopy) == "YES" - AddSectionFilesToCopyList Files-$(Option) $(SrcDir) $(!STF_WINDOWSSYSPATH)\drivers - AddSectionFilesToCopyList Files-App $(SrcDir) $(!STF_WINDOWSSYSPATH) - endif - ifstr(i) $(DoCopy) == "YES" - set !STF_NCPA_FLUSH_COPYLIST = TRUE - CopyFilesInCopyList - endif - ifstr(i) $(DoConfig) == "YES" - endif - Exit - -[Install-Update] - set STF_VITAL = "" - set STF_OVERWRITE = "VERIFYSOURCEOLDER" - AddSectionFilesToCopyList Files-$(Option) $(SrcDir) $(!STF_WINDOWSSYSPATH)\drivers - AddSectionFilesToCopyList Files-App $(SrcDir) $(!STF_WINDOWSSYSPATH) - AddSectionFilesToCopyList Files-Inf $(SrcDir) $(!STF_WINDOWSSYSPATH) - set !STF_NCPA_FLUSH_COPYLIST = TRUE - CopyFilesInCopyList - exit - -[Source Media Descriptions] -1 = "Windows NT Setup Disk #1" , TAGFILE = disk1 -2 = "Windows NT Setup CD-ROM Disk" , TAGFILE = disk2 - -[ProductType] -STF_PRODUCT = Winnt -STF_PLATFORM = I386 - -[Files-Inf] -2, oemsetup.inf, SIZE=1000, RENAME=$(!UG_Filename) - -[Files-B2Ether] -2,B2Ether.SYS , SIZE=999 - -[Files-App] - -[LanguagesSupported] -ENG - -[OptionsTextENG] -NDISPERF = "Basilisk II Ethernet Driver" - -[FileConstantsENG] -ProCaption = "Windows NT Setup" -ProCancel = "Cancel" -ProCancelMsg = "Windows NT Networking is not correctly installed. "+ - "Are you sure you want to cancel copying files?" -ProCancelCap = "Network Setup Message" -ProText1 = "Copying:" -ProText2 = "To:" -ProductSoftwareTitle = "Basilisk II Ethernet Driver" -ProductSoftwareDescription = "Adds ethernet capability to the Basilisk II Macintosh II emulator." -ProductSoftwareDisplayName = "Basilisk II Ethernet Driver" -FunctionTitle = $(ProductSoftwareTitle) -ShellCodeErrorTitle = "Error: "$(FunctionTitle) -ShellCodeErrorText = "Shell Code Error." - -[DialogConstantsENG] -Help = "&Help" -Exit = "Cancel" -OK = "OK" -HelpContext = "" -Continue = "Continue" -Cancel = "Cancel" diff --git a/BasiliskII/src/Windows/b2ether/driver/SOURCES b/BasiliskII/src/Windows/b2ether/driver/SOURCES deleted file mode 100755 index e7aa2866..00000000 --- a/BasiliskII/src/Windows/b2ether/driver/SOURCES +++ /dev/null @@ -1,15 +0,0 @@ -# MYMODE must be set - -TARGETNAME=b2ether -TARGETPATH=$(BASEDIR)\lib -TARGETTYPE=DRIVER - -TARGETLIBS=$(BASEDIR)\lib\*\$(DDKBUILDENV)\ndis.lib -INCLUDES=$(BASEDIR)\inc;$(BASEDIR)\src\network\inc;..\inc - -MSC_WARNING_LEVEL=/W3 /WX /FR /FAcs /D$(MYMODE) - -SOURCES=b2ether.c \ - b2ether_openclose.c \ - b2ether_read.c \ - b2ether_write.c diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether.c b/BasiliskII/src/Windows/b2ether/driver/b2ether.c deleted file mode 100755 index 1119224d..00000000 --- a/BasiliskII/src/Windows/b2ether/driver/b2ether.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * b2ether driver -- derived from DDK packet driver sample - * - * Basilisk II (C) 1997-1999 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "stdarg.h" -#include "ntddk.h" -#include "ntiologc.h" -#include "ndis.h" -#include "ntddpack.h" -#include "b2ether.h" - -#undef DBG -#define DBG 0 -#include "debug.h" - -NTSTATUS -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ); - - -NTSTATUS -PacketReadRegistry( - IN PWSTR *MacDriverName, - IN PWSTR *PacketDriverName, - IN PUNICODE_STRING RegistryPath - ); - - -NTSTATUS -PacketCreateSymbolicLink( - IN PUNICODE_STRING DeviceName, - IN BOOLEAN Create - ); - -NTSTATUS -PacketQueryRegistryRoutine( - IN PWSTR ValueName, - IN ULONG ValueType, - IN PVOID ValueData, - IN ULONG ValueLength, - IN PVOID Context, - IN PVOID EntryContext - ); - - -#if DBG -ULONG PacketDebugFlag = PACKET_DEBUG_LOUD; -#endif - - -PDEVICE_EXTENSION GlobalDeviceExtension; - - -NTSTATUS DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath -) -{ - NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar; - - UNICODE_STRING MacDriverName; - UNICODE_STRING UnicodeDeviceName; - - PDEVICE_OBJECT DeviceObject = NULL; - PDEVICE_EXTENSION DeviceExtension = NULL; - - NTSTATUS Status = STATUS_SUCCESS; - NTSTATUS ErrorCode = STATUS_SUCCESS; - NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver"); - - ULONG DevicesCreated=0; - - PWSTR BindString; - PWSTR ExportString; - - PWSTR BindStringSave; - PWSTR ExportStringSave; - - NDIS_HANDLE NdisProtocolHandle; - - IF_LOUD(DbgPrint("\n\nPacket: DriverEntry\n");) - - RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); - - ProtocolChar.MajorNdisVersion = 3; - ProtocolChar.MinorNdisVersion = 0; - ProtocolChar.Reserved = 0; - ProtocolChar.OpenAdapterCompleteHandler = PacketOpenAdapterComplete; - ProtocolChar.CloseAdapterCompleteHandler = PacketCloseAdapterComplete; - ProtocolChar.SendCompleteHandler = PacketSendComplete; - ProtocolChar.TransferDataCompleteHandler = PacketTransferDataComplete; - ProtocolChar.ResetCompleteHandler = PacketResetComplete; - ProtocolChar.RequestCompleteHandler = PacketRequestComplete; - ProtocolChar.ReceiveHandler = PacketReceiveIndicate; - ProtocolChar.ReceiveCompleteHandler = PacketReceiveComplete; - ProtocolChar.StatusHandler = PacketStatus; - ProtocolChar.StatusCompleteHandler = PacketStatusComplete; - ProtocolChar.Name = ProtoName; - - NdisRegisterProtocol( - &Status, - &NdisProtocolHandle, - &ProtocolChar, - sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); - - if (Status != NDIS_STATUS_SUCCESS) { - IF_LOUD(DbgPrint("Packet: Failed to register protocol with NDIS\n");) - return Status; - } - - // - // Set up the device driver entry points. - // - - DriverObject->MajorFunction[IRP_MJ_CREATE] = PacketOpen; - DriverObject->MajorFunction[IRP_MJ_CLOSE] = PacketClose; - DriverObject->MajorFunction[IRP_MJ_READ] = PacketRead; - DriverObject->MajorFunction[IRP_MJ_WRITE] = PacketWrite; - DriverObject->MajorFunction[IRP_MJ_CLEANUP] = PacketCleanup; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PacketIoControl; - - DriverObject->DriverUnload = PacketUnload; - - - // - // Get the name of the Packet driver and the name of the MAC driver - // to bind to from the registry - // - - Status=PacketReadRegistry( - &BindString, - &ExportString, - RegistryPath - ); - - if (Status != STATUS_SUCCESS) { - IF_LOUD(DbgPrint("Perf: Failed to read registry\n");) - goto RegistryError; - } - - BindStringSave = BindString; - ExportStringSave = ExportString; - - // create a device object for each entry - while (*BindString!= UNICODE_NULL && *ExportString!= UNICODE_NULL) { - - // Create a counted unicode string for both null terminated strings - RtlInitUnicodeString( - &MacDriverName, - BindString - ); - - RtlInitUnicodeString( - &UnicodeDeviceName, - ExportString - ); - - // Advance to the next string of the MULTI_SZ string - BindString += (MacDriverName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR); - - ExportString += (UnicodeDeviceName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR); - - IF_LOUD(DbgPrint("Packet: DeviceName=%ws MacName=%ws\n",UnicodeDeviceName.Buffer,MacDriverName.Buffer);) - - // Create the device object - Status = IoCreateDevice( - DriverObject, - sizeof(DEVICE_EXTENSION), - &UnicodeDeviceName, - FILE_DEVICE_PROTOCOL, - 0, - FALSE, - &DeviceObject - ); - - if (Status != STATUS_SUCCESS) { - IF_LOUD(DbgPrint("Perf: IoCreateDevice() failed:\n");) - break; - } - - DevicesCreated++; - - DeviceObject->Flags |= DO_DIRECT_IO; - DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; - DeviceExtension->DeviceObject = DeviceObject; - - // Save the the name of the MAC driver to open in the Device Extension - DeviceExtension->AdapterName=MacDriverName; - - if (DevicesCreated == 1) { - DeviceExtension->BindString = BindStringSave; - DeviceExtension->ExportString = ExportStringSave; - } - - DeviceExtension->NdisProtocolHandle=NdisProtocolHandle; - } - - if (DevicesCreated > 0) { - return STATUS_SUCCESS; - } - - ExFreePool(BindStringSave); - ExFreePool(ExportStringSave); - -RegistryError: - - NdisDeregisterProtocol( - &Status, - NdisProtocolHandle - ); - - Status=STATUS_UNSUCCESSFUL; - - return(Status); -} - - -VOID PacketUnload( IN PDRIVER_OBJECT DriverObject ) -{ - PDEVICE_OBJECT DeviceObject; - PDEVICE_OBJECT OldDeviceObject; - PDEVICE_EXTENSION DeviceExtension; - - NDIS_HANDLE NdisProtocolHandle; - NDIS_STATUS Status; - - IF_LOUD(DbgPrint("Packet: Unload\n");) - - DeviceObject = DriverObject->DeviceObject; - - while (DeviceObject != NULL) { - DeviceExtension = DeviceObject->DeviceExtension; - NdisProtocolHandle = DeviceExtension->NdisProtocolHandle; - if (DeviceExtension->BindString != NULL) { - ExFreePool(DeviceExtension->BindString); - } - if (DeviceExtension->ExportString != NULL) { - ExFreePool(DeviceExtension->ExportString); - } - OldDeviceObject=DeviceObject; - DeviceObject=DeviceObject->NextDevice; - IoDeleteDevice(OldDeviceObject); - } - - NdisDeregisterProtocol( &Status, NdisProtocolHandle ); -} - - -NTSTATUS PacketIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) -{ - POPEN_INSTANCE Open; - PIO_STACK_LOCATION IrpSp; - PLIST_ENTRY RequestListEntry; - PINTERNAL_REQUEST pRequest; - ULONG FunctionCode; - NDIS_STATUS Status; - - IF_LOUD(DbgPrint("Packet: IoControl\n");) - - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode; - - Open=IrpSp->FileObject->FsContext; - - RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList,&Open->RequestSpinLock); - if (RequestListEntry == NULL) { - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; - } - - pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement); - pRequest->Irp=Irp; - - IoMarkIrpPending(Irp); - Irp->IoStatus.Status = STATUS_PENDING; - - IF_LOUD(DbgPrint("Packet: Function code is %08lx buff size=%08lx %08lx\n",FunctionCode,IrpSp->Parameters.DeviceIoControl.InputBufferLength,IrpSp->Parameters.DeviceIoControl.OutputBufferLength);) - - if (FunctionCode == IOCTL_PROTOCOL_RESET) { - IF_LOUD(DbgPrint("Packet: IoControl - Reset request\n");) - ExInterlockedInsertTailList( - &Open->ResetIrpList, - &Irp->Tail.Overlay.ListEntry, - &Open->RequestSpinLock); - NdisReset( &Status, Open->AdapterHandle ); - - if (Status != NDIS_STATUS_PENDING) { - IF_LOUD(DbgPrint("Packet: IoControl - ResetComplte being called\n");) - PacketResetComplete( Open, Status ); - } - - } else { - // See if it is an Ndis request - PPACKET_OID_DATA OidData=Irp->AssociatedIrp.SystemBuffer; - - if (((FunctionCode == IOCTL_PROTOCOL_SET_OID) || (FunctionCode == IOCTL_PROTOCOL_QUERY_OID)) - && - (IrpSp->Parameters.DeviceIoControl.InputBufferLength == IrpSp->Parameters.DeviceIoControl.OutputBufferLength) - && - (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)) - && - (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)-1+OidData->Length)) { - - IF_LOUD(DbgPrint("Packet: IoControl: Request: Oid=%08lx, Length=%08lx\n",OidData->Oid,OidData->Length);) - - if (FunctionCode == IOCTL_PROTOCOL_SET_OID) { - pRequest->Request.RequestType=NdisRequestSetInformation; - pRequest->Request.DATA.SET_INFORMATION.Oid=OidData->Oid; - pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=OidData->Data; - pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=OidData->Length; - } else { - pRequest->Request.RequestType=NdisRequestQueryInformation; - pRequest->Request.DATA.QUERY_INFORMATION.Oid=OidData->Oid; - pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=OidData->Data; - pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=OidData->Length; - } - NdisRequest( - &Status, - Open->AdapterHandle, - &pRequest->Request - ); - } else { // buffer too small - Status=NDIS_STATUS_FAILURE; - pRequest->Request.DATA.SET_INFORMATION.BytesRead=0; - pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten=0; - } - - if (Status != NDIS_STATUS_PENDING) { - IF_LOUD(DbgPrint("Packet: Calling RequestCompleteHandler\n");) - PacketRequestComplete( - Open, - &pRequest->Request, - Status - ); - } - } - return(STATUS_PENDING); -} - - -VOID PacketRequestComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_REQUEST NdisRequest, - IN NDIS_STATUS Status -) -{ - POPEN_INSTANCE Open; - PIO_STACK_LOCATION IrpSp; - PIRP Irp; - PINTERNAL_REQUEST pRequest; - UINT FunctionCode; - - PPACKET_OID_DATA OidData; - - IF_LOUD(DbgPrint("Packet: RequestComplete\n");) - - Open= (POPEN_INSTANCE)ProtocolBindingContext; - - pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request); - Irp=pRequest->Irp; - - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode; - - OidData=Irp->AssociatedIrp.SystemBuffer; - - if (FunctionCode == IOCTL_PROTOCOL_SET_OID) { - OidData->Length=pRequest->Request.DATA.SET_INFORMATION.BytesRead; - } else { - if (FunctionCode == IOCTL_PROTOCOL_QUERY_OID) { - OidData->Length=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten; - } - } - - Irp->IoStatus.Information=IrpSp->Parameters.DeviceIoControl.InputBufferLength; - - ExInterlockedInsertTailList( - &Open->RequestList, - &pRequest->ListElement, - &Open->RequestSpinLock); - - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); -} - - -VOID PacketStatus( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status, - IN PVOID StatusBuffer, - IN UINT StatusBufferSize -) -{ - IF_LOUD(DbgPrint("Packet: Status Indication\n");) -} - - -VOID PacketStatusComplete( IN NDIS_HANDLE ProtocolBindingContext ) -{ - IF_LOUD(DbgPrint("Packet: StatusIndicationComplete\n");) -} - - -#if 0 -NTSTATUS PacketCreateSymbolicLink( - IN PUNICODE_STRING DeviceName, - IN BOOLEAN Create -) -{ - UNICODE_STRING UnicodeDosDeviceName; - NTSTATUS Status; - - if (DeviceName->Length < sizeof(L"\\Device\\")) { - return STATUS_UNSUCCESSFUL; - } - - RtlInitUnicodeString(&UnicodeDosDeviceName,NULL); - UnicodeDosDeviceName.MaximumLength=DeviceName->Length+sizeof(L"\\DosDevices")+sizeof(UNICODE_NULL); - UnicodeDosDeviceName.Buffer=ExAllocatePool( - NonPagedPool, - UnicodeDosDeviceName.MaximumLength - ); - if (UnicodeDosDeviceName.Buffer != NULL) { - RtlZeroMemory( UnicodeDosDeviceName.Buffer, UnicodeDosDeviceName.MaximumLength ); - RtlAppendUnicodeToString( &UnicodeDosDeviceName, L"\\DosDevices\\" ); - RtlAppendUnicodeToString( &UnicodeDosDeviceName, (DeviceName->Buffer+(sizeof("\\Device"))) ); - IF_LOUD(DbgPrint("Packet: DosDeviceName is %ws\n",UnicodeDosDeviceName.Buffer);) - if (Create) { - Status=IoCreateSymbolicLink(&UnicodeDosDeviceName,DeviceName); - } else { - Status=IoDeleteSymbolicLink(&UnicodeDosDeviceName); - } - ExFreePool(UnicodeDosDeviceName.Buffer); - } - return Status; -} -#endif - - -NTSTATUS PacketReadRegistry( - IN PWSTR *MacDriverName, - IN PWSTR *PacketDriverName, - IN PUNICODE_STRING RegistryPath -) -{ - NTSTATUS Status; - RTL_QUERY_REGISTRY_TABLE ParamTable[5]; - PWSTR Bind = L"Bind"; // LAURI: \Device\W30NT1 - PWSTR Export = L"Export"; // \Device\appletalk\W30NT1\0\0 - PWSTR Parameters = L"Parameters"; - PWSTR Linkage = L"Linkage"; - PWCHAR Path; - - Path=ExAllocatePool( PagedPool, RegistryPath->Length+sizeof(WCHAR) ); - - if (!Path) return STATUS_INSUFFICIENT_RESOURCES; - - RtlZeroMemory( Path, RegistryPath->Length+sizeof(WCHAR) ); - RtlCopyMemory( Path, RegistryPath->Buffer, RegistryPath->Length ); - - IF_LOUD(DbgPrint("Packet: Reg path is %ws\n",RegistryPath->Buffer);) - - RtlZeroMemory( ParamTable, sizeof(ParamTable) ); - - // change to the parmeters key - ParamTable[0].QueryRoutine = NULL; - ParamTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY; - ParamTable[0].Name = Parameters; - - // change to the linkage key - ParamTable[1].QueryRoutine = NULL; - ParamTable[1].Flags = RTL_QUERY_REGISTRY_SUBKEY; - ParamTable[1].Name = Linkage; - - // Get the name of the mac driver we should bind to - ParamTable[2].QueryRoutine = PacketQueryRegistryRoutine; - ParamTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND; - - ParamTable[2].Name = Bind; - ParamTable[2].EntryContext = (PVOID)MacDriverName; - ParamTable[2].DefaultType = REG_MULTI_SZ; - - // Get the name that we should use for the driver object - ParamTable[3].QueryRoutine = PacketQueryRegistryRoutine; - ParamTable[3].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND; - - ParamTable[3].Name = Export; - ParamTable[3].EntryContext = (PVOID)PacketDriverName; - ParamTable[3].DefaultType = REG_MULTI_SZ; - - Status=RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, - Path, - ParamTable, - NULL, - NULL - ); - - ExFreePool(Path); - - return Status; -} - - -NTSTATUS PacketQueryRegistryRoutine( - IN PWSTR ValueName, - IN ULONG ValueType, - IN PVOID ValueData, - IN ULONG ValueLength, - IN PVOID Context, - IN PVOID EntryContext - ) - -{ - PUCHAR Buffer; - - IF_LOUD(DbgPrint("Perf: QueryRegistryRoutine\n");) - - if (ValueType != REG_MULTI_SZ) { - return STATUS_OBJECT_NAME_NOT_FOUND; - } - - Buffer=ExAllocatePool(NonPagedPool,ValueLength); - if(!Buffer) return STATUS_INSUFFICIENT_RESOURCES; - - RtlCopyMemory( Buffer, ValueData, ValueLength ); - - *((PUCHAR *)EntryContext)=Buffer; - - return STATUS_SUCCESS; -} diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether.h b/BasiliskII/src/Windows/b2ether/driver/b2ether.h deleted file mode 100755 index 50080b74..00000000 --- a/BasiliskII/src/Windows/b2ether/driver/b2ether.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * b2ether driver -- derived from DDK packet driver sample - * - * Basilisk II (C) 1997-1999 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define MAX_REQUESTS 4 - -typedef struct _INTERNAL_REQUEST { - LIST_ENTRY ListElement; - PIRP Irp; - NDIS_REQUEST Request; -} INTERNAL_REQUEST, *PINTERNAL_REQUEST; - -// Port device extension. -typedef struct _DEVICE_EXTENSION { - PDEVICE_OBJECT DeviceObject; - NDIS_HANDLE NdisProtocolHandle; - NDIS_STRING AdapterName; - PWSTR BindString; - PWSTR ExportString; -} DEVICE_EXTENSION, *PDEVICE_EXTENSION; - -typedef struct _OPEN_INSTANCE { - PDEVICE_EXTENSION DeviceExtension; - NDIS_HANDLE AdapterHandle; - NDIS_HANDLE PacketPool; - KSPIN_LOCK RcvQSpinLock; - LIST_ENTRY RcvList; - PIRP OpenCloseIrp; - KSPIN_LOCK RequestSpinLock; - LIST_ENTRY RequestList; - LIST_ENTRY ResetIrpList; - INTERNAL_REQUEST Requests[MAX_REQUESTS]; -} OPEN_INSTANCE, *POPEN_INSTANCE; - -typedef struct _PACKET_RESERVED { - LIST_ENTRY ListElement; - PIRP Irp; - PMDL pMdl; -} PACKET_RESERVED, *PPACKET_RESERVED; - - -#define ETHERNET_HEADER_LENGTH 14 -#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) -#define TRANSMIT_PACKETS 16 - - -VOID -PacketOpenAdapterComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status, - IN NDIS_STATUS OpenErrorStatus - ); - -VOID -PacketCloseAdapterComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status - ); - - -NDIS_STATUS -PacketReceiveIndicate( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_HANDLE MacReceiveContext, - IN PVOID HeaderBuffer, - IN UINT HeaderBufferSize, - IN PVOID LookAheadBuffer, - IN UINT LookaheadBufferSize, - IN UINT PacketSize - ); - -VOID -PacketReceiveComplete( - IN NDIS_HANDLE ProtocolBindingContext - ); - - -VOID -PacketRequestComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_REQUEST pRequest, - IN NDIS_STATUS Status - ); - -VOID -PacketSendComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET pPacket, - IN NDIS_STATUS Status - ); - - -VOID -PacketResetComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status - ); - - -VOID -PacketStatus( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status, - IN PVOID StatusBuffer, - IN UINT StatusBufferSize - ); - - -VOID -PacketStatusComplete( - IN NDIS_HANDLE ProtocolBindingContext - ); - -VOID -PacketTransferDataComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET Packet, - IN NDIS_STATUS Status, - IN UINT BytesTransferred - ); - - -VOID -PacketRemoveReference( - IN PDEVICE_EXTENSION DeviceExtension - ); - - -NTSTATUS -PacketCleanup( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP FlushIrp - ); - - -NTSTATUS -PacketShutdown( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -VOID -PacketUnload( - IN PDRIVER_OBJECT DriverObject - ); - - - -NTSTATUS -PacketOpen( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -NTSTATUS -PacketClose( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -NTSTATUS -PacketWrite( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -NTSTATUS -PacketRead( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -NTSTATUS -PacketIoControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether_openclose.c b/BasiliskII/src/Windows/b2ether/driver/b2ether_openclose.c deleted file mode 100755 index 6541993d..00000000 --- a/BasiliskII/src/Windows/b2ether/driver/b2ether_openclose.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * b2ether driver -- derived from DDK packet driver sample - * - * Basilisk II (C) 1997-1999 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//#include "stdarg.h" -#include "ntddk.h" -#include "ntiologc.h" -#include "ndis.h" -#include "b2ether.h" - -#undef DBG -#define DBG 0 -#include "debug.h" - -static UINT Medium; -static NDIS_MEDIUM MediumArray=NdisMedium802_3; - -NTSTATUS PacketOpen( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) -/* - This is the dispatch routine for create/open and close requests. - These requests complete successfully. -*/ -{ - PDEVICE_EXTENSION DeviceExtension; - - POPEN_INSTANCE Open; - - PIO_STACK_LOCATION IrpSp; - - NDIS_STATUS Status; - NDIS_STATUS ErrorStatus; - - UINT i; - - IF_LOUD(DbgPrint("Packet: OpenAdapter\n");) - - DeviceExtension = DeviceObject->DeviceExtension; - - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - Open = ExAllocatePool(NonPagedPool,sizeof(OPEN_INSTANCE)); - if (Open==NULL) { - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlZeroMemory( Open, sizeof(OPEN_INSTANCE) ); - - // Save or open here - IrpSp->FileObject->FsContext = Open; - Open->DeviceExtension = DeviceExtension; - Open->OpenCloseIrp = Irp; - - // Allocate a packet pool for our xmit and receive packets - NdisAllocatePacketPool( - &Status, - &Open->PacketPool, - TRANSMIT_PACKETS, - sizeof(PACKET_RESERVED)); - - if (Status != NDIS_STATUS_SUCCESS) { - IF_LOUD(DbgPrint("Packet: Failed to allocate packet pool\n");) - ExFreePool(Open); - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - - // list to hold irp's want to reset the adapter - InitializeListHead(&Open->ResetIrpList); - - // Initialize list for holding pending read requests - KeInitializeSpinLock(&Open->RcvQSpinLock); - InitializeListHead(&Open->RcvList); - - // Initialize the request list - KeInitializeSpinLock(&Open->RequestSpinLock); - InitializeListHead(&Open->RequestList); - - // link up the request stored in our open block - for ( i=0; iRequestList, - &Open->Requests[i].ListElement, - &Open->RequestSpinLock); - - } - - IoMarkIrpPending(Irp); - Irp->IoStatus.Status = STATUS_PENDING; - - // Try to open the MAC - NdisOpenAdapter( - &Status, - &ErrorStatus, - &Open->AdapterHandle, - &Medium, - &MediumArray, - 1, - DeviceExtension->NdisProtocolHandle, - Open, - &DeviceExtension->AdapterName, - 0, - NULL); - - if (Status != NDIS_STATUS_PENDING) { - PacketOpenAdapterComplete( Open, Status, NDIS_STATUS_SUCCESS ); - } - return(STATUS_PENDING); -} - - -VOID PacketOpenAdapterComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status, - IN NDIS_STATUS OpenErrorStatus -) -{ - PIRP Irp; - POPEN_INSTANCE Open; - - IF_LOUD(DbgPrint("Packet: OpenAdapterComplete\n");) - - Open = (POPEN_INSTANCE)ProtocolBindingContext; - - Irp = Open->OpenCloseIrp; - - if (Status != NDIS_STATUS_SUCCESS) { - IF_LOUD(DbgPrint("Packet: OpenAdapterComplete-FAILURE\n");) - NdisFreePacketPool(Open->PacketPool); - ExFreePool(Open); - } - - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return; -} - - -NTSTATUS PacketClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) -{ - POPEN_INSTANCE Open; - NDIS_STATUS Status; - PIO_STACK_LOCATION IrpSp; - - IF_LOUD(DbgPrint("Packet: CloseAdapter\n");) - - IrpSp = IoGetCurrentIrpStackLocation(Irp); - Open = IrpSp->FileObject->FsContext; - Open->OpenCloseIrp =Irp; - - IoMarkIrpPending(Irp); - Irp->IoStatus.Status = STATUS_PENDING; - - NdisCloseAdapter( &Status, Open->AdapterHandle ); - - if (Status != NDIS_STATUS_PENDING) { - PacketCloseAdapterComplete( Open, Status ); - } - - return(STATUS_PENDING); -} - -VOID PacketCloseAdapterComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status -) -{ - POPEN_INSTANCE Open; - PIRP Irp; - - IF_LOUD(DbgPrint("Packet: CloseAdapterComplete\n");) - - Open = (POPEN_INSTANCE)ProtocolBindingContext; - Irp = Open->OpenCloseIrp; - - NdisFreePacketPool(Open->PacketPool); - ExFreePool(Open); - - Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); -} - - -NTSTATUS PacketCleanup( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP FlushIrp -) -{ - POPEN_INSTANCE Open; - PIO_STACK_LOCATION IrpSp; - PLIST_ENTRY PacketListEntry; - PNDIS_PACKET pPacket; - NDIS_STATUS Status; - - IF_LOUD(DbgPrint("Packet: Cleanup\n");) - - IrpSp = IoGetCurrentIrpStackLocation(FlushIrp); - - Open=IrpSp->FileObject->FsContext; - - IoMarkIrpPending(FlushIrp); - FlushIrp->IoStatus.Status = STATUS_PENDING; - - // - // The open instance of the device is about to close - // We need to complete all pending Irp's - // First we complete any pending read requests - // - while ((PacketListEntry=ExInterlockedRemoveHeadList( - &Open->RcvList, - &Open->RcvQSpinLock - )) != NULL) { - - IF_LOUD(DbgPrint("Packet: CleanUp - Completeing read\n");) - - pPacket=CONTAINING_RECORD(PacketListEntry,NDIS_PACKET,ProtocolReserved); - - // complete normally - PacketTransferDataComplete( - Open, - pPacket, - NDIS_STATUS_SUCCESS, - 0 - ); - } - - // IoMarkIrpPending(FlushIrp); - // FlushIrp->IoStatus.Status = STATUS_PENDING; - - // We now place the Irp on the Reset list - ExInterlockedInsertTailList( - &Open->ResetIrpList, - &FlushIrp->Tail.Overlay.ListEntry, - &Open->RequestSpinLock); - - // Now reset the adapter, the mac driver will complete any - // pending requests we have made to it. - NdisReset( &Status, Open->AdapterHandle ); - - if (Status != NDIS_STATUS_PENDING) { - IF_LOUD(DbgPrint("Packet: Cleanup - ResetComplte being called\n");) - PacketResetComplete( Open, Status ); - } - - return(STATUS_PENDING); -} - - -VOID PacketResetComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status -) -{ - POPEN_INSTANCE Open; - PIRP Irp; - PLIST_ENTRY ResetListEntry; - - IF_LOUD(DbgPrint("Packet: PacketResetComplte\n");) - - Open = (POPEN_INSTANCE)ProtocolBindingContext; - - // remove the reset IRP from the list - ResetListEntry=ExInterlockedRemoveHeadList( - &Open->ResetIrpList, - &Open->RequestSpinLock - ); - -#if DBG - if (ResetListEntry == NULL) { - DbgBreakPoint(); - return; - } -#endif - - Irp = CONTAINING_RECORD(ResetListEntry,IRP,Tail.Overlay.ListEntry); - Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - IF_LOUD(DbgPrint("Packet: PacketResetComplte exit\n");) -} diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether_read.c b/BasiliskII/src/Windows/b2ether/driver/b2ether_read.c deleted file mode 100755 index 87ade9a9..00000000 --- a/BasiliskII/src/Windows/b2ether/driver/b2ether_read.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * b2ether driver -- derived from DDK packet driver sample - * - * Basilisk II (C) 1997-1999 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "stdarg.h" -#include "ntddk.h" -#include "ntiologc.h" -#include "ndis.h" -#include "b2ether.h" - -#undef DBG -#define DBG 0 -#include "debug.h" - - -NTSTATUS PacketRead( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp -) -{ - POPEN_INSTANCE Open; - PIO_STACK_LOCATION IrpSp; - PNDIS_PACKET pPacket; - PMDL pMdl; - NDIS_STATUS Status; - - IF_LOUD(DbgPrint("Packet: Read\n");) - - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - Open = IrpSp->FileObject->FsContext; - - if (IrpSp->Parameters.Read.Length < ETHERNET_HEADER_LENGTH) { - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; - } - - pMdl=IoAllocateMdl( - MmGetMdlVirtualAddress(Irp->MdlAddress), - MmGetMdlByteCount(Irp->MdlAddress), - FALSE, - FALSE, - NULL - ); - - if (!pMdl) { - IF_LOUD(DbgPrint("Packet: Read-Failed to allocate Mdl\n");) - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; - } - - IoBuildPartialMdl( - Irp->MdlAddress, - pMdl, - ((PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress))+ETHERNET_HEADER_LENGTH, - 0 - ); - pMdl->Next = NULL; - - // - // Try to get a packet from our list of free ones - // - NdisAllocatePacket( &Status, &pPacket, Open->PacketPool ); - - if (Status != NDIS_STATUS_SUCCESS) { - IF_LOUD(DbgPrint("Packet: Read- No free packets\n");) - IoFreeMdl(pMdl); - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; - } - - // - // Get a pointer to the packet itself - // - RESERVED(pPacket)->Irp = Irp; - RESERVED(pPacket)->pMdl = pMdl; - - IoMarkIrpPending(Irp); - Irp->IoStatus.Status = STATUS_PENDING; - - // - // Attach our new MDL to the packet - // - NdisChainBufferAtFront(pPacket,pMdl); - - - // - // Put this packet in a list of pending reads. - // The receive indication handler will attemp to remove packets - // from this list for use in transfer data calls - // - ExInterlockedInsertTailList( - &Open->RcvList, - &RESERVED(pPacket)->ListElement, - &Open->RcvQSpinLock); - - return(STATUS_PENDING); -} - - -NDIS_STATUS -PacketReceiveIndicate ( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_HANDLE MacReceiveContext, - IN PVOID HeaderBuffer, - IN UINT HeaderBufferSize, - IN PVOID LookAheadBuffer, - IN UINT LookaheadBufferSize, - IN UINT PacketSize - ) - -{ - POPEN_INSTANCE Open; - PIO_STACK_LOCATION IrpSp; - PIRP Irp; - PLIST_ENTRY PacketListEntry; - PNDIS_PACKET pPacket; - ULONG SizeToTransfer; - NDIS_STATUS Status; - UINT BytesTransfered; - ULONG BufferLength; - PPACKET_RESERVED Reserved; - - IF_LOUD(DbgPrint("Packet: ReceiveIndicate\n");) - - Open = (POPEN_INSTANCE)ProtocolBindingContext; - - if (HeaderBufferSize > ETHERNET_HEADER_LENGTH) { - return NDIS_STATUS_NOT_ACCEPTED; // NDIS_STATUS_SUCCESS; - } - - // See if there are any pending read that we can satisfy - PacketListEntry=ExInterlockedRemoveHeadList( - &Open->RcvList, - &Open->RcvQSpinLock - ); - - if (PacketListEntry == NULL) { - IF_LOUD(DbgPrint("Packet: ReceiveIndicate dropped a packet\n");) - return NDIS_STATUS_NOT_ACCEPTED; - } - - Reserved=CONTAINING_RECORD(PacketListEntry,PACKET_RESERVED,ListElement); - pPacket=CONTAINING_RECORD(Reserved,NDIS_PACKET,ProtocolReserved); - - Irp=RESERVED(pPacket)->Irp; - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - // This is the length of our partial MDL - BufferLength = IrpSp->Parameters.Read.Length-ETHERNET_HEADER_LENGTH; - - SizeToTransfer = (PacketSize < BufferLength) ? PacketSize : BufferLength; - - // copy the ethernet header into the actual readbuffer - NdisMoveMappedMemory( - MmGetSystemAddressForMdl(Irp->MdlAddress), - HeaderBuffer, - HeaderBufferSize - ); - - // Call the Mac to transfer the packet - NdisTransferData( - &Status, - Open->AdapterHandle, - MacReceiveContext, - 0, - SizeToTransfer, - pPacket, - &BytesTransfered); - - if (Status != NDIS_STATUS_PENDING) { - PacketTransferDataComplete( Open, pPacket, Status, BytesTransfered ); - } - - return NDIS_STATUS_SUCCESS; -} - -VOID PacketTransferDataComplete ( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET pPacket, - IN NDIS_STATUS Status, - IN UINT BytesTransfered -) -{ - PIO_STACK_LOCATION IrpSp; - POPEN_INSTANCE Open; - PIRP Irp; - PMDL pMdl; - - IF_LOUD(DbgPrint("Packet: TransferDataComplete\n");) - - Open = (POPEN_INSTANCE)ProtocolBindingContext; - Irp = RESERVED(pPacket)->Irp; - IrpSp = IoGetCurrentIrpStackLocation(Irp); - pMdl = RESERVED(pPacket)->pMdl; - - // Free the MDL that we allocated - IoFreeMdl(pMdl); - - // recycle the packet - NdisReinitializePacket(pPacket); - - // Put the packet on the free queue - NdisFreePacket(pPacket); - - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = BytesTransfered+ETHERNET_HEADER_LENGTH; - IoCompleteRequest(Irp, IO_NO_INCREMENT); -} - - -VOID PacketReceiveComplete( IN NDIS_HANDLE ProtocolBindingContext ) -{ -} diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether_write.c b/BasiliskII/src/Windows/b2ether/driver/b2ether_write.c deleted file mode 100755 index 4b6684ff..00000000 --- a/BasiliskII/src/Windows/b2ether/driver/b2ether_write.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * b2ether driver -- derived from DDK packet driver sample - * - * Basilisk II (C) 1997-1999 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "stdarg.h" -#include "ntddk.h" -#include "ntiologc.h" -#include "ndis.h" -#include "b2ether.h" - -#undef DBG -#define DBG 0 -#include "debug.h" - - -NTSTATUS PacketWrite( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp -) -{ - POPEN_INSTANCE Open; - PIO_STACK_LOCATION IrpSp; - PNDIS_PACKET pPacket; - - NDIS_STATUS Status; - - IF_LOUD(DbgPrint("Packet: SendAdapter\n");) - - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - Open = IrpSp->FileObject->FsContext; - - // Try to get a packet from our list of free ones - NdisAllocatePacket( &Status, &pPacket, Open->PacketPool ); - if (Status != NDIS_STATUS_SUCCESS) { - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; - } - - RESERVED(pPacket)->Irp=Irp; - - // Attach the writes buffer to the packet - NdisChainBufferAtFront(pPacket,Irp->MdlAddress); - - IoMarkIrpPending(Irp); - Irp->IoStatus.Status = STATUS_PENDING; - - // Call the MAC - NdisSend( &Status, Open->AdapterHandle, pPacket ); - - if (Status != NDIS_STATUS_PENDING) { - PacketSendComplete( Open, pPacket, Status ); - } - - return(STATUS_PENDING); -} - - -VOID PacketSendComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET pPacket, - IN NDIS_STATUS Status -) -{ - PIRP Irp; - - IF_LOUD(DbgPrint("Packet: SendComplete\n");) - - Irp = RESERVED(pPacket)->Irp; - - // recyle the packet - NdisReinitializePacket(pPacket); - - // Put the packet back on the free list - NdisFreePacket(pPacket); - - Irp->IoStatus.Status = Status; - - // a known bug, but I don't need this information - Irp->IoStatus.Information = 0; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); -} diff --git a/BasiliskII/src/Windows/b2ether/inc/b2ether_hl.h b/BasiliskII/src/Windows/b2ether/inc/b2ether_hl.h deleted file mode 100755 index d5e87655..00000000 --- a/BasiliskII/src/Windows/b2ether/inc/b2ether_hl.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * b2ether_hl.h - Win32 ethernet driver high-level interface - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _B2_ETHER_HL_ -#define _B2_ETHER_HL_ - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define ETH_802_3_ADDRESS_LENGTH 6 -#define MAX_LINK_NAME_LENGTH 124 - -typedef struct _ADAPTER { - HANDLE hFile; - TCHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; -} ADAPTER, *LPADAPTER; - -typedef struct _PACKET { - OVERLAPPED OverLapped; - PVOID Buffer; - UINT Length; - ULONG BytesReceived; - BOOL bIoComplete; - BOOL free; - struct _PACKET *next; -} PACKET, *LPPACKET; - - - -BOOLEAN StartPacketDriver( - LPCTSTR ServiceName -); - -LPADAPTER PacketOpenAdapter( - LPCTSTR AdapterName, - int16 mode -); - -VOID PacketCloseAdapter( - LPADAPTER lpAdapter -); - -LPPACKET PacketAllocatePacket( - LPADAPTER AdapterObject, - UINT Length -); - -VOID PacketFreePacket( - LPPACKET lpPacket -); - -BOOLEAN PacketSendPacket( - LPADAPTER AdapterObject, - LPPACKET lpPacket, - BOOLEAN Sync, - BOOLEAN RecyclingAllowed -); - -BOOLEAN PacketGetAddress( - LPADAPTER AdapterObject, - PUCHAR AddressBuffer, - PUINT Length -); - -BOOLEAN PacketReceivePacket( - LPADAPTER AdapterObject, - LPPACKET lpPacket, - BOOLEAN Sync -); - -BOOLEAN PacketSetFilter( LPADAPTER AdapterObject, ULONG Filter ); -BOOLEAN PacketGetMAC( LPADAPTER AdapterObject, LPBYTE address, BOOL permanent ); -BOOLEAN PacketAddMulticast( LPADAPTER AdapterObject, LPBYTE address ); -BOOLEAN PacketDelMulticast( LPADAPTER AdapterObject, LPBYTE address ); - -ULONG PacketGetAdapterNames( LPADAPTER lpAdapter, LPTSTR pStr, PULONG BufferSize ); - -// callbacks -void recycle_write_packet( LPPACKET Packet ); - -VOID CALLBACK packet_read_completion( - DWORD dwErrorCode, - DWORD dwNumberOfBytesTransfered, - LPOVERLAPPED lpOverlapped -); - - -#ifdef __cplusplus -} -#endif - - -#endif // _B2_ETHER_HL_ diff --git a/BasiliskII/src/Windows/b2ether/inc/ntddpack.h b/BasiliskII/src/Windows/b2ether/inc/ntddpack.h deleted file mode 100755 index 62af4f3f..00000000 --- a/BasiliskII/src/Windows/b2ether/inc/ntddpack.h +++ /dev/null @@ -1,32 +0,0 @@ -// #include - -#ifndef __NTDDPACKET -#define __NTDDPACKET 1 - -// #include - -#define MAX_LINK_NAME_LENGTH 124 - -#pragma pack(1) -typedef struct _PACKET_OID_DATA { - ULONG Oid; - ULONG Length; - UCHAR Data[1]; -} ATTRIBUTE_PACKED PACKET_OID_DATA, *PPACKET_OID_DATA; -#pragma pack() - - -#define FILE_DEVICE_PROTOCOL 0x8000 - - - -#define IOCTL_PROTOCOL_SET_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 0 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_QUERY_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 1 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_RESET CTL_CODE(FILE_DEVICE_PROTOCOL, 2 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_READ CTL_CODE(FILE_DEVICE_PROTOCOL, 3 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_WRITE CTL_CODE(FILE_DEVICE_PROTOCOL, 4 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_MACNAME CTL_CODE(FILE_DEVICE_PROTOCOL, 5 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_SELECT_BY_NAME CTL_CODE(FILE_DEVICE_PROTOCOL, 6 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_ENUM_ADAPTERS CTL_CODE(FILE_DEVICE_PROTOCOL, 7 , METHOD_BUFFERED, FILE_ANY_ACCESS) - -#endif diff --git a/BasiliskII/src/Windows/b2ether/multiopt.h b/BasiliskII/src/Windows/b2ether/multiopt.h deleted file mode 100755 index d924a199..00000000 --- a/BasiliskII/src/Windows/b2ether/multiopt.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * multiopt.h - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -enum { - ETHER_MULTICAST_MAC, - ETHER_MULTICAST_ALL, - ETHER_MULTICAST_PROMISCUOUS -}; diff --git a/BasiliskII/src/Windows/b2ether/nt5/B2Win2k.inf b/BasiliskII/src/Windows/b2ether/nt5/B2Win2k.inf deleted file mode 100644 index d8726610..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/B2Win2k.inf +++ /dev/null @@ -1,80 +0,0 @@ -[version] -Signature = "$Windows NT$" -Class = NetTrans -ClassGUID = {4d36e975-e325-11ce-bfc1-08002be10318} -Provider = %Msft% -DriverVer = 12/05/1999,5.00.2128 - -[Manufacturer] -%Msft%=MSFT - -[MSFT] -%B2ETHER_Desc%=Install, MS_B2ETHER - -;------------------------------------------------------------------------- -; Installation Section -;------------------------------------------------------------------------- -[Install] -AddReg=Inst_Ndi -Characteristics=0 ; Has no characterstic -CopyFiles=CpyFiles_Sys - -;------------------------------------------------------------------------- -; Ndi installation support -;------------------------------------------------------------------------- -[Inst_Ndi] -HKR,Ndi,Service,,"B2Ether" -HKR,Ndi,HelpText,,%B2ETHER_HelpText% -HKR, Ndi\Interfaces, UpperRange,, noupper -HKR,"Ndi\Interfaces","LowerRange",,"ndis5,ndis4" - -;------------------------------------------------------------------------- -; Service installation support -;------------------------------------------------------------------------- -[Install.Services] -AddService=B2Ether,,B2ETHER_Service_Inst - -[B2Ether_Service_Inst] -DisplayName = %B2ETHER_Desc% -ServiceType = 1 ;SERVICE_KERNEL_DRIVER -StartType = 2 ;SERVICE_AUTO_START -ErrorControl = 1 ;SERVICE_ERROR_NORMAL -ServiceBinary = %12%\B2Ether.sys -LoadOrderGroup = "PNP_TDI" -AddReg = AddReg_B2ETHER_Service_Inst -Description = %B2ETHER_Desc% - -[AddReg_B2ETHER_Service_Inst] -HKLM,"System\CurrentControlSet\Services\B2Ether","TextModeFlags",%REG_DWORD%,0x0001 -HKR,"Parameters","Version",,"5.00.2128" - -;------------------------------------------------------------------------- -; Support for removal of static registry settings -;------------------------------------------------------------------------- -[Install.Remove] -DelReg=Del_Static_Reg - -[Install.Remove.Services] -DelService=B2Ether - -[Del_Static_Reg] -HKLM,"System\CurrentControlSet\Services\B2Ether","TextModeFlags" - -;------------------------------------------------------------------------- -; Declare Destination Directories for file copy/deletion -;------------------------------------------------------------------------- -[DestinationDirs] -CpyFiles_Sys = 12 ; DIRID_DRIVERS - - -;------------------------------------------------------------------------- -; Files to Copy/Delete - Referenced by Install and Remove sections above -;------------------------------------------------------------------------- -[CpyFiles_Sys] -B2Ether.sys,,,2 - -[Strings] -Msft = "Microsoft" -B2ETHER_Desc = "Basilisk II Ethernet Driver" -B2ETHER_HelpText = "Adds ethernet capability to the Basilisk II Macintosh II emulator." -REG_DWORD = 0x10001 diff --git a/BasiliskII/src/Windows/b2ether/nt5/B2Win7Vista-x64.inf b/BasiliskII/src/Windows/b2ether/nt5/B2Win7Vista-x64.inf deleted file mode 100755 index f154af77..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/B2Win7Vista-x64.inf +++ /dev/null @@ -1,80 +0,0 @@ -[version] -Signature = "$Windows NT$" -Class = NetTrans -ClassGUID = {4d36e975-e325-11ce-bfc1-08002be10318} -Provider = %Msft% -DriverVer = 12/05/1999,5.00.2128 - -[Manufacturer] -%Msft%=MSFT,NTamd64 - -[MSFT.NTamd64] -%B2ETHER_Desc%=Install, MS_B2ETHER - -;------------------------------------------------------------------------- -; Installation Section -;------------------------------------------------------------------------- -[Install] -AddReg=Inst_Ndi -Characteristics=0 ; Has no characteristic -CopyFiles=CpyFiles_Sys - -;------------------------------------------------------------------------- -; Ndi installation support -;------------------------------------------------------------------------- -[Inst_Ndi] -HKR,Ndi,Service,,"B2Ether" -HKR,Ndi,HelpText,,%B2ETHER_HelpText% -HKR, Ndi\Interfaces, UpperRange,, noupper -HKR,"Ndi\Interfaces","LowerRange",,"ndis5,ndis4" - -;------------------------------------------------------------------------- -; Service installation support -;------------------------------------------------------------------------- -[Install.Services] -AddService=B2Ether,,B2ETHER_Service_Inst - -[B2Ether_Service_Inst] -DisplayName = %B2ETHER_Desc% -ServiceType = 1 ;SERVICE_KERNEL_DRIVER -StartType = 2 ;SERVICE_AUTO_START -ErrorControl = 1 ;SERVICE_ERROR_NORMAL -ServiceBinary = %12%\B2Ether64.sys -LoadOrderGroup = "PNP_TDI" -AddReg = AddReg_B2ETHER_Service_Inst -Description = %B2ETHER_Desc% - -[AddReg_B2ETHER_Service_Inst] -HKLM,"System\CurrentControlSet\Services\B2Ether","TextModeFlags",%REG_DWORD%,0x0001 -HKR,"Parameters","Version",,"5.00.2128" - -;------------------------------------------------------------------------- -; Support for removal of static registry settings -;------------------------------------------------------------------------- -[Install.Remove] -DelReg=Del_Static_Reg - -[Install.Remove.Services] -DelService=B2Ether - -[Del_Static_Reg] -HKLM,"System\CurrentControlSet\Services\B2Ether","TextModeFlags" - -;------------------------------------------------------------------------- -; Declare Destination Directories for file copy/deletion -;------------------------------------------------------------------------- -[DestinationDirs] -CpyFiles_Sys = 12 ; DIRID_DRIVERS - - -;------------------------------------------------------------------------- -; Files to Copy/Delete - Referenced by Install and Remove sections above -;------------------------------------------------------------------------- -[CpyFiles_Sys] -B2Ether64.sys,,,2 - -[Strings] -Msft = "Microsoft" -B2ETHER_Desc = "Basilisk II Ethernet Driver Test x64" -B2ETHER_HelpText = "Adds ethernet capability to the Basilisk II Macintosh II emulator." -REG_DWORD = 0x10001 diff --git a/BasiliskII/src/Windows/b2ether/nt5/MAKEFILE b/BasiliskII/src/Windows/b2ether/nt5/MAKEFILE deleted file mode 100644 index 58189757..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/MAKEFILE +++ /dev/null @@ -1,7 +0,0 @@ -# -# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source -# file to this component. This file merely indirects to the real make file -# that is shared by all the driver components of the Windows NT DDK -# - -!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/BasiliskII/src/Windows/b2ether/nt5/NTDDPACK.H b/BasiliskII/src/Windows/b2ether/nt5/NTDDPACK.H deleted file mode 100755 index 6c5e0ceb..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/NTDDPACK.H +++ /dev/null @@ -1,32 +0,0 @@ -// #include - -#ifndef __NTDDPACKET -#define __NTDDPACKET 1 - -// #include - -#define MAX_LINK_NAME_LENGTH 124 - -#pragma pack(1) -typedef struct _PACKET_OID_DATA { - ULONG Oid; - ULONG Length; - UCHAR Data[1]; -} PACKET_OID_DATA, *PPACKET_OID_DATA; -#pragma pack() - - -#define FILE_DEVICE_PROTOCOL 0x8000 - - - -#define IOCTL_PROTOCOL_SET_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 0 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_QUERY_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 1 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_RESET CTL_CODE(FILE_DEVICE_PROTOCOL, 2 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_READ CTL_CODE(FILE_DEVICE_PROTOCOL, 3 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_WRITE CTL_CODE(FILE_DEVICE_PROTOCOL, 4 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_MACNAME CTL_CODE(FILE_DEVICE_PROTOCOL, 5 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_SELECT_BY_NAME CTL_CODE(FILE_DEVICE_PROTOCOL, 6 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_ENUM_ADAPTERS CTL_CODE(FILE_DEVICE_PROTOCOL, 7 , METHOD_BUFFERED, FILE_ANY_ACCESS) - -#endif diff --git a/BasiliskII/src/Windows/b2ether/nt5/SOURCES b/BasiliskII/src/Windows/b2ether/nt5/SOURCES deleted file mode 100644 index 1e0c1aca..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/SOURCES +++ /dev/null @@ -1,17 +0,0 @@ -# MYMODE must be set - -TARGETNAME=b2ether -TARGETPATH=obj -TARGETTYPE=DRIVER - -TARGETLIBS=$(DDK_LIB_PATH)\ndis.lib -C_DEFINES=$(C_DEFINES) -DNDIS50 -INCLUDES=$(BASEDIR)\inc;$(BASEDIR)\src\network\inc;..\inc - -MSC_WARNING_LEVEL=/W3 /WX /FR /FAcs /D$(MYMODE) - -SOURCES=b2ether.c \ - b2ether_openclose.c \ - b2ether_read.c \ - b2ether_write.c \ - b2ether.rc diff --git a/BasiliskII/src/Windows/b2ether/nt5/b2ether.c b/BasiliskII/src/Windows/b2ether/nt5/b2ether.c deleted file mode 100644 index ec2c69c9..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/b2ether.c +++ /dev/null @@ -1,755 +0,0 @@ -/* - * b2ether driver -- derived from DDK packet driver sample - * - * Basilisk II (C) 1997-1999 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "ntddk.h" -#include "ndis.h" -#include "ntddpack.h" -#include "b2ether.h" -#include "stdio.h" - - - -NTSTATUS -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath -) -{ - NDIS_PROTOCOL_CHARACTERISTICS protocolChar; - NTSTATUS status = STATUS_SUCCESS; - NDIS_STRING protoName = NDIS_STRING_CONST("B2ether"); - UNICODE_STRING ntDeviceName; - UNICODE_STRING win32DeviceName; - BOOLEAN fSymbolicLink = FALSE; - PDEVICE_OBJECT deviceObject; - - // DebugPrint(("\n\nDriverEntry\n")); - - Globals.DriverObject = DriverObject; - Globals.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); - Globals.RegistryPath.Length = RegistryPath->Length; - Globals.RegistryPath.Buffer = ExAllocatePool( PagedPool, Globals.RegistryPath.MaximumLength ); - if (!Globals.RegistryPath.Buffer) { - // DebugPrint (("Couldn't allocate pool for registry path.")); - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlCopyUnicodeString(&Globals.RegistryPath, RegistryPath); - RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME); - - status = IoCreateDevice (DriverObject, - 0, - &ntDeviceName, - FILE_DEVICE_UNKNOWN, - 0, - FALSE, - &deviceObject); - - - if (!NT_SUCCESS (status)) { - // Either not enough memory to create a deviceobject or another - // deviceobject with the same name exits. This could happen - // if you install another instance of this device. - goto ERROR; - } - - RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME); - - status = IoCreateSymbolicLink( &win32DeviceName, &ntDeviceName ); - if (!NT_SUCCESS(status)) goto ERROR; - - fSymbolicLink = TRUE; - - deviceObject->Flags |= DO_BUFFERED_IO; - Globals.ControlDeviceObject = deviceObject; - - InitializeListHead(&Globals.AdapterList); - KeInitializeSpinLock(&Globals.GlobalLock); - - NdisZeroMemory(&protocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); - - protocolChar.MajorNdisVersion = 5; - protocolChar.MinorNdisVersion = 0; - protocolChar.Name = protoName; - protocolChar.OpenAdapterCompleteHandler = PacketOpenAdapterComplete; - protocolChar.CloseAdapterCompleteHandler = PacketCloseAdapterComplete; - protocolChar.SendCompleteHandler = PacketSendComplete; - protocolChar.TransferDataCompleteHandler = PacketTransferDataComplete; - protocolChar.ResetCompleteHandler = PacketResetComplete; - protocolChar.RequestCompleteHandler = PacketRequestComplete; - protocolChar.ReceiveHandler = PacketReceiveIndicate; - protocolChar.ReceiveCompleteHandler = PacketReceiveComplete; - protocolChar.StatusHandler = PacketStatus; - protocolChar.StatusCompleteHandler = PacketStatusComplete; - protocolChar.BindAdapterHandler = PacketBindAdapter; - protocolChar.UnbindAdapterHandler = PacketUnbindAdapter; - protocolChar.UnloadHandler = NULL; - protocolChar.ReceivePacketHandler = PacketReceivePacket; - protocolChar.PnPEventHandler = PacketPNPHandler; - - NdisRegisterProtocol( - &status, - &Globals.NdisProtocolHandle, - &protocolChar, - sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); - - if (status != NDIS_STATUS_SUCCESS) { - // DebugPrint(("Failed to register protocol with NDIS\n")); - status = STATUS_UNSUCCESSFUL; - goto ERROR; - } - - DriverObject->MajorFunction[IRP_MJ_CREATE] = PacketOpen; - DriverObject->MajorFunction[IRP_MJ_CLOSE] = PacketClose; - DriverObject->MajorFunction[IRP_MJ_READ] = PacketRead; - DriverObject->MajorFunction[IRP_MJ_WRITE] = PacketWrite; - DriverObject->MajorFunction[IRP_MJ_CLEANUP] = PacketCleanup; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PacketIoControl; - DriverObject->DriverUnload = PacketUnload; - - return(STATUS_SUCCESS); - -ERROR: - if(deviceObject) - IoDeleteDevice(deviceObject); - if(fSymbolicLink) - IoDeleteSymbolicLink(&win32DeviceName); - if(Globals.RegistryPath.Buffer) - ExFreePool(Globals.RegistryPath.Buffer); - return status; -} - - -VOID PacketUnload( IN PDRIVER_OBJECT DriverObject ) -{ - NDIS_STATUS status; - UNICODE_STRING win32DeviceName; - - // DebugPrint(("Unload Enter\n")); - - RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME); - IoDeleteSymbolicLink(&win32DeviceName); - - if(Globals.ControlDeviceObject) - IoDeleteDevice(Globals.ControlDeviceObject); - - // Unbind from all the adapters. The system removes the driver code - // pages from the memory as soon as the unload returns. So you - // must wait for all the CloseAdapterCompleteHandler to finish - // before returning from the unload routine. You don't any callbacks - // to trigger after the driver is unloaded. - - while(DriverObject->DeviceObject) { - PacketUnbindAdapter(&status, DriverObject->DeviceObject->DeviceExtension,NULL); - } - - if(Globals.RegistryPath.Buffer) - ExFreePool(Globals.RegistryPath.Buffer); - - // DebugPrint(("Deregister\n")); - - NdisDeregisterProtocol( &status, Globals.NdisProtocolHandle ); - // DebugPrint(("Unload Exit\n")); -} - - - -NTSTATUS PacketIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) -{ - POPEN_INSTANCE open; - PIO_STACK_LOCATION irpSp; - PINTERNAL_REQUEST pRequest; - ULONG functionCode; - NDIS_STATUS status; - ULONG dataLength =0; - - // DebugPrint(("IoControl\n")); - - irpSp = IoGetCurrentIrpStackLocation(Irp); - - functionCode=irpSp->Parameters.DeviceIoControl.IoControlCode; - - if (functionCode == IOCTL_ENUM_ADAPTERS) { - // If the request is not made to the controlobject, fail the request. - - if(DeviceObject != Globals.ControlDeviceObject) { - status = STATUS_INVALID_DEVICE_REQUEST; - } else { - status = PacketGetAdapterList( - Irp->AssociatedIrp.SystemBuffer, - irpSp->Parameters.DeviceIoControl.OutputBufferLength, - &dataLength - ); - } - Irp->IoStatus.Status = status; - Irp->IoStatus.Information = dataLength; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; - } - - open = DeviceObject->DeviceExtension; - IoIncrement(open); - - if(!open->Bound) { - Irp->IoStatus.Status = status = STATUS_UNSUCCESSFUL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - IoDecrement(open); - return status; - } - - // DebugPrint(("Function code is %08lx buff size=%08lx %08lx\n", - // functionCode,irpSp->Parameters.DeviceIoControl.InputBufferLength, - // irpSp->Parameters.DeviceIoControl.OutputBufferLength)); - - // Important: Since we have marked the IRP pending, we must return - // STATUS_PENDING even we happen to complete the IRP synchronously. - - IoMarkIrpPending(Irp); - - if (functionCode == IOCTL_PROTOCOL_RESET) { - // DebugPrint(("IoControl - Reset request\n")); - - // - // Since NDIS doesn't have an interface to cancel a request - // pending at miniport, we cannot set a cancel routine. - // As a result if the application that made the request - // terminates, we wait in the Cleanup routine for all pending - // NDIS requests to complete. - - ExInterlockedInsertTailList( - &open->ResetIrpList, - &Irp->Tail.Overlay.ListEntry, - &open->ResetQueueLock); - - NdisReset( &status, open->AdapterHandle ); - - if (status != NDIS_STATUS_PENDING) { - // DebugPrint(("IoControl - ResetComplete being called\n")); - PacketResetComplete( open, status ); - } - } else { - // See if it is an Ndis request - PPACKET_OID_DATA OidData=Irp->AssociatedIrp.SystemBuffer; - - pRequest = ExAllocatePool(NonPagedPool, sizeof(INTERNAL_REQUEST)); - - if(!pRequest) { - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - IoDecrement(open); - return STATUS_PENDING; - } - pRequest->Irp=Irp; - - if (((functionCode == IOCTL_PROTOCOL_SET_OID) || (functionCode == IOCTL_PROTOCOL_QUERY_OID)) - && - (irpSp->Parameters.DeviceIoControl.InputBufferLength == irpSp->Parameters.DeviceIoControl.OutputBufferLength) - && - (irpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)) - && - (irpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)-1+OidData->Length)) - { - // DebugPrint(("IoControl: Request: Oid=%08lx, Length=%08lx\n", OidData->Oid,OidData->Length)); - - if (functionCode == IOCTL_PROTOCOL_SET_OID) { - pRequest->Request.RequestType = NdisRequestSetInformation; - pRequest->Request.DATA.SET_INFORMATION.Oid = OidData->Oid; - pRequest->Request.DATA.SET_INFORMATION.InformationBuffer = OidData->Data; - pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength = OidData->Length; - } else { - pRequest->Request.RequestType=NdisRequestQueryInformation; - pRequest->Request.DATA.QUERY_INFORMATION.Oid = OidData->Oid; - pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer = OidData->Data; - pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength = OidData->Length; - } - NdisRequest( &status, open->AdapterHandle, &pRequest->Request ); - } else { - status=NDIS_STATUS_FAILURE; - pRequest->Request.DATA.SET_INFORMATION.BytesRead=0; - pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten=0; - } - - if (status != NDIS_STATUS_PENDING) { - // DebugPrint(("Calling RequestCompleteHandler\n")); - PacketRequestComplete( open, &pRequest->Request, status ); - } - } - return STATUS_PENDING; -} - - -VOID -PacketRequestComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_REQUEST NdisRequest, - IN NDIS_STATUS Status - ) -{ - POPEN_INSTANCE open; - PIO_STACK_LOCATION irpSp; - PIRP irp; - PINTERNAL_REQUEST pRequest; - UINT functionCode; - - PPACKET_OID_DATA OidData; - - // DebugPrint(("RequestComplete\n")); - - open = (POPEN_INSTANCE)ProtocolBindingContext; - - pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request); - irp = pRequest->Irp; - - if(Status == NDIS_STATUS_SUCCESS) { - irpSp = IoGetCurrentIrpStackLocation(irp); - functionCode=irpSp->Parameters.DeviceIoControl.IoControlCode; - OidData = irp->AssociatedIrp.SystemBuffer; - if (functionCode == IOCTL_PROTOCOL_SET_OID) { - OidData->Length=pRequest->Request.DATA.SET_INFORMATION.BytesRead; - } else { - if (functionCode == IOCTL_PROTOCOL_QUERY_OID) { - OidData->Length=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten; - } - } - irp->IoStatus.Status = STATUS_SUCCESS; - irp->IoStatus.Information=irpSp->Parameters.DeviceIoControl.InputBufferLength; - } else { - irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - irp->IoStatus.Information = 0; - } - - ExFreePool(pRequest); - IoCompleteRequest(irp, IO_NO_INCREMENT); - IoDecrement(open); -} - - -VOID -PacketStatus( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status, - IN PVOID StatusBuffer, - IN UINT StatusBufferSize -) -{ - // DebugPrint(("Indication Status: %0x, StatusBufferSize: %d\n", Status, StatusBufferSize)); -} - - -VOID PacketStatusComplete( IN NDIS_HANDLE ProtocolBindingContext ) -{ - // DebugPrint(("StatusIndicationComplete\n")); -} - - -NTSTATUS -PacketGetAdapterList( - IN PVOID Buffer, - IN ULONG Length, - IN OUT PULONG DataLength -) -{ - ULONG requiredLength = 0, numOfAdapters = 0; - KIRQL oldIrql; - PLIST_ENTRY thisEntry, listHead; - POPEN_INSTANCE open; - - // DebugPrint(("Enter PacketGetAdapterList\n")); - - KeAcquireSpinLock(&Globals.GlobalLock, &oldIrql); - - // Walks the list to find out total space required for AdapterName and Symbolic Link. - - listHead = &Globals.AdapterList; - - for( thisEntry = listHead->Flink; thisEntry != listHead; thisEntry = thisEntry->Flink) { - open = CONTAINING_RECORD(thisEntry, OPEN_INSTANCE, AdapterListEntry); - requiredLength += open->AdapterName.Length + sizeof(UNICODE_NULL); - requiredLength += open->SymbolicLink.Length + sizeof(UNICODE_NULL); - numOfAdapters++; - } - - // - // We will return the data in the following format: - // numOfAdapters + One_Or_More("AdapterName\0" + "SymbolicLink\0") + UNICODE_NULL - // So let's include the numOfAdapters and UNICODE_NULL size - // to the total length. - // - - requiredLength += sizeof(ULONG) + sizeof(UNICODE_NULL); - *DataLength = requiredLength; - - if(requiredLength > Length) { - KeReleaseSpinLock(&Globals.GlobalLock, oldIrql); - return STATUS_BUFFER_TOO_SMALL; - } - - *(PULONG)Buffer = numOfAdapters; - (PCHAR)Buffer += sizeof(ULONG); - - for( thisEntry = listHead->Flink; thisEntry != listHead; thisEntry = thisEntry->Flink ) { - open = CONTAINING_RECORD(thisEntry, OPEN_INSTANCE, AdapterListEntry); - RtlCopyMemory( Buffer, open->AdapterName.Buffer, open->AdapterName.Length+sizeof(WCHAR) ); - (PCHAR)Buffer += open->AdapterName.Length+sizeof(WCHAR); - RtlCopyMemory( Buffer, open->SymbolicLink.Buffer, open->SymbolicLink.Length+sizeof(WCHAR) ); - (PCHAR)Buffer += open->SymbolicLink.Length+sizeof(WCHAR); - } - - *(PWCHAR)Buffer = UNICODE_NULL; - KeReleaseSpinLock(&Globals.GlobalLock, oldIrql); - return STATUS_SUCCESS; -} - -VOID -PacketBindAdapter( - OUT PNDIS_STATUS Status, - IN NDIS_HANDLE BindContext, - IN PNDIS_STRING DeviceName, - IN PVOID SystemSpecific1, - IN PVOID SystemSpecific2 -) -{ - NDIS_STATUS status; - UINT mediumIndex; - USHORT length; - POPEN_INSTANCE open = NULL; - UNICODE_STRING unicodeDeviceName; - PDEVICE_OBJECT deviceObject = NULL; - PWSTR symbolicLink = NULL, deviceNameStr = NULL; - NDIS_MEDIUM mediumArray = NdisMedium802_3; // Ethernet medium - - // DebugPrint(("Binding DeviceName %ws\n", DeviceName->Buffer)); - - do { - // Create a deviceobject for every adapter we bind to. - // To make a name for the deviceObject, we will append Packet_ - // to the name portion of the input DeviceName. - - unicodeDeviceName.Buffer = NULL; - length = DeviceName->Length + 7 * sizeof(WCHAR) + sizeof(UNICODE_NULL); - - deviceNameStr = ExAllocatePool(NonPagedPool, length); - if (!deviceNameStr) { - // DebugPrint(("Memory allocation for create symbolic failed\n")); - *Status = NDIS_STATUS_FAILURE; - break; - } - swprintf(deviceNameStr, L"\\Device\\B2ether_%ws", &DeviceName->Buffer[8]); - RtlInitUnicodeString(&unicodeDeviceName, deviceNameStr); - - // DebugPrint(("Exported DeviceName %ws\n", unicodeDeviceName.Buffer)); - - status = IoCreateDevice( - Globals.DriverObject, - sizeof(OPEN_INSTANCE), - &unicodeDeviceName, - FILE_DEVICE_PROTOCOL, - 0, - TRUE, // only one handle to the device at a time. - &deviceObject - ); - - if (status != STATUS_SUCCESS) { - // DebugPrint(("CreateDevice Failed: %x\n", status)); - *Status = NDIS_STATUS_FAILURE; - break; - } - - deviceObject->Flags |= DO_DIRECT_IO; - open = (POPEN_INSTANCE) deviceObject->DeviceExtension; - open->DeviceObject = deviceObject; - - // Create a symbolic link. - // We need to replace Device from \Device\Packet_{GUID} with DosDevices - // to create a symbolic link of the form \DosDevices\Packet_{GUID} - // There is a four character difference between these two - // strings. - - length = unicodeDeviceName.Length + sizeof(UNICODE_NULL) + (4 * sizeof(WCHAR)); - - symbolicLink = ExAllocatePool(NonPagedPool, length); - if (!symbolicLink) { - // DebugPrint(("Memory allocation for create symbolic failed\n")); - *Status = NDIS_STATUS_FAILURE; - break; - } - - swprintf( symbolicLink, L"\\DosDevices\\%ws", &unicodeDeviceName.Buffer[8]); - - RtlInitUnicodeString(&open->SymbolicLink,symbolicLink); - - // DebugPrint(("Symbolic Link: %ws\n", open->SymbolicLink.Buffer)); - - status = IoCreateSymbolicLink( - (PUNICODE_STRING) &open->SymbolicLink, - (PUNICODE_STRING) &unicodeDeviceName - ); - if (status != STATUS_SUCCESS) { - // DebugPrint(("Create symbolic failed\n")); - *Status = NDIS_STATUS_FAILURE; - break; - } - - ExFreePool(unicodeDeviceName.Buffer); - unicodeDeviceName.Buffer = NULL; - - NdisAllocatePacketPool( - &status, - &open->PacketPool, - TRANSMIT_PACKETS, - sizeof(PACKET_RESERVED)); - - if (status != NDIS_STATUS_SUCCESS) { - // DebugPrint(("B2ether: Failed to allocate packet pool\n")); - break; - } - - NdisInitializeEvent(&open->Event); - InitializeListHead(&open->ResetIrpList); - KeInitializeSpinLock(&open->ResetQueueLock); - KeInitializeSpinLock(&open->RcvQSpinLock); - InitializeListHead(&open->RcvList); - - NdisOpenAdapter(Status, - &status, - &open->AdapterHandle, - &mediumIndex, - &mediumArray, - sizeof(mediumArray)/sizeof(NDIS_MEDIUM), - Globals.NdisProtocolHandle, - open, - DeviceName, - 0, - NULL); - - if(*Status == NDIS_STATUS_PENDING) { - NdisWaitEvent(&open->Event, 0); - *Status = open->Status; - } - if(*Status != NDIS_STATUS_SUCCESS) { - // DebugPrint(("Failed to openAdapter\n")); - break; - } - - open->IrpCount = 0; - InterlockedExchange( (PLONG)&open->Bound, TRUE ); - NdisInitializeEvent(&open->CleanupEvent); - - NdisSetEvent(&open->CleanupEvent); - - NdisQueryAdapterInstanceName( &open->AdapterName, open->AdapterHandle ); - // DebugPrint(("Bound AdapterName %ws\n", open->AdapterName.Buffer)); - - open->Medium = mediumArray; - - InitializeListHead(&open->AdapterListEntry); - - ExInterlockedInsertTailList(&Globals.AdapterList, - &open->AdapterListEntry, - &Globals.GlobalLock); - - // Clear the DO_DEVICE_INITIALIZING flag. This is required - // if you create deviceobjects outside of DriverEntry. - // Untill you do this, application cannot send I/O request. - - deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; - } while (FALSE); - - if (*Status != NDIS_STATUS_SUCCESS) { - if (open && open->PacketPool) NdisFreePacketPool(open->PacketPool); - if (deviceObject) IoDeleteDevice(deviceObject); - if(unicodeDeviceName.Buffer) ExFreePool(unicodeDeviceName.Buffer); - if(symbolicLink) { - IoDeleteSymbolicLink(&open->SymbolicLink); - ExFreePool(open->SymbolicLink.Buffer); - } - } - // DebugPrint(("Return BindAdapter :0x%x\n", *Status)); -} - - -VOID -PacketUnbindAdapter( - OUT PNDIS_STATUS Status, - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_HANDLE UnbindContext -) -{ - POPEN_INSTANCE open =(POPEN_INSTANCE)ProtocolBindingContext; - KIRQL oldIrql; - - // DebugPrint(("PacketUnbindAdapter :%ws\n", open->AdapterName.Buffer)); - - if(open->AdapterHandle) { - NdisResetEvent(&open->Event); - InterlockedExchange( (PLONG) &open->Bound, FALSE ); - PacketCancelReadIrps(open->DeviceObject); - - // DebugPrint(("Waiting on CleanupEvent\n")); - NdisWaitEvent(&open->CleanupEvent, 0); - - NdisCloseAdapter(Status, open->AdapterHandle); - - // Wait for it to complete - if(*Status == NDIS_STATUS_PENDING) { - NdisWaitEvent(&open->Event, 0); - *Status = open->Status; - } else { - *Status = NDIS_STATUS_FAILURE; - // ASSERT(0); - } - - KeAcquireSpinLock(&Globals.GlobalLock, &oldIrql); - RemoveEntryList(&open->AdapterListEntry); - KeReleaseSpinLock(&Globals.GlobalLock, oldIrql); - - NdisFreePacketPool(open->PacketPool); - - NdisFreeMemory(open->AdapterName.Buffer, open->AdapterName.Length, 0); - - IoDeleteSymbolicLink(&open->SymbolicLink); - ExFreePool(open->SymbolicLink.Buffer); - - IoDeleteDevice(open->DeviceObject); - } - - // DebugPrint(("Exit PacketUnbindAdapter\n")); -} - -VOID -PacketOpenAdapterComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status, - IN NDIS_STATUS OpenErrorStatus -) -{ - POPEN_INSTANCE open = ProtocolBindingContext; - - // DebugPrint(("B2ether: OpenAdapterComplete\n")); - - open->Status = Status; - NdisSetEvent(&open->Event); -} - -VOID -PacketCloseAdapterComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status -) -{ - POPEN_INSTANCE open = ProtocolBindingContext; - - // DebugPrint(("CloseAdapterComplete\n")); - - open->Status = Status; - NdisSetEvent(&open->Event); -} - - -NDIS_STATUS -PacketPNPHandler( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNET_PNP_EVENT NetPnPEvent -) -{ - POPEN_INSTANCE open =(POPEN_INSTANCE)ProtocolBindingContext; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PNET_DEVICE_POWER_STATE powerState; - - // DebugPrint(("PacketPNPHandler\n")); - - powerState = (PNET_DEVICE_POWER_STATE)NetPnPEvent->Buffer; - - // This will happen when all entities in the system need to be notified - // - //if(open == NULL) - //{ - // return Status; - //} - - switch(NetPnPEvent->NetEvent) { - case NetEventSetPower : - // DebugPrint(("NetEventSetPower\n")); - switch (*powerState) { - case NetDeviceStateD0: - Status = NDIS_STATUS_SUCCESS; - break; - default: - // We can't suspend, so we ask NDIS to Unbind us by - // returning this status: - Status = NDIS_STATUS_NOT_SUPPORTED; - break; - } - break; - case NetEventQueryPower : - // DebugPrint(("NetEventQueryPower\n")); - break; - case NetEventQueryRemoveDevice : - // DebugPrint(("NetEventQueryRemoveDevice \n")); - break; - case NetEventCancelRemoveDevice : - // DebugPrint(("NetEventCancelRemoveDevice \n")); - break; - case NetEventReconfigure : - // The protocol should always succeed this event by returning NDIS_STATUS_SUCCESS - // DebugPrint(("NetEventReconfigure\n")); - break; - case NetEventBindsComplete : - // DebugPrint(("NetEventBindsComplete \n")); - break; - case NetEventPnPCapabilities : - // DebugPrint(("NetEventPnPCapabilities \n")); - case NetEventBindList: - // DebugPrint(("NetEventBindList \n")); - default: - Status = NDIS_STATUS_NOT_SUPPORTED; - break; - } - return Status; -} - - -VOID IoIncrement( IN OUT POPEN_INSTANCE Open ) -{ - LONG result = InterlockedIncrement(&Open->IrpCount); - - //DebugPrint(("IoIncrement %d\n", result)); - - // Need to clear event (when IrpCount bumps from 0 to 1) - if (result == 1) { - NdisResetEvent(&Open->CleanupEvent); - } -} - - -VOID IoDecrement ( IN OUT POPEN_INSTANCE Open ) -{ - LONG result = InterlockedDecrement(&Open->IrpCount); - - //DebugPrint(("IoDecrement %d\n", result)); - - if (result == 0) { - // Set the event when the count transition from 1 to 0. - NdisSetEvent (&Open->CleanupEvent); - } -} diff --git a/BasiliskII/src/Windows/b2ether/nt5/b2ether.h b/BasiliskII/src/Windows/b2ether/nt5/b2ether.h deleted file mode 100644 index e1c729f8..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/b2ether.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * b2ether driver -- derived from DDK packet driver sample - * - * Basilisk II (C) 1997-1999 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _B2ETHER_H_ -#define _B2ETHER_H_ - -#undef ExAllocatePool -#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a, b, 'te2B') - -#if DBG -#define DebugPrint(_x_) \ - DbgPrint("B2ETHER: ");\ - DbgPrint _x_; -#else -#define DebugPrint(_x_) -#endif - -#define NT_DEVICE_NAME L"\\Device\\B2ether" -#define DOS_DEVICE_NAME L"\\DosDevices\\B2ether" - -typedef struct _GLOBAL { - PDRIVER_OBJECT DriverObject; - NDIS_HANDLE NdisProtocolHandle; - UNICODE_STRING RegistryPath; - LIST_ENTRY AdapterList; - KSPIN_LOCK GlobalLock; - PDEVICE_OBJECT ControlDeviceObject; -} GLOBAL, *PGLOBAL; - -GLOBAL Globals; - -typedef struct _INTERNAL_REQUEST { - PIRP Irp; - NDIS_REQUEST Request; -} INTERNAL_REQUEST, *PINTERNAL_REQUEST; - -typedef struct _OPEN_INSTANCE { - PDEVICE_OBJECT DeviceObject; - ULONG IrpCount; - NDIS_STRING AdapterName; - NDIS_STRING SymbolicLink; - NDIS_HANDLE AdapterHandle; - NDIS_HANDLE PacketPool; - KSPIN_LOCK RcvQSpinLock; - LIST_ENTRY RcvList; - NDIS_MEDIUM Medium; - KSPIN_LOCK ResetQueueLock; - LIST_ENTRY ResetIrpList; - NDIS_STATUS Status; - NDIS_EVENT Event; - NDIS_EVENT CleanupEvent; - LIST_ENTRY AdapterListEntry; - BOOLEAN Bound; - CHAR Filler[3]; -} OPEN_INSTANCE, *POPEN_INSTANCE; - -typedef struct _PACKET_RESERVED { - LIST_ENTRY ListElement; - PIRP Irp; - PMDL pMdl; -} PACKET_RESERVED, *PPACKET_RESERVED; - - -#define ETHERNET_HEADER_LENGTH 14 -#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) -#define TRANSMIT_PACKETS 16 - - -NTSTATUS -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ); - -NTSTATUS -PacketCancelReadIrps( - IN PDEVICE_OBJECT DeviceObject -); - -NTSTATUS -PacketCleanup( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -VOID -PacketBindAdapter( - OUT PNDIS_STATUS Status, - IN NDIS_HANDLE BindContext, - IN PNDIS_STRING DeviceName, - IN PVOID SystemSpecific1, - IN PVOID SystemSpecific2 - ); -VOID -PacketUnbindAdapter( - OUT PNDIS_STATUS Status, - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_HANDLE UnbindContext - ); - - -VOID -PacketOpenAdapterComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status, - IN NDIS_STATUS OpenErrorStatus - ); - -VOID -PacketCloseAdapterComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status - ); - - -NDIS_STATUS -PacketReceiveIndicate( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_HANDLE MacReceiveContext, - IN PVOID HeaderBuffer, - IN UINT HeaderBufferSize, - IN PVOID LookAheadBuffer, - IN UINT LookaheadBufferSize, - IN UINT PacketSize - ); - -VOID -PacketReceiveComplete( - IN NDIS_HANDLE ProtocolBindingContext - ); - - -VOID -PacketRequestComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_REQUEST pRequest, - IN NDIS_STATUS Status - ); - -VOID -PacketSendComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET pPacket, - IN NDIS_STATUS Status - ); - - -VOID -PacketResetComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status - ); - - -VOID -PacketStatus( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status, - IN PVOID StatusBuffer, - IN UINT StatusBufferSize - ); - - -VOID -PacketStatusComplete( - IN NDIS_HANDLE ProtocolBindingContext - ); - -VOID -PacketTransferDataComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET Packet, - IN NDIS_STATUS Status, - IN UINT BytesTransferred - ); - - -NTSTATUS -PacketShutdown( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -VOID -PacketUnload( - IN PDRIVER_OBJECT DriverObject - ); - - - -NTSTATUS -PacketOpen( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -NTSTATUS -PacketClose( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -NTSTATUS -PacketWrite( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -NTSTATUS -PacketRead( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -NTSTATUS -PacketIoControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -VOID -PacketCancelRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -INT -PacketReceivePacket( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET Packet - ); - -NTSTATUS -PacketGetAdapterList( - IN PVOID Buffer, - IN ULONG Length, - IN OUT PULONG DataLength - ); - -NDIS_STATUS -PacketPNPHandler( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNET_PNP_EVENT pNetPnPEvent - ); - - -VOID -IoIncrement ( - IN OUT POPEN_INSTANCE Open - ); - -VOID -IoDecrement ( - IN OUT POPEN_INSTANCE Open - ); - -#endif //_B2ETHER_H_ diff --git a/BasiliskII/src/Windows/b2ether/nt5/b2ether.rc b/BasiliskII/src/Windows/b2ether/nt5/b2ether.rc deleted file mode 100644 index 3e4e918a..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/b2ether.rc +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include - -#define VER_FILETYPE VFT_DRV -#define VER_FILESUBTYPE VFT2_DRV_NETWORK -#define VER_FILEDESCRIPTION_STR "Basilisk II Protocol Driver" -#define VER_INTERNALNAME_STR "B2ETHER.SYS" -#define VER_ORIGINALFILENAME_STR "B2ETHER.SYS" - -#include "common.ver" diff --git a/BasiliskII/src/Windows/b2ether/nt5/b2ether64.sln b/BasiliskII/src/Windows/b2ether/nt5/b2ether64.sln deleted file mode 100755 index 1d2055d9..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/b2ether64.sln +++ /dev/null @@ -1,26 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "b2ether64", "b2ether64.vcxproj", "{F7EA62B6-E0EC-4074-8A83-D0CBB1C990B4}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F7EA62B6-E0EC-4074-8A83-D0CBB1C990B4}.Debug|Win32.ActiveCfg = Debug|Win32 - {F7EA62B6-E0EC-4074-8A83-D0CBB1C990B4}.Debug|Win32.Build.0 = Debug|Win32 - {F7EA62B6-E0EC-4074-8A83-D0CBB1C990B4}.Debug|x64.ActiveCfg = Debug|x64 - {F7EA62B6-E0EC-4074-8A83-D0CBB1C990B4}.Debug|x64.Build.0 = Debug|x64 - {F7EA62B6-E0EC-4074-8A83-D0CBB1C990B4}.Release|Win32.ActiveCfg = Release|Win32 - {F7EA62B6-E0EC-4074-8A83-D0CBB1C990B4}.Release|Win32.Build.0 = Release|Win32 - {F7EA62B6-E0EC-4074-8A83-D0CBB1C990B4}.Release|x64.ActiveCfg = Release|x64 - {F7EA62B6-E0EC-4074-8A83-D0CBB1C990B4}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/BasiliskII/src/Windows/b2ether/nt5/b2ether64.vcxproj b/BasiliskII/src/Windows/b2ether/nt5/b2ether64.vcxproj deleted file mode 100755 index 51fe3bc7..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/b2ether64.vcxproj +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {F7EA62B6-E0EC-4074-8A83-D0CBB1C990B4} - MakeFileProj - - - - Makefile - true - - - Makefile - false - - - Makefile - - - Makefile - - - - - - - - - - - - - call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk win7 -build - rmdir /s /q objchk_win7_x86 - rmdir /s /q objchk_win7_x86 -call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk win7 -build - objchk_win7_x86 - objchk_win7_x86 - objchk_win7_x86\i386\b2ether.sys - WIN32;_CONSOLE;_X86_;_DDK_;_DEBUG;DBG=1;$(NMakePreprocessorDefinitions) - $(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt;$(NMakeIncludeSearchPath) - - - call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre win7 -build - rmdir /s /q objfre_win7_x86 - rmdir /s /q objfre_win7_x86 -call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre win7 -build - objfre_win7_x86 - objfre_win7_x86 - objfre_win7_x86\i386\b2ether.sys - WIN32;_CONSOLE;_X86_;_DDK_;_NDEBUG;DBG=0;$(NMakePreprocessorDefinitions) - $(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt;$(NMakeIncludeSearchPath) - - - call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk x64 win7 -build - rmdir /s /q objchk_win7_amd64 - rmdir /s /q objchk_win7_amd64 -call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk x64 win7 -build - objchk_win7_amd64 - objchk_win7_amd64 - objchk_win7_amd64\amd64\b2ether64.sys - WIN32;_CONSOLE;_AMD64_;_DDK_;_DEBUG;DBG=1;$(NMakePreprocessorDefinitions) - $(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt;$(NMakeIncludeSearchPath) - - - call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre x64 win7 -build - rmdir /s /q objfre_win7_amd64 - rmdir /s /q objfre_win7_amd64 -call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre x64 win7 -build - objfre_win7_amd64 - objfre_win7_amd64 - objfre_win7_amd64\amd64\b2ether64.sys - WIN32;_CONSOLE;_AMD64_;_DDK_;_NDEBUG;DBG=0;$(NMakePreprocessorDefinitions) - $(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt;$(NMakeIncludeSearchPath) - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/b2ether/nt5/b2ether_openclose.c b/BasiliskII/src/Windows/b2ether/nt5/b2ether_openclose.c deleted file mode 100644 index b584dbc7..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/b2ether_openclose.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * b2ether driver -- derived from DDK packet driver sample - * - * Basilisk II (C) 1997-1999 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "ntddk.h" -#include "ndis.h" -#include "b2ether.h" - -NTSTATUS PacketOpen( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) -{ - POPEN_INSTANCE open; - NTSTATUS status = STATUS_SUCCESS; - - // DebugPrint(("OpenAdapter\n")); - - if(DeviceObject == Globals.ControlDeviceObject) { - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; - } - - open = DeviceObject->DeviceExtension; - - // DebugPrint(("AdapterName :%ws\n", open->AdapterName.Buffer)); - - IoIncrement(open); - - if(!open->Bound) { - status = STATUS_DEVICE_NOT_READY; - } - - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = status; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - IoDecrement(open); - return status; -} - - -NTSTATUS PacketClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) -{ - POPEN_INSTANCE open; - NTSTATUS status = STATUS_SUCCESS; - - // DebugPrint(("CloseAdapter \n")); - - if(DeviceObject == Globals.ControlDeviceObject) { - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; - } - - open = DeviceObject->DeviceExtension; - IoIncrement(open); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = status; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - IoDecrement(open); - return status; -} - - -NTSTATUS PacketCleanup( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) -{ - POPEN_INSTANCE open; - NTSTATUS status = STATUS_SUCCESS; - - // DebugPrint(("Packet: Cleanup\n")); - - if(DeviceObject == Globals.ControlDeviceObject) { - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; - } - - open = DeviceObject->DeviceExtension; - - IoIncrement(open); - - PacketCancelReadIrps(DeviceObject); - - // Since the current implementation of NDIS doesn't - // allow us to cancel requests pending at the - // minport, we must wait here until they complete. - - IoDecrement(open); - - NdisWaitEvent(&open->CleanupEvent, 0); - - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = status; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - return status; -} - - -VOID -PacketResetComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status -) -{ - POPEN_INSTANCE open; - PIRP irp; - - PLIST_ENTRY resetListEntry; - - // DebugPrint(("PacketResetComplte\n")); - - open= (POPEN_INSTANCE)ProtocolBindingContext; - - resetListEntry=ExInterlockedRemoveHeadList( - &open->ResetIrpList, - &open->ResetQueueLock - ); - -#if DBG - if (resetListEntry == NULL) { - DbgBreakPoint(); - return; - } -#endif - - irp=CONTAINING_RECORD(resetListEntry,IRP,Tail.Overlay.ListEntry); - - if(Status == NDIS_STATUS_SUCCESS) { - irp->IoStatus.Status = STATUS_SUCCESS; - } else { - irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - } - - irp->IoStatus.Information = 0; - IoCompleteRequest(irp, IO_NO_INCREMENT); - IoDecrement(open); - - // DebugPrint(("PacketResetComplte exit\n")); -} diff --git a/BasiliskII/src/Windows/b2ether/nt5/b2ether_read.c b/BasiliskII/src/Windows/b2ether/nt5/b2ether_read.c deleted file mode 100644 index 3f4f100d..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/b2ether_read.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * b2ether driver -- derived from DDK packet driver sample - * - * Basilisk II (C) 1997-1999 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "ntddk.h" -#include "ndis.h" -#include "b2ether.h" - - -NTSTATUS PacketRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) -{ - POPEN_INSTANCE open; - PNDIS_PACKET pPacket; - NDIS_STATUS status; - NTSTATUS ntStatus; - PIO_STACK_LOCATION irpSp; - - // DebugPrint(("Read\n")); - - open = DeviceObject->DeviceExtension; - - IoIncrement(open); - - if(!open->Bound) { - ntStatus = STATUS_DEVICE_NOT_READY; - goto ERROR; - } - - irpSp = IoGetCurrentIrpStackLocation(Irp); - - if (irpSp->Parameters.Read.Length < ETHERNET_HEADER_LENGTH) { - ntStatus = STATUS_BUFFER_TOO_SMALL; - goto ERROR; - } - - NdisAllocatePacket( &status, &pPacket, open->PacketPool ); - if (status != NDIS_STATUS_SUCCESS) { - // DebugPrint(("Packet: Read- No free packets\n")); - ntStatus = STATUS_INSUFFICIENT_RESOURCES; - goto ERROR; - } - - RESERVED(pPacket)->Irp=Irp; - RESERVED(pPacket)->pMdl=NULL; - IoMarkIrpPending(Irp); - - IoSetCancelRoutine(Irp, PacketCancelRoutine); - - ExInterlockedInsertTailList( - &open->RcvList, - &RESERVED(pPacket)->ListElement, - &open->RcvQSpinLock); - - return STATUS_PENDING; - -ERROR: - Irp->IoStatus.Status = ntStatus; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - IoDecrement(open); - return ntStatus; -} - - - -NDIS_STATUS -PacketReceiveIndicate ( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_HANDLE MacReceiveContext, - IN PVOID HeaderBuffer, - IN UINT HeaderBufferSize, - IN PVOID LookAheadBuffer, - IN UINT LookaheadBufferSize, - IN UINT PacketSize -) -{ - POPEN_INSTANCE open; - PIO_STACK_LOCATION irpSp; - PIRP irp; - PLIST_ENTRY packetListEntry; - PNDIS_PACKET pPacket; - ULONG sizeToTransfer; - NDIS_STATUS status; - UINT bytesTransfered = 0; - ULONG bufferLength; - PPACKET_RESERVED reserved; - PMDL pMdl; - - // DebugPrint(("ReceiveIndicate\n")); - - open= (POPEN_INSTANCE)ProtocolBindingContext; - - if (HeaderBufferSize > ETHERNET_HEADER_LENGTH) { - return NDIS_STATUS_SUCCESS; - } - - // See if there are any pending read that we can satisfy - packetListEntry = ExInterlockedRemoveHeadList( &open->RcvList, &open->RcvQSpinLock ); - - if (packetListEntry == NULL) { - // DebugPrint(("No pending read, dropping packets\n")); - return NDIS_STATUS_NOT_ACCEPTED; - } - - reserved = CONTAINING_RECORD(packetListEntry,PACKET_RESERVED,ListElement); - pPacket = CONTAINING_RECORD(reserved,NDIS_PACKET,ProtocolReserved); - - irp = RESERVED(pPacket)->Irp; - irpSp = IoGetCurrentIrpStackLocation(irp); - - // We don't have to worry about the situation where the IRP is cancelled - // after we remove it from the queue and before we reset the cancel - // routine because the cancel routine has been coded to cancel an IRP - // only if it's in the queue. - - IoSetCancelRoutine(irp, NULL); - - bufferLength = irpSp->Parameters.Read.Length-ETHERNET_HEADER_LENGTH; - - sizeToTransfer = (PacketSize < bufferLength) ? PacketSize : bufferLength; - - NdisMoveMappedMemory( - MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority), - HeaderBuffer, - HeaderBufferSize - ); - - pMdl=IoAllocateMdl( - MmGetMdlVirtualAddress(irp->MdlAddress), - MmGetMdlByteCount(irp->MdlAddress), - FALSE, - FALSE, - NULL - ); - - if (pMdl == NULL) { - // DebugPrint(("Packet: Read-Failed to allocate Mdl\n")); - status = NDIS_STATUS_RESOURCES; - goto ERROR; - } - - IoBuildPartialMdl( - irp->MdlAddress, - pMdl, - ((PUCHAR)MmGetMdlVirtualAddress(irp->MdlAddress))+ETHERNET_HEADER_LENGTH, - 0 - ); - - pMdl->Next = NULL; - - RESERVED(pPacket)->pMdl=pMdl; - - NdisChainBufferAtFront(pPacket,pMdl); - - NdisTransferData( - &status, - open->AdapterHandle, - MacReceiveContext, - 0, - sizeToTransfer, - pPacket, - &bytesTransfered - ); - - if (status == NDIS_STATUS_PENDING) { - return NDIS_STATUS_SUCCESS; - } - -ERROR: - PacketTransferDataComplete( open, pPacket, status, bytesTransfered ); - return NDIS_STATUS_SUCCESS; -} - - -VOID -PacketTransferDataComplete ( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET pPacket, - IN NDIS_STATUS Status, - IN UINT BytesTransfered -) -{ - PIO_STACK_LOCATION irpSp; - POPEN_INSTANCE open; - PIRP irp; - PMDL pMdl; - - // DebugPrint(("Packet: TransferDataComplete\n")); - - open = (POPEN_INSTANCE)ProtocolBindingContext; - irp = RESERVED(pPacket)->Irp; - irpSp = IoGetCurrentIrpStackLocation(irp); - pMdl = RESERVED(pPacket)->pMdl; - - - if(pMdl) IoFreeMdl(pMdl); - - NdisFreePacket(pPacket); - - if(Status == NDIS_STATUS_SUCCESS) { - irp->IoStatus.Status = STATUS_SUCCESS; - irp->IoStatus.Information = BytesTransfered+ETHERNET_HEADER_LENGTH; - } else { - irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - irp->IoStatus.Information = 0; - } - - // DebugPrint(("BytesTransfered:%d\n", irp->IoStatus.Information)); - - IoCompleteRequest(irp, IO_NO_INCREMENT); - IoDecrement(open); -} - -VOID PacketReceiveComplete( IN NDIS_HANDLE ProtocolBindingContext ) -{ -} - -INT -PacketReceivePacket( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET Packet -) -{ - UINT bytesTransfered = 0; - POPEN_INSTANCE open; - PIRP irp; - PNDIS_PACKET myPacket; - PLIST_ENTRY packetListEntry; - ULONG bufferLength; - PPACKET_RESERVED reserved; - PIO_STACK_LOCATION irpSp; - PMDL mdl; - PVOID startAddress; - NTSTATUS status; - - // DebugPrint(("PacketReceivePacket\n")); - - open = (POPEN_INSTANCE)ProtocolBindingContext; - - packetListEntry = ExInterlockedRemoveHeadList( - &open->RcvList, - &open->RcvQSpinLock - ); - - if (packetListEntry == NULL) { - // DebugPrint(("No pending read, dropping packets\n")); - return 0; - } - - reserved = CONTAINING_RECORD(packetListEntry,PACKET_RESERVED,ListElement); - myPacket = CONTAINING_RECORD(reserved,NDIS_PACKET,ProtocolReserved); - - irp = RESERVED(myPacket)->Irp; - irpSp = IoGetCurrentIrpStackLocation(irp); - - // We don't have to worry about the situation where the IRP is cancelled - // after we remove it from the queue and before we reset the cancel - // routine because the cancel routine has been coded to cancel an IRP - // only if it's in the queue. - - IoSetCancelRoutine(irp, NULL); - - // Following block of code locks the destination packet - // MDLs in a safe manner. This is a temporary workaround - // for NdisCopyFromPacketToPacket that currently doesn't use - // safe functions to lock pages of MDL. This is required to - // prevent system from bugchecking under low memory resources. - // - { - PVOID virtualAddress; - PNDIS_BUFFER firstBuffer, nextBuffer; - ULONG totalLength; - - NdisQueryPacket(Packet, NULL, NULL, &firstBuffer, &totalLength); - while( firstBuffer ) { - NdisQueryBufferSafe( firstBuffer, &virtualAddress, &totalLength, NormalPagePriority ); - if(!virtualAddress) { - status = STATUS_INSUFFICIENT_RESOURCES; - goto CleanExit; - } - NdisGetNextBuffer(firstBuffer, &nextBuffer); - firstBuffer = nextBuffer; - } - } - - NdisChainBufferAtFront( myPacket, irp->MdlAddress ); - bufferLength=irpSp->Parameters.Read.Length; - NdisCopyFromPacketToPacket( myPacket, 0, bufferLength, Packet, 0, &bytesTransfered ); - -CleanExit: - NdisFreePacket(myPacket); - irp->IoStatus.Status = status; - irp->IoStatus.Information = bytesTransfered; - IoCompleteRequest(irp, IO_NO_INCREMENT); - // DebugPrint(("BytesTransfered:%d\n", bytesTransfered)); - IoDecrement(open); - return 0; -} - - -VOID -PacketCancelRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp -) - -{ - POPEN_INSTANCE open = DeviceObject->DeviceExtension; - KIRQL oldIrql; - PIRP irpToComplete = NULL; - PLIST_ENTRY thisEntry, listHead; - PIRP pendingIrp; - PNDIS_PACKET myPacket = NULL; - PPACKET_RESERVED reserved; - PMDL mdl; - - // Don't assume that the IRP being cancelled is in the queue. - // Only complete the IRP if it IS in the queue. - // - // Must acquire the local spinlock before releasing - // the global cancel spinlock - // - // DebugPrint(("PacketCancelRoutine\n")); - - oldIrql = Irp->CancelIrql; - - // One should not intermix KeAcquireSpinLock(AtDpcLevel) - // and ExInterlocked...List() functions on the same spinlock if the - // routines that use the lock run at IRQL > DISPATCH_LEVEL. - // After acquiring the lock using Ke function, if we got interrupted - // and entered into an ISR and tried to manipulate the list using - // ExInterlocked...List function with the same lock, we deadlock. - // In this sample we can safely do that because none of our routines - // will be called at IRQL > DISPATCH_LEVEL. - - KeAcquireSpinLockAtDpcLevel(&open->RcvQSpinLock); - IoReleaseCancelSpinLock( KeGetCurrentIrql() ); - - listHead = &open->RcvList; - for( thisEntry = listHead->Flink; thisEntry != listHead; thisEntry = thisEntry->Flink ) { - reserved=CONTAINING_RECORD(thisEntry,PACKET_RESERVED,ListElement); - myPacket=CONTAINING_RECORD(reserved,NDIS_PACKET,ProtocolReserved); - pendingIrp = RESERVED(myPacket)->Irp; - if (pendingIrp == Irp) { - RemoveEntryList(thisEntry); - irpToComplete = pendingIrp; - break; - } - } - - KeReleaseSpinLock(&open->RcvQSpinLock, oldIrql); - - if(irpToComplete) { - // DebugPrint(("Cancelling IRP\n")); - // ASSERT(myPacket); - - NdisFreePacket(myPacket); - - irpToComplete->IoStatus.Status = STATUS_CANCELLED; - irpToComplete->IoStatus.Information = 0; - IoCompleteRequest(irpToComplete, IO_NO_INCREMENT); - IoDecrement(open); - } -} - - -NTSTATUS PacketCancelReadIrps( IN PDEVICE_OBJECT DeviceObject ) -{ - POPEN_INSTANCE open = DeviceObject->DeviceExtension; - PLIST_ENTRY thisEntry; - PIRP pendingIrp; - PNDIS_PACKET myPacket = NULL; - PPACKET_RESERVED reserved; - PMDL mdl; - - // DebugPrint(("PacketCancelReadIrps\n")); - - // Walk through the RcvList and cancel all read IRPs. - - while( thisEntry = ExInterlockedRemoveHeadList( &open->RcvList, &open->RcvQSpinLock )) { - reserved=CONTAINING_RECORD(thisEntry,PACKET_RESERVED,ListElement); - myPacket=CONTAINING_RECORD(reserved,NDIS_PACKET,ProtocolReserved); - - ASSERT(myPacket); - - pendingIrp = RESERVED(myPacket)->Irp; - - NdisFreePacket(myPacket); - - // DebugPrint(("Cancelled : 0%0x\n", pendingIrp)); - - IoSetCancelRoutine(pendingIrp, NULL); - - pendingIrp->IoStatus.Information = 0; - pendingIrp->IoStatus.Status = STATUS_CANCELLED; - IoCompleteRequest(pendingIrp, IO_NO_INCREMENT); - IoDecrement(open); - } - - return STATUS_SUCCESS; -} diff --git a/BasiliskII/src/Windows/b2ether/nt5/b2ether_write.c b/BasiliskII/src/Windows/b2ether/nt5/b2ether_write.c deleted file mode 100644 index 42b1ec94..00000000 --- a/BasiliskII/src/Windows/b2ether/nt5/b2ether_write.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * b2ether driver -- derived from DDK packet driver sample - * - * Basilisk II (C) 1997-1999 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "ntddk.h" -#include "ndis.h" -#include "b2ether.h" - - -NTSTATUS PacketWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) -{ - POPEN_INSTANCE open; - PNDIS_PACKET pPacket; - NDIS_STATUS Status; - - // DebugPrint(("SendAdapter\n")); - - open = DeviceObject->DeviceExtension; - - IoIncrement(open); - - if(!open->Bound) { - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - IoDecrement(open); - return STATUS_UNSUCCESSFUL; - } - - NdisAllocatePacket( &Status, &pPacket, open->PacketPool ); - - if (Status != NDIS_STATUS_SUCCESS) { - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - IoDecrement(open); - return STATUS_INSUFFICIENT_RESOURCES; - } - - RESERVED(pPacket)->Irp=Irp; - - NdisChainBufferAtFront(pPacket,Irp->MdlAddress); - - // Important: Since we have marked the IRP pending, we must return - // STATUS_PENDING even we happen to complete the IRP synchronously. - - IoMarkIrpPending(Irp); - - NdisSend( &Status, open->AdapterHandle, pPacket ); - - if (Status != NDIS_STATUS_PENDING) { - PacketSendComplete( open, pPacket, Status ); - } - - return STATUS_PENDING; -} - -VOID -PacketSendComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET pPacket, - IN NDIS_STATUS Status -) -{ - PIRP irp; - PIO_STACK_LOCATION irpSp; - - // DebugPrint(("Packet: SendComplete :%x\n", Status)); - - irp = RESERVED(pPacket)->Irp; - irpSp = IoGetCurrentIrpStackLocation(irp); - - NdisFreePacket(pPacket); - - if(Status == NDIS_STATUS_SUCCESS) { - irp->IoStatus.Information = irpSp->Parameters.Write.Length; - irp->IoStatus.Status = STATUS_SUCCESS; - } else { - irp->IoStatus.Information = 0; - irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - } - - IoCompleteRequest(irp, IO_NO_INCREMENT); - IoDecrement((POPEN_INSTANCE)ProtocolBindingContext); -} diff --git a/BasiliskII/src/Windows/b2ether/packet32.cpp b/BasiliskII/src/Windows/b2ether/packet32.cpp deleted file mode 100755 index 72efb1fe..00000000 --- a/BasiliskII/src/Windows/b2ether/packet32.cpp +++ /dev/null @@ -1,694 +0,0 @@ -/* - * packet32.cpp - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "main.h" -#include "util_windows.h" -#include -#include -#include "cpu_emulation.h" -typedef unsigned long ULONG_PTR, *PULONG_PTR; - -// VC6 does not have this, Platform SDK has. -// In case of errors, try to comment out, the needed -// definitions are below (#ifndef _NTDDNDIS_) - -// Most people don't have the Platform SDK, so I take this one out. -// #include - -#include "inc/ntddpack.h" - -#include "ether.h" -#include "ether_defs.h" -#include "b2ether/multiopt.h" -#include "b2ether/inc/b2ether_hl.h" - - - -#ifndef _NTDDNDIS_ -#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 -#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 -#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 -#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 -#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 -#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 - -#define OID_802_3_PERMANENT_ADDRESS 0x01010101 -#define OID_802_3_CURRENT_ADDRESS 0x01010102 -#define OID_802_3_MULTICAST_LIST 0x01010103 - -#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E -#endif - -#define DEBUG_PACKETS 0 -#define DEBUG 0 -#include "debug.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if DEBUG -#pragma optimize("",off) -#endif - -#define MAX_MULTICAST 100 -#define MAX_MULTICAST_SZ (20*ETH_802_3_ADDRESS_LENGTH) - -static ULONG packet_filter = 0; - - -LPADAPTER PacketOpenAdapter( LPCTSTR AdapterName, int16 mode ) -{ - LPADAPTER lpAdapter; - BOOLEAN Result = TRUE; - - D(bug("Packet32: PacketOpenAdapter\n")); - - // May fail if user is not an Administrator. - StartPacketDriver( TEXT("B2ether") ); - - lpAdapter = (LPADAPTER)GlobalAllocPtr( GMEM_MOVEABLE|GMEM_ZEROINIT, sizeof(ADAPTER) ); - if (lpAdapter==NULL) { - D(bug("Packet32: PacketOpenAdapter GlobalAlloc Failed\n")); - return NULL; - } - - TCHAR device_name[256]; - _sntprintf(lpAdapter->SymbolicLink, lengthof(lpAdapter->SymbolicLink), TEXT("\\\\.\\B2ether_%s"), AdapterName ); - _sntprintf(device_name, lengthof(device_name), TEXT("\\Device\\B2ether_%s"), AdapterName ); - - // Work around one subtle NT4 bug. - DefineDosDevice( - DDD_REMOVE_DEFINITION, - &lpAdapter->SymbolicLink[4], - NULL - ); - DefineDosDevice( - DDD_RAW_TARGET_PATH, - &lpAdapter->SymbolicLink[4], - device_name - ); - - packet_filter = NDIS_PACKET_TYPE_DIRECTED | - NDIS_PACKET_TYPE_MULTICAST | - NDIS_PACKET_TYPE_BROADCAST; - - if(mode == ETHER_MULTICAST_ALL) packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; - if(mode == ETHER_MULTICAST_PROMISCUOUS) packet_filter |= NDIS_PACKET_TYPE_PROMISCUOUS; - - if (Result) { - lpAdapter->hFile = CreateFile(lpAdapter->SymbolicLink, - GENERIC_WRITE | GENERIC_READ, - 0, - NULL, - // (os == VER_PLATFORM_WIN32_NT) ? CREATE_ALWAYS : OPEN_EXISTING, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - 0 - ); - if (lpAdapter->hFile != INVALID_HANDLE_VALUE) { - if(*AdapterName && _tcscmp(AdapterName,TEXT("")) != 0) { - PacketSetFilter( lpAdapter, packet_filter ); - } - return lpAdapter; - } - } - D(bug("Packet32: PacketOpenAdapter Could not open adapter\n")); - GlobalFreePtr( lpAdapter ); - return NULL; -} - -VOID PacketCloseAdapter( LPADAPTER lpAdapter ) -{ - D(bug("Packet32: PacketCloseAdapter\n")); - - if(lpAdapter) { - if(lpAdapter->hFile) { - CloseHandle(lpAdapter->hFile); - } - GlobalFreePtr(lpAdapter); - } -} - -LPPACKET PacketAllocatePacket( LPADAPTER AdapterObject, UINT Length ) -{ - LPPACKET lpPacket; - - lpPacket = (LPPACKET)GlobalAllocPtr( GMEM_MOVEABLE|GMEM_ZEROINIT, sizeof(PACKET) ); - if(lpPacket==NULL) { - D(bug("Packet32: PacketAllocatePacket: GlobalAlloc Failed\n")); - return NULL; - } - - lpPacket->OverLapped.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); - if(!lpPacket->OverLapped.hEvent) { - D(bug("Packet32: PacketAllocatePacket: CreateEvent Failed\n")); - GlobalFreePtr(lpPacket); - return NULL; - } - - lpPacket->Buffer = GlobalAllocPtr(GMEM_MOVEABLE,2048); // 1514 - if(!lpPacket->Buffer) { - D(bug("Packet32: PacketAllocatePacket: GlobalAllocPtr Failed\n")); - if(lpPacket->OverLapped.hEvent) CloseHandle(lpPacket->OverLapped.hEvent); - GlobalFreePtr(lpPacket); - return NULL; - } - - lpPacket->OverLapped.Offset = 0; - lpPacket->OverLapped.OffsetHigh = 0; - lpPacket->Length = Length; - lpPacket->BytesReceived = 0; - lpPacket->bIoComplete = FALSE; - lpPacket->free = TRUE; - - return lpPacket; -} - -VOID PacketFreePacket( LPPACKET lpPacket ) -{ - if(lpPacket) { - if(lpPacket->Buffer) GlobalFreePtr(lpPacket->Buffer); - if(lpPacket->OverLapped.hEvent) CloseHandle(lpPacket->OverLapped.hEvent); - GlobalFreePtr(lpPacket); - } -} - -BOOLEAN PacketDeviceIoControl( - LPADAPTER lpAdapterObject, - LPPACKET lpPacket, - ULONG ulIoctl, - BOOLEAN bSync -) -{ - BOOLEAN Result; - - lpPacket->OverLapped.Offset = 0; - lpPacket->OverLapped.OffsetHigh = 0; - lpPacket->BytesReceived = 0; - - if ( !ResetEvent( lpPacket->OverLapped.hEvent ) ) { - lpPacket->bIoComplete = FALSE; - D(bug( "Packet32: PacketDeviceIoControl failed to reset event\r\n", GetLastError() )); - return FALSE; - } - - Result = DeviceIoControl( - lpAdapterObject->hFile, - ulIoctl, - lpPacket->Buffer, - lpPacket->Length, - lpPacket->Buffer, - lpPacket->Length, - &(lpPacket->BytesReceived), - &(lpPacket->OverLapped) ); - - if( !Result && bSync ) { - if (GetLastError() == ERROR_IO_PENDING) { - Result = GetOverlappedResult( lpAdapterObject->hFile, - &(lpPacket->OverLapped), - &(lpPacket->BytesReceived), - TRUE ); - } else { - D(bug( "Packet32: unsupported API call returned error 0x%x\r\n", GetLastError() )); - } - } - lpPacket->bIoComplete = Result; - return Result; -} - -VOID CALLBACK PacketSendCompletionRoutine( - DWORD dwErrorCode, - DWORD dwNumberOfBytesTransfered, - LPOVERLAPPED lpOverlapped -) -{ - LPPACKET lpPacket = CONTAINING_RECORD(lpOverlapped,PACKET,OverLapped); - -#if DEBUG_PACKETS - D(bug("PacketSendCompletionRoutine %d\n",dwNumberOfBytesTransfered)); -#endif - - lpPacket->bIoComplete = TRUE; - // lpPacket->free = TRUE; - // PacketFreePacket(lpPacket); - recycle_write_packet(lpPacket); -} - -BOOLEAN PacketSendPacket( - LPADAPTER AdapterObject, - LPPACKET lpPacket, - BOOLEAN Sync, - BOOLEAN RecyclingAllowed -) -{ - BOOLEAN Result; - -#if DEBUG_PACKETS - D(bug("Packet32: PacketSendPacket bytes=%d, sync=%d\n",lpPacket->Length,Sync)); -#endif - - lpPacket->OverLapped.Offset = 0; - lpPacket->OverLapped.OffsetHigh = 0; - lpPacket->bIoComplete = FALSE; - - if(Sync) { - Result = WriteFile( - AdapterObject->hFile, - lpPacket->Buffer, - lpPacket->Length, - &lpPacket->BytesReceived, - &lpPacket->OverLapped - ); - if(Result) { - Result = GetOverlappedResult( - AdapterObject->hFile, - &lpPacket->OverLapped, - &lpPacket->BytesReceived, - TRUE - ); - } else { - D(bug("Packet32: PacketSendPacket WriteFile failed, err=%d\n",(int)GetLastError())); - } - lpPacket->bIoComplete = TRUE; - if(RecyclingAllowed) PacketFreePacket(lpPacket); -#if DEBUG_PACKETS - D(bug("Packet32: PacketSendPacket result=%d, bytes=%d\n",(int)Result,(int)lpPacket->BytesReceived)); -#endif - } else { - // don't care about the result - Result = WriteFileEx( - AdapterObject->hFile, - lpPacket->Buffer, - lpPacket->Length, - &lpPacket->OverLapped, - PacketSendCompletionRoutine - ); -#if DEBUG_PACKETS - D(bug("Packet32: PacketSendPacket result=%d\n",(int)Result)); -#endif - if(!Result && RecyclingAllowed) { - recycle_write_packet(lpPacket); - } - } - - return Result; -} - -BOOLEAN PacketReceivePacket( - LPADAPTER AdapterObject, - LPPACKET lpPacket, - BOOLEAN Sync -) -{ - BOOLEAN Result; - - lpPacket->OverLapped.Offset=0; - lpPacket->OverLapped.OffsetHigh=0; - lpPacket->bIoComplete = FALSE; - -#if DEBUG_PACKETS - D(bug("Packet32: PacketReceivePacket\n")); -#endif - - if (Sync) { - Result = ReadFile( - AdapterObject->hFile, - lpPacket->Buffer, - lpPacket->Length, - &lpPacket->BytesReceived, - &lpPacket->OverLapped - ); - if(Result) { - Result = GetOverlappedResult( - AdapterObject->hFile, - &lpPacket->OverLapped, - &lpPacket->BytesReceived, - TRUE - ); - if(Result) - lpPacket->bIoComplete = TRUE; - else - lpPacket->free = TRUE; - } - } else { - Result = ReadFileEx( - AdapterObject->hFile, - lpPacket->Buffer, - lpPacket->Length, - &lpPacket->OverLapped, - packet_read_completion - ); - } - - if(!Result) lpPacket->BytesReceived = 0; - -#if DEBUG_PACKETS - D(bug("Packet32: PacketReceivePacket got %d bytes, result=%d\n",lpPacket->BytesReceived,(int)Result)); -#endif - - return Result; -} - -BOOLEAN PacketRequest( - LPADAPTER lpAdapterObject, - LPPACKET lpPacket, - BOOLEAN bSet -) -{ - BOOLEAN Result = FALSE; - - Result = PacketDeviceIoControl( - lpAdapterObject, - lpPacket, - (ULONG) ((bSet) ? IOCTL_PROTOCOL_SET_OID : IOCTL_PROTOCOL_QUERY_OID), - TRUE ); - - if ( lpPacket->BytesReceived == 0 ) { - D(bug( "Packet32: Ndis returned error to OID\r\n")); - Result = FALSE; - } - return Result; -} - -LPPACKET PacketQueryOid( - LPADAPTER lpAdapter, - ULONG ulOid, - ULONG ulLength -) -{ - ULONG ioctl; - LPPACKET lpPacket; - -#define pOidData ((PPACKET_OID_DATA)(lpPacket->Buffer)) - - lpPacket = PacketAllocatePacket( lpAdapter, sizeof(PACKET_OID_DATA)-1+ulLength ); - - if( lpPacket ) { - ioctl = IOCTL_PROTOCOL_QUERY_OID; - pOidData->Oid = ulOid; - pOidData->Length = ulLength; - - if (PacketRequest( lpAdapter, lpPacket, FALSE )) { - return lpPacket; - } - PacketFreePacket( lpPacket ); - } - -#undef pOidData - - return 0; -} - -BOOLEAN PacketGetMAC( LPADAPTER AdapterObject, LPBYTE address, BOOL permanent ) -{ - BOOLEAN Status; - LPPACKET lpPacket; - - lpPacket = PacketQueryOid( - AdapterObject, - permanent ? OID_802_3_PERMANENT_ADDRESS : OID_802_3_CURRENT_ADDRESS, - ETH_802_3_ADDRESS_LENGTH - ); - if(lpPacket) { - memcpy( address, - ((BYTE *)(lpPacket->Buffer)) + sizeof(PACKET_OID_DATA) - 1, - ETH_802_3_ADDRESS_LENGTH ); - PacketFreePacket( lpPacket ); - Status = TRUE; - } else { - Status = FALSE; - } - - return Status; -} - -// There are other ways to do this. - -BOOLEAN PacketAddMulticast( LPADAPTER AdapterObject, LPBYTE address ) -{ - BOOLEAN Status = FALSE; - LPBYTE p; - int i, count; - LPPACKET lpPacket; - - D(bug("PacketAddMulticast\n")); - - /* - if(packet_filter & (NDIS_PACKET_TYPE_ALL_MULTICAST|NDIS_PACKET_TYPE_PROMISCUOUS)) { - D(bug("PacketAddMulticast: already listening for all multicast\n")); - return TRUE; - } - */ - - lpPacket = PacketQueryOid( AdapterObject, OID_802_3_MULTICAST_LIST, MAX_MULTICAST_SZ ); -#define OidData ((PPACKET_OID_DATA)(lpPacket->Buffer)) - - if(lpPacket) { - count = OidData->Length / ETH_802_3_ADDRESS_LENGTH; - - D(bug("PacketAddMulticast: %d old addresses\n",count)); - - p = (LPBYTE)OidData->Data; - - for( i=0; i= MAX_MULTICAST) { - D(bug("PacketAddMulticast: too many addresses\n")); - Status = FALSE; - } else { - D(bug("PacketAddMulticast: adding a new address\n")); - - // ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA)+ETH_802_3_ADDRESS_LENGTH*1-1); - ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA)+ETH_802_3_ADDRESS_LENGTH*(count+1)-1); - - LPPACKET lpPacket2 = PacketAllocatePacket( AdapterObject, IoCtlBufferLength ); -#define OidData2 ((PPACKET_OID_DATA)(lpPacket2->Buffer)) - if ( lpPacket2 ) { - OidData2->Oid = OID_802_3_MULTICAST_LIST; - - // OidData2->Length = ETH_802_3_ADDRESS_LENGTH*1; - // memcpy( OidData2->Data, address, ETH_802_3_ADDRESS_LENGTH ); - - memcpy( OidData2->Data, OidData->Data, ETH_802_3_ADDRESS_LENGTH*count ); - memcpy( OidData2->Data+ETH_802_3_ADDRESS_LENGTH*count, address, ETH_802_3_ADDRESS_LENGTH ); - OidData2->Length = ETH_802_3_ADDRESS_LENGTH*(count+1); - - Status = PacketRequest( AdapterObject, lpPacket2, TRUE ); - PacketFreePacket( lpPacket2 ); - } -#undef OidData2 - } - } - PacketFreePacket( lpPacket ); - } - - #undef OidData - - // return Status; - return TRUE; -} - -// It seems that the last multicast address is never deleted. Why? -// Don't know the reason, but luckily this is not fatal. -// Hard to examine return codes. See NE2000 sources, always returns ok. - -BOOLEAN PacketDelMulticast( LPADAPTER AdapterObject, LPBYTE address ) -{ - BOOLEAN Status = FALSE; - LPBYTE p; - int i, count; - LPPACKET lpPacket, lpPacket2; - - D(bug("PacketDelMulticast\n")); - - if(packet_filter & (NDIS_PACKET_TYPE_ALL_MULTICAST|NDIS_PACKET_TYPE_PROMISCUOUS)) { - D(bug("PacketDelMulticast: already listening for all multicast\n")); - return TRUE; - } - - lpPacket = PacketQueryOid( AdapterObject, OID_802_3_MULTICAST_LIST, MAX_MULTICAST_SZ ); -#define OidData ((PPACKET_OID_DATA)(lpPacket->Buffer)) - - if(lpPacket) { - count = OidData->Length / ETH_802_3_ADDRESS_LENGTH; - - D(bug("PacketDelMulticast: %d old addresses\n",count)); - - Status = FALSE; - - p = (LPBYTE)OidData->Data; - - for( i=0; iBuffer)) - if ( lpPacket2 ) { - OidData2->Oid = OID_802_3_MULTICAST_LIST; - OidData2->Length = ETH_802_3_ADDRESS_LENGTH*(count-1); - tail_len = ETH_802_3_ADDRESS_LENGTH * (count-i-1); - if(tail_len) memmove( p, p+ETH_802_3_ADDRESS_LENGTH, tail_len ); - if(OidData2->Length) memcpy( OidData2->Data, OidData->Data, OidData2->Length ); - if(count == 1) memset( OidData2->Data, 0, ETH_802_3_ADDRESS_LENGTH ); // eh... - Status = PacketRequest( AdapterObject, lpPacket2, TRUE ); - PacketFreePacket( lpPacket2 ); - D(bug("PacketDelMulticast: PacketRequest returned status 0x%X, last error = 0x%X\n",Status,GetLastError())); - } - break; -#undef OidData2 - } - p += ETH_802_3_ADDRESS_LENGTH; - } - if( i == count ) { - D(bug("PacketDelMulticast: cannot delete, was not defined\n")); - } - PacketFreePacket( lpPacket ); -#undef OidData - } - - // return Status; - return TRUE; -} - -BOOLEAN PacketSetFilter( LPADAPTER AdapterObject, ULONG Filter ) -{ - BOOLEAN Status; - ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); - LPPACKET lpPacket; - - lpPacket = PacketAllocatePacket( AdapterObject, IoCtlBufferLength ); -#define lpOidData ((PPACKET_OID_DATA)(lpPacket->Buffer)) - - if ( lpPacket ) { - lpOidData->Oid = OID_GEN_CURRENT_PACKET_FILTER; - lpOidData->Length = sizeof(ULONG); - *((PULONG)lpOidData->Data) = Filter; - Status = PacketRequest( AdapterObject, lpPacket, TRUE ); - PacketFreePacket( lpPacket ); - } else { - Status = FALSE; - } - -#undef lpOidData - - return Status; -} - -BOOLEAN StartPacketDriver( LPCTSTR ServiceName ) -{ - BOOLEAN Status = FALSE; - - SC_HANDLE SCManagerHandle; - SC_HANDLE SCServiceHandle; - - SCManagerHandle = OpenSCManager( - NULL, - NULL, - SC_MANAGER_ALL_ACCESS); - - if(SCManagerHandle == NULL) { - D(bug("Could not open Service Control Manager\r\n")); - } else { - SCServiceHandle = OpenService(SCManagerHandle,ServiceName,SERVICE_START); - if (SCServiceHandle == NULL) { - D(bug(TEXT("Could not open service %s\r\n"),ServiceName)); - } else { - Status = StartService( SCServiceHandle, 0, NULL ); - if(!Status) { - if (GetLastError()==ERROR_SERVICE_ALREADY_RUNNING) { - Status = TRUE; - } - } - BOOL waiting = TRUE; - // loop until the service is fully started. - while (waiting) { - SERVICE_STATUS ServiceStatus; - if (QueryServiceStatus(SCServiceHandle, &ServiceStatus)) { - switch(ServiceStatus.dwCurrentState) { - case SERVICE_RUNNING: - waiting = FALSE; - Status = TRUE; - break; - case SERVICE_START_PENDING: - Sleep(500); - break; - default: - waiting = FALSE; - break; - } - } else { - waiting = FALSE; - } - } - CloseServiceHandle(SCServiceHandle); - } - CloseServiceHandle(SCManagerHandle); - } - return Status; -} - -ULONG PacketGetAdapterNames( LPADAPTER lpAdapter, LPTSTR pStr, PULONG BufferSize ) -{ - LONG Status; - - HKEY hKey; - DWORD RegType; - - Status = RegOpenKey( - HKEY_LOCAL_MACHINE, - TEXT("SYSTEM\\CurrentControlSet\\Services\\B2Ether\\Linkage"), - &hKey - ); - if( Status == ERROR_SUCCESS ) { - Status = RegQueryValueEx( - hKey, - TEXT("Export"), - NULL, - &RegType, - (LPBYTE)pStr, - BufferSize - ); - RegCloseKey(hKey); - } - - return Status; -} - -#ifdef __cplusplus -} -#endif - -#if DEBUG -#pragma optimize("",on) -#endif diff --git a/BasiliskII/src/Windows/build68k.vcxproj b/BasiliskII/src/Windows/build68k.vcxproj deleted file mode 100644 index b29e072d..00000000 --- a/BasiliskII/src/Windows/build68k.vcxproj +++ /dev/null @@ -1,156 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} - Win32Proj - build68k - 8.1 - - - - Application - true - v140 - Unicode - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - Application - false - v140 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - $(Configuration)\$(ProjectName)\ - - - true - - - false - $(Configuration)\$(ProjectName)\ - - - false - - - - - - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - - - - - - - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - true - true - - - - - - - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/build68k.vcxproj.filters b/BasiliskII/src/Windows/build68k.vcxproj.filters deleted file mode 100644 index 65e38167..00000000 --- a/BasiliskII/src/Windows/build68k.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/cd_defs.h b/BasiliskII/src/Windows/cd_defs.h deleted file mode 100755 index f58069e5..00000000 --- a/BasiliskII/src/Windows/cd_defs.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * cd_defs.h - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define MAXIMUM_NUMBER_TRACKS 100 -#define MAXIMUM_CDROM_SIZE 804 - -#pragma pack(push, 1) - -typedef struct _TRACK_DATA { - UCHAR Reserved; - UCHAR Control : 4; - UCHAR Adr : 4; - UCHAR TrackNumber; - UCHAR Reserved1; - UCHAR Address[4]; -} TRACK_DATA, *PTRACK_DATA; - -typedef struct _CDROM_TOC { - UCHAR Length[2]; - UCHAR FirstTrack; - UCHAR LastTrack; - TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]; -} CDROM_TOC, *PCDROM_TOC; - -// #include "ntddcdrm.h" -#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM -#define IOCTL_CDROM_UNLOAD_DRIVER CTL_CODE(IOCTL_CDROM_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS) -// -// CDROM Audio Device Control Functions -// -#define IOCTL_CDROM_READ_TOC CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_GET_CONTROL CTL_CODE(IOCTL_CDROM_BASE, 0x000D, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_PLAY_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0006, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_SEEK_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_STOP_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0002, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_PAUSE_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0003, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_RESUME_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_GET_VOLUME CTL_CODE(IOCTL_CDROM_BASE, 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_SET_VOLUME CTL_CODE(IOCTL_CDROM_BASE, 0x000A, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_READ_Q_CHANNEL CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_GET_LAST_SESSION CTL_CODE(IOCTL_CDROM_BASE, 0x000E, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS) -#define IOCTL_CDROM_DISK_TYPE CTL_CODE(IOCTL_CDROM_BASE, 0x0010, METHOD_BUFFERED, FILE_ANY_ACCESS) - -typedef struct _VOLUME_CONTROL { - UCHAR PortVolume[4]; -} VOLUME_CONTROL, *PVOLUME_CONTROL; - -typedef struct _CDROM_PLAY_AUDIO_MSF { - UCHAR StartingM; - UCHAR StartingS; - UCHAR StartingF; - UCHAR EndingM; - UCHAR EndingS; - UCHAR EndingF; -} CDROM_PLAY_AUDIO_MSF, *PCDROM_PLAY_AUDIO_MSF; - -typedef struct _CDROM_SEEK_AUDIO_MSF { - UCHAR M; - UCHAR S; - UCHAR F; -} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF; - - -// -// CD ROM Sub-Q Channel Data Format -// - -typedef struct _SUB_Q_HEADER { - UCHAR Reserved; - UCHAR AudioStatus; - UCHAR DataLength[2]; -} SUB_Q_HEADER, *PSUB_Q_HEADER; - -typedef struct _SUB_Q_CURRENT_POSITION { - SUB_Q_HEADER Header; - UCHAR FormatCode; - UCHAR Control : 4; - UCHAR ADR : 4; - UCHAR TrackNumber; - UCHAR IndexNumber; - UCHAR AbsoluteAddress[4]; - UCHAR TrackRelativeAddress[4]; -} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION; - -typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER { - SUB_Q_HEADER Header; - UCHAR FormatCode; - UCHAR Reserved[3]; - UCHAR Reserved1 : 7; - UCHAR Mcval : 1; - UCHAR MediaCatalog[15]; -} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER; - -typedef struct _SUB_Q_TRACK_ISRC { - SUB_Q_HEADER Header; - UCHAR FormatCode; - UCHAR Reserved0; - UCHAR Track; - UCHAR Reserved1; - UCHAR Reserved2 : 7; - UCHAR Tcval : 1; - UCHAR TrackIsrc[15]; -} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC; - -typedef union _SUB_Q_CHANNEL_DATA { - SUB_Q_CURRENT_POSITION CurrentPosition; - SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog; - SUB_Q_TRACK_ISRC TrackIsrc; -} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA; - -typedef enum _TRACK_MODE_TYPE { - YellowMode2, - XAForm2, - CDDA -} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE; - -typedef struct __RAW_READ_INFO { - LARGE_INTEGER DiskOffset; - ULONG SectorCount; - TRACK_MODE_TYPE TrackMode; -} RAW_READ_INFO, *PRAW_READ_INFO; - -typedef struct _CDROM_SUB_Q_DATA_FORMAT { - UCHAR Format; - UCHAR Track; -} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT; - -#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00 -#define IOCTL_CDROM_CURRENT_POSITION 0x01 -#define IOCTL_CDROM_MEDIA_CATALOG 0x02 -#define IOCTL_CDROM_TRACK_ISRC 0x03 - -#pragma pack(pop) diff --git a/BasiliskII/src/Windows/cdenable/cache.cpp b/BasiliskII/src/Windows/cdenable/cache.cpp deleted file mode 100755 index 483f3ca1..00000000 --- a/BasiliskII/src/Windows/cdenable/cache.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * cache.cpp - simple floppy/cd cache for Win32 - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - Note that this is particularly silly cache code - and doesn't even use hash buckets. It is sufficient - for floppies and maybe emulated cd's but that's it. -*/ - -#include "sysdeps.h" -#include "cache.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -void cache_clear( cachetype *cptr ) -{ - if(cptr->inited) { - cptr->res_count = 0; - memset( cptr->LRU, 0, NBLOCKS * sizeof(int) ); - } -} - -static int init( cachetype *cptr, int sector_size ) -{ - cache_clear( cptr ); - cptr->sector_size = sector_size; - cptr->blocks = (char *)VirtualAlloc( - NULL, NBLOCKS*sector_size, - MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE ); - cptr->block = (int *)VirtualAlloc( - NULL, NBLOCKS*sizeof(int), - MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE ); - cptr->LRU = (DWORD *)VirtualAlloc( - NULL, NBLOCKS*sizeof(DWORD), - MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE ); - return(cptr->blocks != NULL); -} - -static void final( cachetype *cptr ) -{ - if(cptr->blocks) { - VirtualFree( cptr->blocks, 0, MEM_RELEASE ); - cptr->blocks = 0; - } - if(cptr->block) { - VirtualFree( cptr->block, 0, MEM_RELEASE ); - cptr->block = 0; - } - if(cptr->LRU) { - VirtualFree( cptr->LRU, 0, MEM_RELEASE ); - cptr->LRU = 0; - } - cptr->inited = 0; -} - -void cache_init( cachetype *cptr ) -{ - cptr->inited = 0; -} - -void cache_final( cachetype *cptr ) -{ - if(cptr->inited) { - final( cptr ); - cptr->inited = 0; - } -} - -static int in_cache( cachetype *cptr, int block ) -{ - int i; - for(i=cptr->res_count-1; i>=0; i--) { - if(cptr->block[i] == block) return(i); - } - return(-1); -} - -static int get_LRU( cachetype *cptr ) -{ - int i, result = 0; - DWORD mtime = cptr->LRU[0]; - - for(i=1; iLRU[i] < mtime) { - mtime = cptr->LRU[i]; - result = i; - } - } - return(result); -} - -void cache_put( cachetype *cptr, int block, char *buf, int ss ) -{ - int inx; - - if(!cptr->inited) { - if(!init(cptr,ss)) return; - cptr->inited = 1; - } - inx = in_cache( cptr, block ); - if(inx < 0) { - if(cptr->res_count == NBLOCKS) { - inx = get_LRU( cptr ); - } else { - inx = cptr->res_count++; - } - cptr->block[inx] = block; - } - cptr->LRU[inx] = GetTickCount(); - memcpy( cptr->blocks + inx * ss, buf, ss ); -} - -int cache_get( cachetype *cptr, int block, char *buf ) -{ - int inx; - - if(!cptr->inited) return(0); - - inx = in_cache( cptr, block ); - if(inx >= 0) { - memcpy( buf, cptr->blocks + inx * cptr->sector_size, cptr->sector_size ); - return(1); - } else { - return(0); - } -} - -void cache_remove( cachetype *cptr, int block, int ss ) -{ - int inx, from; - - if(!cptr->inited) { - if(!init(cptr,ss)) return; - cptr->inited = 1; - } - inx = in_cache( cptr, block ); - if(inx >= 0) { - if(cptr->res_count > 1) { - from = cptr->res_count-1; - cptr->block[inx] = cptr->block[from]; - cptr->LRU[inx] = cptr->LRU[from]; - memcpy( - cptr->blocks + inx * cptr->sector_size, - cptr->blocks + from * cptr->sector_size, - cptr->sector_size - ); - } - cptr->res_count--; - } -} - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/BasiliskII/src/Windows/cdenable/cache.h b/BasiliskII/src/Windows/cdenable/cache.h deleted file mode 100755 index 14607bef..00000000 --- a/BasiliskII/src/Windows/cdenable/cache.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * cache.cpp - simple floppy/cd cache for Win32 - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _CACHE_H_ -#define _CACHE_H_ -#define NBLOCKS 1000 - -typedef struct { - int inited; - int res_count; - int sector_size; - char *blocks; - int *block; - DWORD *LRU; -} cachetype; - -void cache_init( cachetype *cptr ); -void cache_clear( cachetype *cptr ); -void cache_final( cachetype *cptr ); -int cache_get( cachetype *cptr, int block, char *buf ); -void cache_put( cachetype *cptr, int block, char *buf, int ss ); -void cache_remove( cachetype *cptr, int block, int ss ); -#endif - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/BasiliskII/src/Windows/cdenable/cdenable.h b/BasiliskII/src/Windows/cdenable/cdenable.h deleted file mode 100755 index 26b90242..00000000 --- a/BasiliskII/src/Windows/cdenable/cdenable.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * cdenable.h - cdenable.vxd definitions - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// max read requests, if larger -> STATUS_INVALID_PARAMETER -#define CDENABLE_MAX_TRANSFER_SIZE (0x10000) - - -// A structure representing the instance information associated with -// a particular device -typedef struct _DEVICE_EXTENSION -{ - // not needed. - ULONG StateVariable; -} DEVICE_EXTENSION, *PDEVICE_EXTENSION; - - -// Define the various device type values. Note that values used by Microsoft -// Corporation are in the range 0-32767, and 32768-65535 are reserved for use -// by customers. -#define FILE_DEVICE_CDENABLE 0x00008301 - - -// Target NT version, internal version -#define CDENABLE_CURRENT_VERSION 0x04000100 - - -// Macro definition for defining IOCTL and FSCTL function control codes. Note -// that function codes 0-2047 are reserved for Microsoft Corporation, and -// 2048-4095 are reserved for customers. -#define CDENABLE_IOCTL_READ 0x830 -#define CDENABLE_IOCTL_GET_VERSION 0x831 - - -#define IOCTL_CDENABLE_READ CTL_CODE(FILE_DEVICE_CDENABLE, \ - CDENABLE_IOCTL_READ, \ - METHOD_BUFFERED, \ - FILE_ANY_ACCESS) -#define IOCTL_CDENABLE_GET_VERSION CTL_CODE(FILE_DEVICE_CDENABLE, \ - CDENABLE_IOCTL_GET_VERSION, \ - METHOD_BUFFERED, \ - FILE_ANY_ACCESS) diff --git a/BasiliskII/src/Windows/cdenable/eject_nt.cpp b/BasiliskII/src/Windows/cdenable/eject_nt.cpp deleted file mode 100755 index 414ce4b9..00000000 --- a/BasiliskII/src/Windows/cdenable/eject_nt.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - * eject_nt.cpp - cd eject routines for WinNT (derived from MS samples) - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include - -// Prototypes - -extern "C" { - -#include "eject_nt.h" - -LPTSTR szVolumeFormat = TEXT("\\\\.\\%c:"); -LPTSTR szRootFormat = TEXT("%c:\\"); -LPTSTR szErrorFormat = TEXT("Error %d: %s\n"); - -void ReportError(LPTSTR szMsg) -{ - // _tprintf(szErrorFormat, GetLastError(), szMsg); -} - -HANDLE OpenVolume(TCHAR cDriveLetter) -{ - HANDLE hVolume; - UINT uDriveType; - TCHAR szVolumeName[8]; - TCHAR szRootName[5]; - DWORD dwAccessFlags; - - wsprintf(szRootName, szRootFormat, cDriveLetter); - - uDriveType = GetDriveType(szRootName); - switch(uDriveType) { - case DRIVE_REMOVABLE: - dwAccessFlags = GENERIC_READ | GENERIC_WRITE; - break; - case DRIVE_CDROM: - dwAccessFlags = GENERIC_READ; - break; - default: - // _tprintf(TEXT("Cannot eject. Drive type is incorrect.\n")); - return INVALID_HANDLE_VALUE; - } - - wsprintf(szVolumeName, szVolumeFormat, cDriveLetter); - - hVolume = CreateFile( szVolumeName, - dwAccessFlags, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - 0, - NULL ); - if (hVolume == INVALID_HANDLE_VALUE) - ReportError(TEXT("CreateFile")); - - return hVolume; -} - -BOOL CloseVolume(HANDLE hVolume) -{ - return CloseHandle(hVolume); -} - -#define LOCK_TIMEOUT 1000 // 1 second -#define LOCK_RETRIES 20 - -BOOL LockVolume(HANDLE hVolume) -{ - DWORD dwBytesReturned; - DWORD dwSleepAmount; - int nTryCount; - - dwSleepAmount = LOCK_TIMEOUT / LOCK_RETRIES; - - // Do this in a loop until a timeout period has expired - for (nTryCount = 0; nTryCount < LOCK_RETRIES; nTryCount++) { - if (DeviceIoControl(hVolume, - FSCTL_LOCK_VOLUME, - NULL, 0, - NULL, 0, - &dwBytesReturned, - NULL)) - return TRUE; - - Sleep(dwSleepAmount); - } - - return FALSE; -} - -BOOL DismountVolume(HANDLE hVolume) -{ - DWORD dwBytesReturned; - - return DeviceIoControl( hVolume, - FSCTL_DISMOUNT_VOLUME, - NULL, 0, - NULL, 0, - &dwBytesReturned, - NULL); -} - -BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval) -{ - DWORD dwBytesReturned; - PREVENT_MEDIA_REMOVAL PMRBuffer; - - PMRBuffer.PreventMediaRemoval = fPreventRemoval; - - return DeviceIoControl( hVolume, - IOCTL_STORAGE_MEDIA_REMOVAL, - &PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL), - NULL, 0, - &dwBytesReturned, - NULL); -} - -BOOL AutoEjectVolume( HANDLE hVolume, BOOL reload ) -{ - DWORD dwBytesReturned; - - return DeviceIoControl( hVolume, - reload ? IOCTL_STORAGE_LOAD_MEDIA : IOCTL_STORAGE_EJECT_MEDIA, - NULL, 0, - NULL, 0, - &dwBytesReturned, - NULL); -} - -BOOL EjectVolume( TCHAR cDriveLetter, BOOL reload ) -{ - HANDLE hVolume; - - BOOL fRemoveSafely = FALSE; - BOOL fAutoEject = FALSE; - - // Open the volume. - hVolume = OpenVolume(cDriveLetter); - if (hVolume == INVALID_HANDLE_VALUE) - return FALSE; - - // Lock and dismount the volume. - if (LockVolume(hVolume) && DismountVolume(hVolume)) { - fRemoveSafely = TRUE; - - // Set prevent removal to false and eject the volume. - if (PreventRemovalOfVolume(hVolume, FALSE) && - AutoEjectVolume(hVolume,reload)) - fAutoEject = TRUE; - } - - // Close the volume so other processes can use the drive. - if (!CloseVolume(hVolume)) - return FALSE; - - /* - if (fAutoEject) - printf("Media in Drive %c has been ejected safely.\n", cDriveLetter); - else { - if (fRemoveSafely) - printf("Media in Drive %c can be safely removed.\n", cDriveLetter); - } - */ - - return TRUE; -} - -} // extern "C" diff --git a/BasiliskII/src/Windows/cdenable/eject_nt.h b/BasiliskII/src/Windows/cdenable/eject_nt.h deleted file mode 100755 index 88272cc6..00000000 --- a/BasiliskII/src/Windows/cdenable/eject_nt.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * eject_nt.cpp - cd eject routines for WinNT (derived from MS samples) - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _EJECT_NT_H_ -#define _EJECT_NT_H_ - - -#ifdef __cplusplus -extern "C" { -#endif - -BOOL EjectVolume(TCHAR cDriveLetter,BOOL reload); - -HANDLE OpenVolume(TCHAR cDriveLetter); -BOOL LockVolume(HANDLE hVolume); -BOOL DismountVolume(HANDLE hVolume); -BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPrevent); -BOOL AutoEjectVolume(HANDLE hVolume,BOOL reload); -BOOL CloseVolume(HANDLE hVolume); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif //_EJECT_NT_H_ diff --git a/BasiliskII/src/Windows/cdenable/ntcd.cpp b/BasiliskII/src/Windows/cdenable/ntcd.cpp deleted file mode 100755 index acefb13c..00000000 --- a/BasiliskII/src/Windows/cdenable/ntcd.cpp +++ /dev/null @@ -1,344 +0,0 @@ -/* - * ntcd.cpp - Interface to cdenable.sys driver - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -extern "C" { - -#include -#include -#include "ntcd.h" -#include "cdenable.h" - -static LPCTSTR sDriverShort = TEXT("cdenable"); -static LPCTSTR sDriverLong = TEXT("System32\\Drivers\\cdenable.sys"); -static LPCTSTR sCompleteName = TEXT("\\\\.\\cdenable"); - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -// Start type must be SERVICE_AUTO_START or lower, in order -// it to start automatically and allow the mechanism work -// for users with no admin rights. -static BOOL InstallDriver( - IN SC_HANDLE SchSCManager, - IN LPCTSTR DriverName, - IN LPCTSTR ServiceExe -) -{ - SC_HANDLE schService; - DWORD err; - - schService = CreateService ( - SchSCManager, // SCManager database - DriverName, // name of service - DriverName, // name to display - SERVICE_ALL_ACCESS, // desired access - SERVICE_KERNEL_DRIVER, // service type - SERVICE_AUTO_START, // SERVICE_DEMAND_START, // start type - SERVICE_ERROR_NORMAL, // error control type - ServiceExe, // service's binary - NULL, // no load ordering group - NULL, // no tag identifier - NULL, // no dependencies - NULL, // LocalSystem account - NULL // no password - ); - - if (schService == NULL) { - err = GetLastError(); - if (err == ERROR_SERVICE_EXISTS) { - return TRUE; - } else { - return FALSE; - } - } - CloseServiceHandle (schService); - return TRUE; -} - -static BOOL RemoveDriver( - IN SC_HANDLE SchSCManager, - IN LPCTSTR DriverName -) -{ - SC_HANDLE schService; - BOOL ret; - - schService = OpenService (SchSCManager, - DriverName, - SERVICE_ALL_ACCESS - ); - if (schService == NULL) return FALSE; - ret = DeleteService (schService); - CloseServiceHandle (schService); - return ret; -} - -static BOOL StartDriver( - IN SC_HANDLE SchSCManager, - IN LPCTSTR DriverName -) { - SC_HANDLE schService; - BOOL ret; - DWORD err; - - schService = OpenService (SchSCManager, - DriverName, - SERVICE_ALL_ACCESS - ); - if (schService == NULL) return FALSE; - ret = StartService (schService, // service identifier - 0, // number of arguments - NULL // pointer to arguments - ); - if(ret == 0) { - err = GetLastError(); - if (err == ERROR_SERVICE_ALREADY_RUNNING) { - ret = TRUE; - } else { - ret = FALSE; - } - } - CloseServiceHandle (schService); - return ret; -} - -static BOOL StopDriver( - IN SC_HANDLE SchSCManager, - IN LPCTSTR DriverName -) -{ - SC_HANDLE schService; - BOOL ret; - SERVICE_STATUS serviceStatus; - - schService = OpenService (SchSCManager, - DriverName, - SERVICE_ALL_ACCESS - ); - if (schService == NULL) return FALSE; - ret = ControlService (schService, - SERVICE_CONTROL_STOP, - &serviceStatus - ); - CloseServiceHandle (schService); - return ret; -} - -static BOOL __cdecl start_driver( void ) -{ - SC_HANDLE schSCManager; - BOOL ret = FALSE; - - schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); - if(!schSCManager) return(FALSE); - if(!InstallDriver( schSCManager, sDriverShort, sDriverLong )) { - CloseServiceHandle( schSCManager ); - return(FALSE); - } - ret = StartDriver( schSCManager, sDriverShort ); - if(!ret) { - (void)RemoveDriver( schSCManager, sDriverShort ); - } - CloseServiceHandle( schSCManager ); - return( ret ); -} - -static BOOL __cdecl stop_driver( void ) -{ - SC_HANDLE schSCManager; - BOOL ret = FALSE; - - schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); - if(!schSCManager) return(FALSE); - if(StopDriver( schSCManager, sDriverShort )) ret = TRUE; - CloseServiceHandle( schSCManager ); - return( ret ); -} - -static BOOL __cdecl remove_driver( void ) -{ - SC_HANDLE schSCManager; - BOOL ret = FALSE; - - schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); - if(!schSCManager) return(FALSE); - if(RemoveDriver( schSCManager, sDriverShort )) ret = TRUE; - CloseServiceHandle( schSCManager ); - return( ret ); -} - - - -// Exported stuff begins - -int CdenableSysReadCdBytes( HANDLE h, DWORD start, DWORD count, char *buf ) -{ - HANDLE hDevice; - int ret; - DWORD nb; - DWORD in_buffer[10]; - DWORD out_buffer[10]; - - ret = 0; - - in_buffer[0] = (DWORD)h; - in_buffer[1] = (DWORD)start; - in_buffer[2] = (DWORD)count; - in_buffer[3] = (DWORD)buf; - out_buffer[0] = 0; - - hDevice = CreateFile (sCompleteName, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL - ); - - if (hDevice == ((HANDLE)-1)) { - ret = 0; - } else { - if ( DeviceIoControl( hDevice, - IOCTL_CDENABLE_READ, - (LPVOID)in_buffer, 16, - (LPVOID)out_buffer, 4, - &nb, NULL ) ) - { - if(out_buffer[0] != 0) ret = count; - } - CloseHandle (hDevice); - } - - return ret; -} - -int CdenableSysReadCdSectors( HANDLE h, DWORD start, DWORD count, char *buf ) -{ - return( CdenableSysReadCdBytes( h, (start<<11), (count<<11), buf ) ); -} - -int CdenableSysWriteCdBytes( HANDLE h, DWORD start, DWORD count, char *buf ) -{ - return( 0 ); - - /* - HANDLE hDevice; - int ret; - DWORD nb; - DWORD in_buffer[10]; - DWORD out_buffer[10]; - - ret = 0; - - in_buffer[0] = (DWORD)h; - in_buffer[1] = (DWORD)start; - in_buffer[2] = (DWORD)count; - in_buffer[3] = (DWORD)buf; - out_buffer[0] = 0; - - hDevice = CreateFile (sCompleteName, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL - ); - - if (hDevice == ((HANDLE)-1)) { - ret = 0; - } else { - if ( DeviceIoControl( hDevice, - IOCTL_CDENABLE_WRITE, - (LPVOID)in_buffer, 16, - (LPVOID)out_buffer, 4, - &nb, NULL ) ) - { - if(out_buffer[0] != 0) ret = count; - } - CloseHandle (hDevice); - } - - return ret; - */ -} - -int CdenableSysWriteCdSectors( HANDLE h, DWORD start, DWORD count, char *buf ) -{ - // return( CdenableSysWriteCdBytes( h, (start<<11), (count<<11), buf ) ); - return( 0 ); -} - -BOOL CdenableSysInstallStart(void) -{ - return(start_driver()); -} - -void CdenableSysStopRemove(void) -{ - stop_driver(); - remove_driver(); -} - -DWORD CdenableSysGetVersion( void ) -{ - HANDLE hDevice; - DWORD ret; - DWORD nb; - DWORD out_buffer[10]; - - ret = 0; - out_buffer[0] = 0; - hDevice = CreateFile (sCompleteName, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL - ); - if (hDevice == ((HANDLE)-1)) { - ret = 0; - } else { - if ( DeviceIoControl( hDevice, - IOCTL_CDENABLE_GET_VERSION, - NULL, 0, - (LPVOID)out_buffer, 4, - &nb, NULL ) ) - { - ret = out_buffer[0]; - } - CloseHandle (hDevice); - } - return ret; -} - -#ifdef __cplusplus -} //extern "C" -#endif - diff --git a/BasiliskII/src/Windows/cdenable/ntcd.h b/BasiliskII/src/Windows/cdenable/ntcd.h deleted file mode 100755 index 8be3193e..00000000 --- a/BasiliskII/src/Windows/cdenable/ntcd.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * ntcd.h - Interface to cdenable.sys driver - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -/* - Installs the driver, if not already installed. - Starts the driver, if not already running. - - You can either always call "CdenableSysInstallStart" when your - program fires up and "CdenableSysStopRemove" when it terminates, - or just let the installation program call "CdenableSysInstallStart" - and leave it always be present. - - I recommend the latter option. Calling "CdenableSysInstallStart" - always doesn't hurt anything, it will immediately return - with success if the service is running. - - Returns non-zero if installation/startup was succesfull, - zero if anything failed. - Returns non-zero also if the driver was already running. - - The file "cdenable.sys" must already have been copied to - the directory "System32\Drivers" -*/ - -#ifndef _NT_CD_H_ -#define _NT_CD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - -BOOL CdenableSysInstallStart(void); - - -/* - Stops and removes the driver. See above. - This must be called when new version of the driver is updated. -*/ -void CdenableSysStopRemove(void); - - -/* - HANDLE h: returned from CreateFile ( "\\\\.\\X:", GENERIC_READ, ... ); - Returns the bytes actually read (==count), 0 on failure. - NOTE: in my code, start and count are always aligned to - sector boundaries (2048 bytes). - I cannot guarantee that this works if they are not. - Max read is 64 kb. - Synchronous read, but quite fast. -*/ -int CdenableSysReadCdBytes( HANDLE h, DWORD start, DWORD count, char *buf ); - - -/* - Same as SysReadCdBytes, but "start" and "count" are in 2048 byte - sectors. -*/ -int CdenableSysReadCdSectors( HANDLE h, DWORD start, DWORD count, char *buf ); - - -/* - Ditto for writing stuff. - Not a cd of course but removable & hd media are supported now. -*/ -int CdenableSysWriteCdBytes( HANDLE h, DWORD start, DWORD count, char *buf ); -int CdenableSysWriteCdSectors( HANDLE h, DWORD start, DWORD count, char *buf ); - - -/* - Returns CDENABLE_CURRENT_VERSION (of the driver). -*/ -DWORD CdenableSysGetVersion( void ); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif //_NT_CD_H_ diff --git a/BasiliskII/src/Windows/clip_windows.cpp b/BasiliskII/src/Windows/clip_windows.cpp deleted file mode 100755 index c4ee65bc..00000000 --- a/BasiliskII/src/Windows/clip_windows.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - * clip_windows.cpp - Clipboard handling, Windows implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include - -#include "macos_util.h" -#include "clip.h" -#include "prefs.h" -#include "cpu_emulation.h" -#include "main.h" -#include "emul_op.h" - -#define DEBUG 0 -#include "debug.h" - -#ifndef NO_STD_NAMESPACE -using std::vector; -#endif - - -// Conversion tables -static const uint8 mac2iso[0x80] = { - 0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1, - 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8, - 0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3, - 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc, - 0x2b, 0xb0, 0xa2, 0xa3, 0xa7, 0xb7, 0xb6, 0xdf, - 0xae, 0xa9, 0x20, 0xb4, 0xa8, 0x23, 0xc6, 0xd8, - 0x20, 0xb1, 0x3c, 0x3e, 0xa5, 0xb5, 0xf0, 0x53, - 0x50, 0x70, 0x2f, 0xaa, 0xba, 0x4f, 0xe6, 0xf8, - 0xbf, 0xa1, 0xac, 0x2f, 0x66, 0x7e, 0x44, 0xab, - 0xbb, 0x2e, 0x20, 0xc0, 0xc3, 0xd5, 0x4f, 0x6f, - 0x2d, 0x2d, 0x22, 0x22, 0x60, 0x27, 0xf7, 0x20, - 0xff, 0x59, 0x2f, 0xa4, 0x3c, 0x3e, 0x66, 0x66, - 0x23, 0xb7, 0x2c, 0x22, 0x25, 0xc2, 0xca, 0xc1, - 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4, - 0x20, 0xd2, 0xda, 0xdb, 0xd9, 0x69, 0x5e, 0x7e, - 0xaf, 0x20, 0xb7, 0xb0, 0xb8, 0x22, 0xb8, 0x20 -}; - -static const uint8 iso2mac[0x80] = { - 0xad, 0xb0, 0xe2, 0xc4, 0xe3, 0xc9, 0xa0, 0xe0, - 0xf6, 0xe4, 0xde, 0xdc, 0xce, 0xb2, 0xb3, 0xb6, - 0xb7, 0xd4, 0xd5, 0xd2, 0xd3, 0xa5, 0xd0, 0xd1, - 0xf7, 0xaa, 0xdf, 0xdd, 0xcf, 0xba, 0xfd, 0xd9, - 0xca, 0xc1, 0xa2, 0xa3, 0xdb, 0xb4, 0xbd, 0xa4, - 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0xf0, 0xa8, 0xf8, - 0xa1, 0xb1, 0xc3, 0xc5, 0xab, 0xb5, 0xa6, 0xe1, - 0xfc, 0xc6, 0xbc, 0xc8, 0xf9, 0xda, 0xd7, 0xc0, - 0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, - 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, - 0xf5, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0xfb, - 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0xfa, 0xb8, 0xa7, - 0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, - 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, - 0xfe, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, - 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0xff, 0xb9, 0xd8 -}; - -// Flag: Don't convert clipboard text -static bool no_clip_conversion; - -// Flag for PutScrap(): the data was put by GetScrap(), don't bounce it back to the Windows side -static bool we_put_this_data = false; - -// Define a byte array (rewrite if it's a bottleneck) -struct ByteArray : public vector { - uint8 *data() { return &(*this)[0]; } -}; - -// Prototypes -static void do_putscrap(uint32 type, void *scrap, int32 length); -static void do_getscrap(void **handle, uint32 type, int32 offset); - -// From main_windows.cpp -extern HWND GetMainWindowHandle(void); - - -/* - * Initialization - */ - -void ClipInit(void) -{ - no_clip_conversion = PrefsFindBool("noclipconversion"); -} - - -/* - * Deinitialization - */ - -void ClipExit(void) -{ -} - - -/* - * Mac application wrote to clipboard - */ - -void PutScrap(uint32 type, void *scrap, int32 length) -{ - D(bug("PutScrap type %08lx, data %p, length %ld\n", type, scrap, length)); - if (we_put_this_data) { - we_put_this_data = false; - return; - } - if (length <= 0) - return; - - do_putscrap(type, scrap, length); -} - -static void do_putscrap(uint32 type, void *scrap, int32 length) -{ - ByteArray clip_data; - UINT uFormat = 0; - - switch (type) { - case FOURCC('T','E','X','T'): { - D(bug(" clipping TEXT\n")); - - // Convert text from Mac charset to ISO-Latin1 - uint8 *p = (uint8 *)scrap; - for (int i=0; i CR/LF - clip_data.push_back(c); - c = 10; - } - } else if (!no_clip_conversion) - c = mac2iso[c & 0x7f]; - clip_data.push_back(c); - } - clip_data.push_back(0); - uFormat = CF_TEXT; - break; - } - } - if (uFormat != CF_TEXT) // 'TEXT' only - return; - - // Transfer data to the native clipboard - HWND hMainWindow = GetMainWindowHandle(); - if (!hMainWindow ||!OpenClipboard(hMainWindow)) - return; - EmptyClipboard(); - HANDLE hData = GlobalAlloc(GMEM_DDESHARE, clip_data.size()); - if (hData) { - uint8 *data = (uint8 *)GlobalLock(hData); - memcpy(data, clip_data.data(), clip_data.size()); - GlobalUnlock(hData); - if (!SetClipboardData(uFormat, hData)) - GlobalFree(hData); - } - CloseClipboard(); -} - -/* - * Mac application zeroes clipboard - */ - -void ZeroScrap() -{ - -} - -/* - * Mac application reads clipboard - */ - -void GetScrap(void **handle, uint32 type, int32 offset) -{ - D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset)); - - do_getscrap(handle, type, offset); -} - -static void do_getscrap(void **handle, uint32 type, int32 offset) -{ - // Get appropriate format for requested data - UINT uFormat = 0; - switch (type) { - case FOURCC('T','E','X','T'): - uFormat = CF_TEXT; - break; - } - if (uFormat != CF_TEXT) // 'TEXT' only - return; - - // Get the native clipboard data - HWND hMainWindow = GetMainWindowHandle(); - if (!hMainWindow || !OpenClipboard(hMainWindow)) - return; - HANDLE hData = GetClipboardData(uFormat); - if (hData) { - uint8 *data = (uint8 *)GlobalLock(hData); - if (data) { - uint32 length = GlobalSize(hData); - if (length) { - int32 out_length = 0; - - // Allocate space for new scrap in MacOS side - M68kRegisters r; - r.d[0] = length; - Execute68kTrap(0xa71e, &r); // NewPtrSysClear() - uint32 scrap_area = r.a[0]; - - if (scrap_area) { - switch (type) { - case FOURCC('T','E','X','T'): - D(bug(" clipping TEXT\n")); - - // Convert text from ISO-Latin1 to Mac charset - uint8 *p = Mac2HostAddr(scrap_area); - for (uint32 i = 0; i < length; i++) { - uint8 c = data[i]; - if (c < 0x80) { - if (c == 0) - break; - if (c == 13 && i < length - 1 && data[i + 1] == 10) { // CR/LF -> CR - c = 13; - i++; - } - } else if (!no_clip_conversion) - c = iso2mac[c & 0x7f]; - *p++ = c; - out_length++; - } - break; - } - - // Add new data to clipboard - static uint8 proc[] = { - 0x59, 0x8f, // subq.l #4,sp - 0xa9, 0xfc, // ZeroScrap() - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #length,-(sp) - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #type,-(sp) - 0x2f, 0x3c, 0, 0, 0, 0, // move.l #outbuf,-(sp) - 0xa9, 0xfe, // PutScrap() - 0x58, 0x8f, // addq.l #4,sp - uint8(M68K_RTS >> 8), uint8(M68K_RTS) - }; - uint32 proc_area = Host2MacAddr(proc); - WriteMacInt32(proc_area + 6, out_length); - WriteMacInt32(proc_area + 12, type); - WriteMacInt32(proc_area + 18, scrap_area); - we_put_this_data = true; - Execute68k(proc_area, &r); - - // We are done with scratch memory - r.a[0] = scrap_area; - Execute68kTrap(0xa01f, &r); // DisposePtr - } - } - GlobalUnlock(hData); - } - } - CloseClipboard(); -} diff --git a/BasiliskII/src/Windows/config.h b/BasiliskII/src/Windows/config.h deleted file mode 100644 index 88bd0904..00000000 --- a/BasiliskII/src/Windows/config.h +++ /dev/null @@ -1,260 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -/* #undef AC_APPLE_UNIVERSAL_BUILD */ - -/* Define if using video enabled on SEGV signals. */ -#ifndef _DEBUG -#define ENABLE_VOSF 1 -#endif - -/* Define to 1 if you have the `acoshl' function. */ -#define HAVE_ACOSHL 1 - -/* Define to 1 if you have the `acosl' function. */ -#define HAVE_ACOSL 1 - -/* Define to 1 if you have the `asinhl' function. */ -#define HAVE_ASINHL 1 - -/* Define to 1 if you have the `asinl' function. */ -#define HAVE_ASINL 1 - -/* Define to 1 if you have the `atanh' function. */ -#define HAVE_ATANH 1 - -/* Define to 1 if you have the `atanhl' function. */ -#define HAVE_ATANHL 1 - -/* Define to 1 if you have the `atanl' function. */ -#define HAVE_ATANL 1 - -/* Define to 1 if the system has the type `caddr_t'. */ -/* #undef HAVE_CADDR_T */ - -/* Define to 1 if you have the `ceill' function. */ -#define HAVE_CEILL 1 - -/* Define to 1 if you have the `coshl' function. */ -#define HAVE_COSHL 1 - -/* Define to 1 if you have the `cosl' function. */ -#define HAVE_COSL 1 - -/* Define to 1 if you have the `expl' function. */ -/* #undef HAVE_EXPL */ - -/* Define to 1 if you have the `fabsl' function. */ -/* #undef HAVE_FABSL */ - -/* Define to 1 if you have the `finite' function. */ -#define HAVE_FINITE 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_FLOATINGPOINT_H */ - -/* Define to 1 if you have the `floorl' function. */ -#define HAVE_FLOORL 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IEEE754_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IEEEFP_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `isinf' function. */ -/* #undef HAVE_ISINF */ - -/* Define to 1 if you have the `isinfl' function. */ -/* #undef HAVE_ISINFL */ - -/* Define to 1 if you have the `isnan' function. */ -#define HAVE_ISNAN 1 - -/* Define to 1 if you have the `isnanl' function. */ -/* #undef HAVE_ISNANL */ - -/* Define to 1 if you have the `isnormal' function. */ -/* #undef HAVE_ISNORMAL */ - -/* Define to 1 if the system has the type `loff_t'. */ -/* #undef HAVE_LOFF_T */ - -/* Define to 1 if you have the `log10l' function. */ -/* #undef HAVE_LOG10L */ - -/* Define to 1 if you have the `logl' function. */ -/* #undef HAVE_LOGL */ - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NAN_H */ - -/* Define to 1 if you have the `powl' function. */ -#define HAVE_POWL 1 - -/* Define to 1 if you have the `signbit' function. */ -/* #undef HAVE_SIGNBIT */ - -/* Define if we can ignore the fault (instruction skipping in SIGSEGV - handler). */ -#define HAVE_SIGSEGV_SKIP_INSTRUCTION 1 - -/* Define to 1 if you have the `sinhl' function. */ -#define HAVE_SINHL 1 - -/* Define to 1 if you have the `sinl' function. */ -#define HAVE_SINL 1 - -/* Define to 1 if you have the `sqrtl' function. */ -#define HAVE_SQRTL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STRINGS_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the `tanhl' function. */ -#define HAVE_TANHL 1 - -/* Define to 1 if you have the `tanl' function. */ -#define HAVE_TANL 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_UNISTD_H */ - -/* Define if your system supports Windows exceptions. */ -#define HAVE_WIN32_EXCEPTIONS 1 - -/* Define if your system has a working Win32-based memory allocator. */ -#define HAVE_WIN32_VM 1 - -/* Define to the floating point format of the host machine. */ -#define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT - -/* Define to 1 if the host machine stores floating point numbers in memory - with the word containing the sign bit at the lowest address, or to 0 if it - does it the other way around. This macro should not be defined if the - ordering is the same as for multi-word integers. */ -/* #undef HOST_FLOAT_WORDS_BIG_ENDIAN */ - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Define this program name. */ -#define PACKAGE "Basilisk II" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "Christian.Bauer@uni-mainz.de" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "Basilisk II" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "Basilisk II 1.0" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "BasiliskII" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "1.0" - -/* The size of `double', as computed by sizeof. */ -#define SIZEOF_DOUBLE 8 - -/* The size of `float', as computed by sizeof. */ -#define SIZEOF_FLOAT 4 - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of `long', as computed by sizeof. */ -#define SIZEOF_LONG 4 - -/* The size of `long double', as computed by sizeof. */ -#define SIZEOF_LONG_DOUBLE 8 - -/* The size of `long long', as computed by sizeof. */ -#define SIZEOF_LONG_LONG 8 - -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* The size of `void *', as computed by sizeof. */ -#define SIZEOF_VOID_P 4 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to enble SDL support */ -#define USE_SDL 1 - -/* Define to enable SDL audio support */ -#define USE_SDL_AUDIO 1 - -/* Define to enable SDL video graphics support */ -#define USE_SDL_VIDEO 1 - -/* Define this program version. */ -#define VERSION "1.0" - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -/* # undef WORDS_BIGENDIAN */ -# endif -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `long int' if does not define. */ -/* #undef off_t */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ diff --git a/BasiliskII/src/Windows/configure.ac b/BasiliskII/src/Windows/configure.ac deleted file mode 100755 index fc902704..00000000 --- a/BasiliskII/src/Windows/configure.ac +++ /dev/null @@ -1,569 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -dnl Written in 2002 by Christian Bauer et al. - -AC_INIT([Basilisk II], 1.0, [Christian.Bauer@uni-mainz.de], BasiliskII) -AC_CONFIG_SRCDIR(main_windows.cpp) -AC_CONFIG_AUX_DIR(../Unix) -AC_PREREQ(2.52) -AC_CONFIG_HEADER(config.h) - -dnl Aliases for PACKAGE and VERSION macros. -AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE_NAME", [Define this program name.]) -AC_DEFINE_UNQUOTED(VERSION, "$PACKAGE_VERSION", [Define this program version.]) - -dnl SDL options. -AC_ARG_ENABLE(sdl-static, [ --enable-sdl-static use SDL static libraries for linking [default=no]], [WANT_SDL_STATIC=$enableval], [WANT_SDL_STATIC=no]) - -dnl JIT compiler options. -AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=yes]], [WANT_JIT=$enableval], [WANT_JIT=yes]) -AC_ARG_ENABLE(jit-debug, [ --enable-jit-debug activate native code disassemblers [default=no]], [WANT_JIT_DEBUG=$enableval], [WANT_JIT_DEBUG=no]) - -dnl FPU emulation core. -AC_ARG_ENABLE(fpe, -[ --enable-fpe=FPE specify which fpu emulator to use [default=auto]], -[ case "$enableval" in - dnl default is always ieee, if architecture has this fp format - auto) FPE_CORE_TEST_ORDER="ieee uae";; - ieee) FPE_CORE_TEST_ORDER="ieee";; - uae) FPE_CORE_TEST_ORDER="uae";; - x86) FPE_CORE_TEST_ORDER="x86";; - *) AC_MSG_ERROR([--enable-fpe takes only one of the following values: auto, x86, ieee, uae]);; - esac -], -[ FPE_CORE_TEST_ORDER="ieee uae" -]) - -dnl External packages. -AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]], [WANT_GTK=$withval], [WANT_GTK=yes]) - -dnl Addressing modes. -AC_ARG_ENABLE(addressing, -[ --enable-addressing=AM specify the addressing mode to use [default=fastest]], -[ case "$enableval" in - direct) ADDRESSING_TEST_ORDER="direct";; - banks) ADDRESSING_TEST_ORDER="banks";; - fastest)ADDRESSING_TEST_ORDER="direct banks";; - *) AC_MSG_ERROR([--enable-addressing takes only one of the following values: fastest, direct, banks]);; - esac -], -[ ADDRESSING_TEST_ORDER="direct banks" -]) - -dnl Canonical system information. -AC_CANONICAL_HOST -AC_CANONICAL_TARGET - -dnl Target CPU type. -HAVE_I386=no -HAVE_POWERPC=no -HAVE_X86_64=no -case "$target_cpu" in - i386* | i486* | i586* | i686* | i786* ) HAVE_I386=yes;; - powerpc* ) HAVE_POWERPC=yes;; - x86_64* ) HAVE_X86_64=yes;; -esac - -dnl Checks for programs. -AC_PROG_CC -AC_PROG_CC_C_O -AC_PROG_CPP -AC_PROG_CXX -AC_PROG_MAKE_SET -AC_PROG_EGREP -AC_PROG_LN_S -AC_CHECK_TOOL(WINDRES, windres) - -dnl We use GTK+ if possible. -if [[ "x$WANT_GTK" = "xyes" ]]; then - AM_PATH_GTK_2_0(1.3.15, [], [ - AC_MSG_WARN([Could not find GTK+ 2.0, disabling user interface.]) - WANT_GTK=no - ]) -fi -AC_SUBST(WANT_GTK) - -dnl We use 64-bit file size support if possible. -AC_SYS_LARGEFILE - -dnl Checks for header files. -AC_HEADER_STDC - -dnl Checks for typedefs, structures, and compiler characteristics. -AC_C_BIGENDIAN -AC_C_CONST -AC_C_INLINE -AC_CHECK_SIZEOF(short, 2) -AC_CHECK_SIZEOF(int, 4) -AC_CHECK_SIZEOF(long, 4) -AC_CHECK_SIZEOF(long long, 8) -AC_CHECK_SIZEOF(float, 4) -AC_CHECK_SIZEOF(double, 8) -AC_CHECK_SIZEOF(long double, 12) -AC_CHECK_SIZEOF(void *, 4) -AC_TYPE_OFF_T -AC_CHECK_TYPES(loff_t) -AC_CHECK_TYPES(caddr_t) -AC_TYPE_SIZE_T - -dnl Checks for library functions. -AC_CHECK_FUNCS(strdup strerror) - -dnl Define a macro that translates a yesno-variable into a C macro definition -dnl to be put into the config.h file -dnl $1 -- the macro to define -dnl $2 -- the value to translate -dnl $3 -- template name -AC_DEFUN([AC_TRANSLATE_DEFINE], [ - if [[ "x$2" = "xyes" -o "x$2" = "xguessing yes" ]]; then - AC_DEFINE($1, 1, $3) - fi -]) - -dnl Check that VirtualAlloc(), VirtualProtect() work -AC_CACHE_CHECK([whether VirtualProtect works], - ac_cv_VirtualProtect_works, [ - AC_LANG_SAVE - AC_LANG_CPLUSPLUS - ac_cv_VirtualProtect_works=yes - dnl First the tests that should segfault - for test_def in NONE_READ NONE_WRITE READ_WRITE; do - AC_TRY_RUN([ - #define HAVE_WIN32_VM 1 - #define CONFIGURE_TEST_VM_MAP - #define TEST_VM_PROT_$test_def - #include "../Unix/vm_alloc.cpp" - ], ac_cv_VirtualProtect_works=no, rm -f core, - dnl When cross-compiling, assume it works - ac_cv_VirtualProtect_works="yes" - ) - done - AC_TRY_RUN([ - #define HAVE_WIN32_VM 1 - #define CONFIGURE_TEST_VM_MAP - #define TEST_VM_PROT_RDWR_WRITE - #include "../Unix/vm_alloc.cpp" - ], , ac_cv_VirtualProtect_works=no, - dnl When cross-compiling, assume it works - ac_cv_VirtualProtect_works="yes" - ) - AC_LANG_RESTORE - ] -) -if [[ "x$ac_cv_VirtualProtect_works" = "xyes" ]]; then - AC_DEFINE(HAVE_WIN32_VM, 1, [Define if your system has a working Win32-based memory allocator.]) -else - AC_MSG_ERROR([Sorry, Windows VM functions don't work as expected on your system.]) -fi - -dnl Check if Windows exceptions are supported. -AC_CACHE_CHECK([whether your system supports Windows exceptions], - ac_cv_have_win32_exceptions, [ - AC_LANG_SAVE - AC_LANG_CPLUSPLUS - AC_TRY_RUN([ - #define HAVE_WIN32_EXCEPTIONS 1 - #define CONFIGURE_TEST_SIGSEGV_RECOVERY - #include "../Unix/vm_alloc.cpp" - #include "../Unix/sigsegv.cpp" - ], - ac_cv_have_win32_exceptions=yes, - ac_cv_have_win32_exceptions=no, - dnl When cross-compiling, assume it works - ac_cv_have_win32_exceptions="yes" - ) - AC_LANG_RESTORE - ] -) -if [[ "x$ac_cv_have_win32_exceptions" = "xyes" ]]; then - AC_DEFINE(HAVE_WIN32_EXCEPTIONS, 1, [Define if your system supports Windows exceptions.]) -else - AC_MSG_ERROR([Sorry, Windows exceptions don't work as expected on your system.]) -fi - -dnl Check if we can ignore the fault (instruction skipping in SIGSEGV handler) -AC_CACHE_CHECK([whether we can skip instruction in SIGSEGV handler], - ac_cv_have_skip_instruction, [ - AC_LANG_SAVE - AC_LANG_CPLUSPLUS - AC_TRY_RUN([ - #define HAVE_SIGSEGV_SKIP_INSTRUCTION 1 - #define CONFIGURE_TEST_SIGSEGV_RECOVERY - #include "../Unix/vm_alloc.cpp" - #include "../Unix/sigsegv.cpp" - ], ac_cv_have_skip_instruction=yes, ac_cv_have_skip_instruction=no, - dnl When cross-compiling, do not assume anything. - ac_cv_have_skip_instruction=no - ) - AC_LANG_RESTORE - ] -) -AC_TRANSLATE_DEFINE(HAVE_SIGSEGV_SKIP_INSTRUCTION, "$ac_cv_have_skip_instruction", - [Define if we can ignore the fault (instruction skipping in SIGSEGV handler).]) - -dnl We really want VOSF (Video on SEGV Signals) screen updates acceleration -AC_DEFINE(ENABLE_VOSF, 1, [Define if using video enabled on SEGV signals.]) - -dnl Determine the addressing mode to use -ADDRESSING_MODE="" -AC_MSG_CHECKING([for the addressing mode to use]) -for am in $ADDRESSING_TEST_ORDER; do - case $am in - direct) - dnl Direct addressing mode (constant offset) - ADDRESSING_MODE="direct" - DEFINES="$DEFINES -DDIRECT_ADDRESSING" - break - ;; - banks) - dnl Default addressing mode - ADDRESSING_MODE="memory banks" - break - ;; - *) - AC_MSG_ERROR([Internal configure.ac script error for $am addressing mode]) - esac -done -AC_MSG_RESULT($ADDRESSING_MODE) -if [[ "x$ADDRESSING_MODE" = "x" ]]; then - AC_MSG_WARN([Sorry, no suitable addressing mode in $ADDRESSING_TEST_ORDER]) - ADDRESSING_MODE="memory banks" -fi - -dnl Banked Memory Addressing mode is not supported by the JIT compiler -if [[ "x$WANT_JIT" = "xyes" -a "x$ADDRESSING_MODE" = "xmemory banks" ]]; then - AC_MSG_ERROR([Sorry, the JIT Compiler requires Direct Addressing, at least]) -fi - -dnl Check for GAS. -HAVE_GAS=no -AC_MSG_CHECKING(for GAS .p2align feature) -cat >conftest.S << EOF - .text - .p2align 5 -EOF -if $CC conftest.S -c -o conftest.o >/dev/null 2>&1 ; then HAVE_GAS=yes; fi -AC_MSG_RESULT($HAVE_GAS) - -dnl Check for GCC 2.7 or higher. -HAVE_GCC27=no -AC_MSG_CHECKING(for GCC 2.7 or higher) -AC_EGREP_CPP(xyes, -[#if __GNUC__ - 1 > 1 || __GNUC_MINOR__ - 1 > 5 - xyes -#endif -], [AC_MSG_RESULT(yes); HAVE_GCC27=yes], AC_MSG_RESULT(no)) - -dnl Check for GCC 3.0 or higher. -HAVE_GCC30=no -AC_MSG_CHECKING(for GCC 3.0 or higher) -AC_EGREP_CPP(xyes, -[#if __GNUC__ >= 3 - xyes -#endif -], [AC_MSG_RESULT(yes); HAVE_GCC30=yes], AC_MSG_RESULT(no)) - -dnl Add -fno-strict-aliasing for slirp sources -if [[ "x$HAVE_GCC30" = "xyes" ]]; then - SAVED_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fno-strict-aliasing" - AC_CACHE_CHECK([whether the compiler supports -fno-strict-aliasing], - ac_cv_gcc_no_strict_aliasing, [ - AC_TRY_COMPILE([],[], - [ac_cv_gcc_no_strict_aliasing=yes; AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing")], - [ac_cv_gcc_no_strict_aliasing=no]) - ]) - CFLAGS="$SAVED_CFLAGS" -fi - -dnl Select appropriate CPU source and REGPARAM define. -ASM_OPTIMIZATIONS=none -CPUSRCS="cpuemu1.cpp cpuemu2.cpp cpuemu3.cpp cpuemu4.cpp cpuemu5.cpp cpuemu6.cpp cpuemu7.cpp cpuemu8.cpp" - -dnl JITSRCS will be emptied later if the JIT is not available -dnl Other platforms should define their own set of noflags file variants -CAN_JIT=no -JITSRCS="compemu1.cpp compemu2.cpp compemu3.cpp compemu4.cpp compemu5.cpp compemu6.cpp compemu7.cpp compemu8.cpp" - -if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_I386" = "xyes" ]]; then - dnl i386 CPU - DEFINES="$DEFINES -DUNALIGNED_PROFITABLE -DREGPARAM=\"__attribute__((regparm(3)))\"" - if [[ "x$HAVE_GAS" = "xyes" ]]; then - ASM_OPTIMIZATIONS=i386 - DEFINES="$DEFINES -DX86_ASSEMBLY -DOPTIMIZED_FLAGS -DSAHF_SETO_PROFITABLE" - JITSRCS="cpuemu1_nf.cpp cpuemu2_nf.cpp cpuemu3_nf.cpp cpuemu4_nf.cpp cpuemu5_nf.cpp cpuemu6_nf.cpp cpuemu7_nf.cpp cpuemu8_nf.cpp $JITSRCS" - CAN_JIT=yes - fi -elif [[ "x$HAVE_GCC30" = "xyes" -a "x$HAVE_X86_64" = "xyes" ]]; then - dnl x86-64 CPU - DEFINES="$DEFINES -DUNALIGNED_PROFITABLE" - if [[ "x$HAVE_GAS" = "xyes" ]]; then - ASM_OPTIMIZATIONS="x86-64" - DEFINES="$DEFINES -DX86_64_ASSEMBLY -DOPTIMIZED_FLAGS" - JITSRCS="cpuemu1_nf.cpp cpuemu2_nf.cpp cpuemu3_nf.cpp cpuemu4_nf.cpp cpuemu5_nf.cpp cpuemu6_nf.cpp cpuemu7_nf.cpp cpuemu8_nf.cpp $JITSRCS" - CAN_JIT=yes - fi -fi - -dnl Enable JIT compiler, if possible. -if [[ "x$WANT_JIT" = "xyes" -a "x$CAN_JIT" ]]; then - JITSRCS="$JITSRCS ../uae_cpu/compiler/compemu_support.cpp ../uae_cpu/compiler/compemu_fpp.cpp compstbl.o cpustbl_nf.o" - DEFINES="$DEFINES -DUSE_JIT -DUSE_JIT_FPU" - - if [[ "x$WANT_JIT_DEBUG" = "xyes" ]]; then - if [[ "x$WANT_MON" = "xyes" ]]; then - DEFINES="$DEFINES -DJIT_DEBUG=1" - else - AC_MSG_WARN([cxmon not found, ignoring --enable-jit-debug]) - WANT_JIT_DEBUG=no - fi - fi - - dnl IEEE core is the only FPU emulator to use with the JIT compiler - case $FPE_CORE_TEST_ORDER in - ieee*) ;; - *) AC_MSG_WARN([Forcing use of the IEEE FPU core, as the JIT compiler supports only this one.]) ;; - esac - FPE_CORE_TEST_ORDER="ieee" -else - WANT_JIT=no - WANT_JIT_DEBUG=no - JITSRCS="" -fi - -dnl Utility macro used by next two tests. -dnl AC_EXAMINE_OBJECT(C source code, -dnl commands examining object file, -dnl [commands to run if compile failed]): -dnl -dnl Compile the source code to an object file; then convert it into a -dnl printable representation. All unprintable characters and -dnl asterisks (*) are replaced by dots (.). All white space is -dnl deleted. Newlines (ASCII 0x10) in the input are preserved in the -dnl output, but runs of newlines are compressed to a single newline. -dnl Finally, line breaks are forcibly inserted so that no line is -dnl longer than 80 columns and the file ends with a newline. The -dnl result of all this processing is in the file conftest.dmp, which -dnl may be examined by the commands in the second argument. -dnl -AC_DEFUN([gcc_AC_EXAMINE_OBJECT], -[AC_LANG_SAVE -AC_LANG_C -dnl Next bit cribbed from AC_TRY_COMPILE. -cat > conftest.$ac_ext < conftest.dmp - $2 -ifelse($3, , , else - $3 -)dnl -fi -rm -rf conftest* -AC_LANG_RESTORE]) - -dnl Floating point format probe. -dnl The basic concept is the same as the above: grep the object -dnl file for an interesting string. We have to watch out for -dnl rounding changing the values in the object, however; this is -dnl handled by ignoring the least significant byte of the float. -dnl -dnl Does not know about VAX G-float or C4x idiosyncratic format. -dnl It does know about PDP-10 idiosyncratic format, but this is -dnl not presently supported by GCC. S/390 "binary floating point" -dnl is in fact IEEE (but maybe we should have that in EBCDIC as well -dnl as ASCII?) -dnl -AC_DEFUN([gcc_AC_C_FLOAT_FORMAT], -[AC_CACHE_CHECK(floating point format, ac_cv_c_float_format, -[gcc_AC_EXAMINE_OBJECT( -[/* This will not work unless sizeof(double) == 8. */ -extern char sizeof_double_must_be_8 [sizeof(double) == 8 ? 1 : -1]; - -/* This structure must have no internal padding. */ -struct possibility { - char prefix[8]; - double candidate; - char postfix[8]; -}; - -#define C(cand) { "\nformat:", cand, ":tamrof\n" } -struct possibility table [] = -{ - C( 3.25724264705901305206e+01), /* @@IEEEFP - IEEE 754 */ - C( 3.53802595280598432000e+18), /* D__float - VAX */ - C( 5.32201830133125317057e-19), /* D.PDP-10 - PDP-10 - the dot is 0x13a */ - C( 1.77977764695171661377e+10), /* IBMHEXFP - s/390 format, ascii */ - C(-5.22995989424860458374e+10) /* IBMHEXFP - s/390 format, EBCDIC */ -};], - [if grep 'format:.@IEEEF.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='IEEE (big-endian)' - elif grep 'format:.I@@PFE.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='IEEE (big-endian)' - elif grep 'format:.FEEEI@.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='IEEE (little-endian)' - elif grep 'format:.EFP@@I.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='IEEE (little-endian)' - elif grep 'format:.__floa.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='VAX D-float' - elif grep 'format:..PDP-1.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='PDP-10' - elif grep 'format:.BMHEXF.:tamrof' conftest.dmp >/dev/null 2>&1; then - ac_cv_c_float_format='IBM 370 hex' - else - AC_MSG_ERROR(Unknown floating point format) - fi], - [AC_MSG_ERROR(compile failed)]) -]) -# IEEE is the default format. If the float endianness isn't the same -# as the integer endianness, we have to set FLOAT_WORDS_BIG_ENDIAN -# (which is a tristate: yes, no, default). This is only an issue with -# IEEE; the other formats are only supported by a few machines each, -# all with the same endianness. -format=IEEE_FLOAT_FORMAT -fbigend= -case $ac_cv_c_float_format in - 'IEEE (big-endian)' ) - if test $ac_cv_c_bigendian = no; then - fbigend=1 - fi - ;; - 'IEEE (little-endian)' ) - if test $ac_cv_c_bigendian = yes; then - fbigend=0 - fi - ;; - 'VAX D-float' ) - format=VAX_FLOAT_FORMAT - ;; - 'PDP-10' ) - format=PDP10_FLOAT_FORMAT - ;; - 'IBM 370 hex' ) - format=IBM_FLOAT_FORMAT - ;; -esac -AC_DEFINE_UNQUOTED(HOST_FLOAT_FORMAT, $format, - [Define to the floating point format of the host machine.]) -if test -n "$fbigend"; then - AC_DEFINE_UNQUOTED(HOST_FLOAT_WORDS_BIG_ENDIAN, $fbigend, - [Define to 1 if the host machine stores floating point numbers in - memory with the word containing the sign bit at the lowest address, - or to 0 if it does it the other way around. - - This macro should not be defined if the ordering is the same as for - multi-word integers.]) -fi -]) - -dnl Select appropriate FPU source. -gcc_AC_C_FLOAT_FORMAT -AC_CHECK_HEADERS(ieee754.h ieeefp.h floatingpoint.h nan.h) - -for fpe in $FPE_CORE_TEST_ORDER; do - case $fpe in - ieee) - case $ac_cv_c_float_format in - IEEE*) - FPE_CORE="IEEE fpu core" - DEFINES="$DEFINES -DFPU_IEEE" - FPUSRCS="../uae_cpu/fpu/fpu_ieee.cpp" - dnl Math functions not mandated by C99 standard - AC_CHECK_FUNCS(isnanl isinfl) - dnl Math functions required by C99 standard, but probably not - dnl implemented everywhere. In that case, we fall back to the - dnl regular variant for doubles. - AC_CHECK_FUNCS(logl log10l expl powl fabsl sqrtl) - AC_CHECK_FUNCS(sinl cosl tanl sinhl coshl tanhl) - AC_CHECK_FUNCS(asinl acosl atanl asinhl acoshl atanhl) - AC_CHECK_FUNCS(floorl ceill) - break - ;; - esac - ;; - x86) - if [[ ":$HAVE_GCC27:$HAVE_I386:$HAVE_GAS:" = ":yes:yes:yes:" ]]; then - FPE_CORE="i387 fpu core" - DEFINES="$DEFINES -DFPU_X86" - FPUSRCS="../uae_cpu/fpu/fpu_x86.cpp" - break - fi - ;; - uae) - FPE_CORE="uae fpu core" - DEFINES="$DEFINES -DFPU_UAE" - FPUSRCS="../uae_cpu/fpu/fpu_uae.cpp" - break - ;; - *) - AC_MSG_ERROR([Internal configure.in script error for $fpe fpu core]) - ;; - esac -done -if [[ "x$FPE_CORE" = "x" ]]; then - AC_MSG_ERROR([Sorry, no suitable FPU core found in $FPE_CORE_TEST_ORDER]) -fi - -dnl Check for certain math functions -AC_CHECK_FUNCS(atanh) -AC_CHECK_FUNCS(isnan isinf finite isnormal signbit) - -dnl UAE CPU sources for all non-m68k-native architectures. -CPUINCLUDES="-I../uae_cpu" -CPUSRCS="../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp ../uae_cpu/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS $JITSRCS" - -dnl We really want SDL for now -AC_CHECK_TOOL(sdl_config, sdl-config, [AC_MSG_ERROR([Sorry, you currently need SDL for this port])]) -SDL_CFLAGS=`$sdl_config --cflags` -AC_SUBST(SDL_CFLAGS) -if [[ "x$WANT_SDL_STATIC" = "xyes" ]]; then - SDL_LIBS=`$sdl_config --static-libs` - sdl_prefix=`$sdl_config --exec-prefix` - if [[ -n "$sdl_prefix" ]]; then - SDL_LIBS=`echo "$SDL_LIBS" | sed -e "s,-l\(SDLmain\|SDL\),$sdl_prefix/lib/lib\1.a,g"` - fi - SDL_LIBS="$SDL_LIBS -lwinmm" -else - SDL_LIBS=`$sdl_config --libs` -fi -AC_SUBST(SDL_LIBS) -AC_DEFINE(USE_SDL, 1, [Define to enble SDL support]) -AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support]) -AC_DEFINE(USE_SDL_AUDIO, 1, [Define to enable SDL audio support]) - -dnl Remove the "-g" option if set for GCC. -if [[ "x$HAVE_GCC27" = "xyes" ]]; then - CFLAGS=`echo $CFLAGS | sed -e 's/-g\b//g'` - CXXFLAGS=`echo $CXXFLAGS | sed -e 's/-g\b//g'` -fi - -dnl Generate Makefile. -AC_SUBST(DEFINES) -AC_SUBST(CPUINCLUDES) -AC_SUBST(CPUSRCS) -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT - -dnl Print summary. -echo -echo Basilisk II configuration summary: -echo -echo Use JIT compiler ....................... : $WANT_JIT -echo JIT debug mode ......................... : $WANT_JIT_DEBUG -echo Floating-Point emulation core .......... : $FPE_CORE -echo Assembly optimizations ................. : $ASM_OPTIMIZATIONS -echo Addressing mode ........................ : $ADDRESSING_MODE -echo GTK user interface ..................... : $WANT_GTK -echo -echo "Configuration done. Now type \"make\" (or \"gmake\")." diff --git a/BasiliskII/src/Windows/ether_windows.cpp b/BasiliskII/src/Windows/ether_windows.cpp deleted file mode 100755 index 1f59d830..00000000 --- a/BasiliskII/src/Windows/ether_windows.cpp +++ /dev/null @@ -1,1609 +0,0 @@ -/* - * ether_windows.cpp - Ethernet device driver - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include - -#include "cpu_emulation.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "ether.h" -#include "ether_defs.h" -#include "b2ether/multiopt.h" -#include "b2ether/inc/b2ether_hl.h" -#include "ether_windows.h" -#include "router/router.h" -#include "util_windows.h" -#include "libslirp.h" - -// Define to let the slirp library determine the right timeout for select() -#define USE_SLIRP_TIMEOUT 1 - - -#define DEBUG 0 -#define MONITOR 0 - -#if DEBUG -#pragma optimize("",off) -#endif - -#include "debug.h" - - -// Ethernet device types -enum { - NET_IF_B2ETHER, - NET_IF_ROUTER, - NET_IF_SLIRP, - NET_IF_TAP, - NET_IF_FAKE, -}; - -// TAP-Win32 constants -#define TAP_VERSION_MIN_MAJOR 7 -#define TAP_VERSION_MIN_MINOR 1 - -#define TAP_CONTROL_CODE(request, method) \ - CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) - -#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) -#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) -#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) -#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) -#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) -#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) - -#define OLD_TAP_CONTROL_CODE(request, method) \ - CTL_CODE (FILE_DEVICE_PHYSICAL_NETCARD | 8000, request, method, FILE_ANY_ACCESS) - -#define OLD_TAP_IOCTL_GET_VERSION OLD_TAP_CONTROL_CODE (3, METHOD_BUFFERED) - -// Options -bool ether_use_permanent = true; -static int16 ether_multi_mode = ETHER_MULTICAST_MAC; - -// Global variables -HANDLE ether_th; -unsigned int ether_tid; -HANDLE ether_th1; -HANDLE ether_th2; -static int net_if_type = -1; // Ethernet device type -#ifdef SHEEPSHAVER -static bool net_open = false; // Flag: initialization succeeded, network device open -uint8 ether_addr[6]; // Our Ethernet address -#endif - -// These are protected by queue_csection -// Controls transfer for read thread to feed thread -static CRITICAL_SECTION queue_csection; -typedef struct _win_queue_t { - uint8 *buf; - int sz; -} win_queue_t; -#define MAX_QUEUE_ITEMS 1024 -static win_queue_t queue[MAX_QUEUE_ITEMS]; -static int queue_head = 0; -static int queue_inx = 0; -static bool wait_request = true; - - - -// Read thread protected packet pool -static CRITICAL_SECTION fetch_csection; -// Some people use pools as large as 64. -#define PACKET_POOL_COUNT 10 -static LPPACKET packets[PACKET_POOL_COUNT]; -static bool wait_request2 = false; - - - -// Write thread packet queue -static CRITICAL_SECTION send_csection; -static LPPACKET send_queue = 0; - - -// Write thread free packet pool -static CRITICAL_SECTION wpool_csection; -static LPPACKET write_packet_pool = 0; - - - -// Try to deal with echos. Protected by fetch_csection. -// The code should be moved to the driver. No need to lift -// the echo packets to the application level. -// MAX_ECHO must be a power of two. -#define MAX_ECHO (1<<2) -static int echo_count = 0; -typedef uint8 echo_t[1514]; -static echo_t pending_packet[MAX_ECHO]; -static int pending_packet_sz[MAX_ECHO]; - - -// List of attached protocols -struct NetProtocol { - NetProtocol *next; - uint16 type; - uint32 handler; -}; - -static NetProtocol *prot_list = NULL; - - -static LPADAPTER fd = 0; -static bool thread_active = false; -static bool thread_active_1 = false; -static bool thread_active_2 = false; -static bool thread_active_3 = false; -static HANDLE int_ack = 0; -static HANDLE int_sig = 0; -static HANDLE int_sig2 = 0; -static HANDLE int_send_now = 0; - -// Prototypes -static LPADAPTER tap_open_adapter(LPCTSTR dev_name); -static void tap_close_adapter(LPADAPTER fd); -static bool tap_check_version(LPADAPTER fd); -static bool tap_set_status(LPADAPTER fd, ULONG status); -static bool tap_get_mac(LPADAPTER fd, LPBYTE addr); -static bool tap_receive_packet(LPADAPTER fd, LPPACKET lpPacket, BOOLEAN Sync); -static bool tap_send_packet(LPADAPTER fd, LPPACKET lpPacket, BOOLEAN Sync, BOOLEAN recycle); -static unsigned int WINAPI slirp_receive_func(void *arg); -static unsigned int WINAPI ether_thread_feed_int(void *arg); -static unsigned int WINAPI ether_thread_get_packets_nt(void *arg); -static unsigned int WINAPI ether_thread_write_packets(void *arg); -static void init_queue(void); -static void final_queue(void); -static bool allocate_read_packets(void); -static void free_read_packets(void); -static void free_write_packets(void); -static int16 ether_do_add_multicast(uint8 *addr); -static int16 ether_do_del_multicast(uint8 *addr); -static int16 ether_do_write(uint32 arg); -static void ether_do_interrupt(void); - - -/* - * Find protocol in list - */ - -static NetProtocol *find_protocol(uint16 type) -{ - // All 802.2 types are the same - if (type <= 1500) - type = 0; - - // Search list (we could use hashing here but there are usually only three - // handlers installed: 0x0000 for AppleTalk and 0x0800/0x0806 for TCP/IP) - NetProtocol *p = prot_list; - while (p) { - if (p->type == type) - return p; - p = p->next; - } - return NULL; -} - - -/* - * Initialization - */ - -bool ether_init(void) -{ - TCHAR buf[256]; - - // Do nothing if no Ethernet device specified - const char *name = PrefsFindString("ether"); - if (name == NULL) - return false; - - ether_multi_mode = PrefsFindInt32("ethermulticastmode"); - ether_use_permanent = PrefsFindBool("etherpermanentaddress"); - - // Determine Ethernet device type - net_if_type = -1; - if (PrefsFindBool("routerenabled") || strcmp(name, "router") == 0) - net_if_type = NET_IF_ROUTER; - else if (strcmp(name, "slirp") == 0) - net_if_type = NET_IF_SLIRP; - else if (strcmp(name, "tap") == 0) - net_if_type = NET_IF_TAP; - else - net_if_type = NET_IF_B2ETHER; - - // Initialize NAT-Router - if (net_if_type == NET_IF_ROUTER) { - if (!router_init()) - net_if_type = NET_IF_FAKE; - } - - // Initialize slirp library - if (net_if_type == NET_IF_SLIRP) { - if (slirp_init() < 0) { - WarningAlert(GetString(STR_SLIRP_NO_DNS_FOUND_WARN)); - return false; - } - } - - // Open ethernet device - decltype(tstr(std::declval())) dev_name; - switch (net_if_type) { - case NET_IF_B2ETHER: - dev_name = tstr(PrefsFindString("etherguid")); - if (dev_name == NULL || strcmp(name, "b2ether") != 0) - dev_name = tstr(name); - break; - case NET_IF_TAP: - dev_name = tstr(PrefsFindString("etherguid")); - break; - } - if (net_if_type == NET_IF_B2ETHER) { - if (dev_name == NULL) { - WarningAlert("No ethernet device GUID specified. Ethernet is not available."); - goto open_error; - } - - fd = PacketOpenAdapter( dev_name.get(), ether_multi_mode ); - if (!fd) { - _sntprintf(buf, lengthof(buf), TEXT("Could not open ethernet adapter %s."), dev_name.get()); - WarningAlert(buf); - goto open_error; - } - - // Get Ethernet address - if(!PacketGetMAC(fd,ether_addr,ether_use_permanent)) { - _sntprintf(buf, lengthof(buf), TEXT("Could not get hardware address of device %s. Ethernet is not available."), dev_name.get()); - WarningAlert(buf); - goto open_error; - } - D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); - - const char *ether_fake_address; - ether_fake_address = PrefsFindString("etherfakeaddress"); - if(ether_fake_address && strlen(ether_fake_address) == 12) { - char sm[10]; - strcpy( sm, "0x00" ); - for( int i=0; i<6; i++ ) { - sm[2] = ether_fake_address[i*2]; - sm[3] = ether_fake_address[i*2+1]; - ether_addr[i] = (uint8)strtoul(sm,0,0); - } - D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); - } - } - else if (net_if_type == NET_IF_TAP) { - if (dev_name == NULL) { - WarningAlert("No ethernet device GUID specified. Ethernet is not available."); - goto open_error; - } - - fd = tap_open_adapter(dev_name.get()); - if (!fd) { - _sntprintf(buf, lengthof(buf), TEXT("Could not open ethernet adapter %s."), dev_name.get()); - WarningAlert(buf); - goto open_error; - } - - if (!tap_check_version(fd)) { - _sntprintf(buf, lengthof(buf), TEXT("Minimal TAP-Win32 version supported is %d.%d."), TAP_VERSION_MIN_MAJOR, TAP_VERSION_MIN_MINOR); - WarningAlert(buf); - goto open_error; - } - - if (!tap_set_status(fd, true)) { - WarningAlert("Could not set media status to connected."); - goto open_error; - } - - if (!tap_get_mac(fd, ether_addr)) { - _sntprintf(buf, lengthof(buf), TEXT("Could not get hardware address of device %s. Ethernet is not available."), dev_name.get()); - WarningAlert(buf); - goto open_error; - } - D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); - - const char *ether_fake_address; - ether_fake_address = PrefsFindString("etherfakeaddress"); - if (ether_fake_address && strlen(ether_fake_address) == 12) { - char sm[10]; - strcpy( sm, "0x00" ); - for( int i=0; i<6; i++ ) { - sm[2] = ether_fake_address[i*2]; - sm[3] = ether_fake_address[i*2+1]; - ether_addr[i] = (uint8)strtoul(sm,0,0); - } - } -#if 1 - /* - If we bridge the underlying ethernet connection and the TAP - device altogether, we have to use a fake address. - */ - else { - ether_addr[0] = 0x52; - ether_addr[1] = 0x54; - ether_addr[2] = 0x00; - } -#endif - D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); - } - else if (net_if_type == NET_IF_SLIRP) { - ether_addr[0] = 0x52; - ether_addr[1] = 0x54; - ether_addr[2] = 0x00; - ether_addr[3] = 0x12; - ether_addr[4] = 0x34; - ether_addr[5] = 0x56; - D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); - } - else { - memcpy( ether_addr, router_mac_addr, 6 ); - D(bug("Fake ethernet address (same as router) %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); - } - - // Start packet reception thread - int_ack = CreateSemaphore( 0, 0, 1, NULL); - if(!int_ack) { - WarningAlert("WARNING: Cannot create int_ack semaphore"); - goto open_error; - } - - // nonsignaled - int_sig = CreateSemaphore( 0, 0, 1, NULL); - if(!int_sig) { - WarningAlert("WARNING: Cannot create int_sig semaphore"); - goto open_error; - } - - int_sig2 = CreateSemaphore( 0, 0, 1, NULL); - if(!int_sig2) { - WarningAlert("WARNING: Cannot create int_sig2 semaphore"); - goto open_error; - } - - int_send_now = CreateSemaphore( 0, 0, 1, NULL); - if(!int_send_now) { - WarningAlert("WARNING: Cannot create int_send_now semaphore"); - goto open_error; - } - - init_queue(); - - if(!allocate_read_packets()) goto open_error; - - // No need to enter wait state if we can avoid it. - // These all terminate fast. - - InitializeCriticalSectionAndSpinCount( &fetch_csection, 5000 ); - InitializeCriticalSectionAndSpinCount( &queue_csection, 5000 ); - InitializeCriticalSectionAndSpinCount( &send_csection, 5000 ); - InitializeCriticalSectionAndSpinCount( &wpool_csection, 5000 ); - - ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, ðer_tid ); - if (!ether_th) { - D(bug("Failed to create ethernet thread\n")); - goto open_error; - } - thread_active = true; - - unsigned int dummy; - unsigned int (WINAPI *receive_func)(void *); - switch (net_if_type) { - case NET_IF_SLIRP: - receive_func = slirp_receive_func; - break; - default: - receive_func = ether_thread_get_packets_nt; - break; - } - ether_th2 = (HANDLE)_beginthreadex( 0, 0, receive_func, 0, 0, &dummy ); - ether_th1 = (HANDLE)_beginthreadex( 0, 0, ether_thread_write_packets, 0, 0, &dummy ); - - // Everything OK - return true; - - open_error: - if (thread_active) { - TerminateThread(ether_th,0); - ether_th = 0; - if (int_ack) - CloseHandle(int_ack); - int_ack = 0; - if(int_sig) - CloseHandle(int_sig); - int_sig = 0; - if(int_sig2) - CloseHandle(int_sig2); - int_sig2 = 0; - if(int_send_now) - CloseHandle(int_send_now); - int_send_now = 0; - thread_active = false; - } - if (fd) { - switch (net_if_type) { - case NET_IF_B2ETHER: - PacketCloseAdapter(fd); - break; - case NET_IF_TAP: - tap_close_adapter(fd); - break; - } - fd = 0; - } - return false; -} - - -/* - * Deinitialization - */ - -void ether_exit(void) -{ - D(bug("EtherExit\n")); - - // Stop reception thread - thread_active = false; - - if(int_ack) ReleaseSemaphore(int_ack,1,NULL); - if(int_sig) ReleaseSemaphore(int_sig,1,NULL); - if(int_sig2) ReleaseSemaphore(int_sig2,1,NULL); - if(int_send_now) ReleaseSemaphore(int_send_now,1,NULL); - - D(bug("CancelIO if needed\n")); - if (fd && fd->hFile) - CancelIo(fd->hFile); - - // Wait max 2 secs to shut down pending io. After that, kill them. - D(bug("Wait delay\n")); - for( int i=0; i<10; i++ ) { - if(!thread_active_1 && !thread_active_2 && !thread_active_3) break; - Sleep(200); - } - - if(thread_active_1) { - D(bug("Ether killing ether_th1\n")); - if(ether_th1) TerminateThread(ether_th1,0); - thread_active_1 = false; - } - if(thread_active_2) { - D(bug("Ether killing ether_th2\n")); - if(ether_th2) TerminateThread(ether_th2,0); - thread_active_2 = false; - } - if(thread_active_3) { - D(bug("Ether killing thread\n")); - if(ether_th) TerminateThread(ether_th,0); - thread_active_3 = false; - } - - ether_th1 = 0; - ether_th2 = 0; - ether_th = 0; - - D(bug("Closing semaphores\n")); - if(int_ack) { - CloseHandle(int_ack); - int_ack = 0; - } - if(int_sig) { - CloseHandle(int_sig); - int_sig = 0; - } - if(int_sig2) { - CloseHandle(int_sig2); - int_sig2 = 0; - } - if(int_send_now) { - CloseHandle(int_send_now); - int_send_now = 0; - } - - // Close ethernet device - if (fd) { - switch (net_if_type) { - case NET_IF_B2ETHER: - PacketCloseAdapter(fd); - break; - case NET_IF_TAP: - tap_close_adapter(fd); - break; - } - fd = 0; - } - - // Remove all protocols - D(bug("Removing protocols\n")); - NetProtocol *p = prot_list; - while (p) { - NetProtocol *next = p->next; - delete p; - p = next; - } - prot_list = 0; - - D(bug("Deleting sections\n")); - DeleteCriticalSection( &fetch_csection ); - DeleteCriticalSection( &queue_csection ); - DeleteCriticalSection( &send_csection ); - DeleteCriticalSection( &wpool_csection ); - - D(bug("Freeing read packets\n")); - free_read_packets(); - - D(bug("Freeing write packets\n")); - free_write_packets(); - - D(bug("Finalizing queue\n")); - final_queue(); - - if (net_if_type == NET_IF_ROUTER) { - D(bug("Stopping router\n")); - router_final(); - } - - D(bug("EtherExit done\n")); -} - - -/* - * Glue around low-level implementation - */ - -#ifdef SHEEPSHAVER -// Error codes -enum { - eMultiErr = -91, - eLenErr = -92, - lapProtErr = -94, - excessCollsns = -95 -}; - -// Initialize ethernet -void EtherInit(void) -{ - net_open = false; - - // Do nothing if the user disabled the network - if (PrefsFindBool("nonet")) - return; - - net_open = ether_init(); -} - -// Exit ethernet -void EtherExit(void) -{ - ether_exit(); - net_open = false; -} - -// Get ethernet hardware address -void AO_get_ethernet_address(uint32 arg) -{ - uint8 *addr = Mac2HostAddr(arg); - if (net_open) - OTCopy48BitAddress(ether_addr, addr); - else { - addr[0] = 0x12; - addr[1] = 0x34; - addr[2] = 0x56; - addr[3] = 0x78; - addr[4] = 0x9a; - addr[5] = 0xbc; - } - D(bug("AO_get_ethernet_address: got address %02x%02x%02x%02x%02x%02x\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5])); -} - -// Add multicast address -void AO_enable_multicast(uint32 addr) -{ - if (net_open) - ether_do_add_multicast(Mac2HostAddr(addr)); -} - -// Disable multicast address -void AO_disable_multicast(uint32 addr) -{ - if (net_open) - ether_do_del_multicast(Mac2HostAddr(addr)); -} - -// Transmit one packet -void AO_transmit_packet(uint32 mp) -{ - if (net_open) { - switch (ether_do_write(mp)) { - case noErr: - num_tx_packets++; - break; - case excessCollsns: - num_tx_buffer_full++; - break; - } - } -} - -// Copy packet data from message block to linear buffer -static inline int ether_arg_to_buffer(uint32 mp, uint8 *p) -{ - return ether_msgb_to_buffer(mp, p); -} - -// Ethernet interrupt -void EtherIRQ(void) -{ - D(bug("EtherIRQ\n")); - num_ether_irq++; - - OTEnterInterrupt(); - ether_do_interrupt(); - OTLeaveInterrupt(); - - // Acknowledge interrupt to reception thread - D(bug(" EtherIRQ done\n")); - ReleaseSemaphore(int_ack,1,NULL); -} -#else -// Add multicast address -int16 ether_add_multicast(uint32 pb) -{ - return ether_do_add_multicast(Mac2HostAddr(pb + eMultiAddr)); -} - -// Disable multicast address -int16 ether_del_multicast(uint32 pb) -{ - return ether_do_del_multicast(Mac2HostAddr(pb + eMultiAddr)); -} - -// Transmit one packet -int16 ether_write(uint32 wds) -{ - return ether_do_write(wds); -} - -// Copy packet data from WDS to linear buffer -static inline int ether_arg_to_buffer(uint32 wds, uint8 *p) -{ - return ether_wds_to_buffer(wds, p); -} - -// Dispatch packet to protocol handler -static void ether_dispatch_packet(uint32 packet, uint32 length) -{ - // Get packet type - uint16 type = ReadMacInt16(packet + 12); - - // Look for protocol - NetProtocol *prot = find_protocol(type); - if (prot == NULL) - return; - - // No default handler - if (prot->handler == 0) - return; - - // Copy header to RHA - Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14); - D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12))); - - // Call protocol handler - M68kRegisters r; - r.d[0] = type; // Packet type - r.d[1] = length - 14; // Remaining packet length (without header, for ReadPacket) - r.a[0] = packet + 14; // Pointer to packet (Mac address, for ReadPacket) - r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA - r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines - D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4])); - Execute68k(prot->handler, &r); -} - -// Ethernet interrupt -void EtherInterrupt(void) -{ - D(bug("EtherIRQ\n")); - ether_do_interrupt(); - - // Acknowledge interrupt to reception thread - D(bug(" EtherIRQ done\n")); - ReleaseSemaphore(int_ack,1,NULL); -} -#endif - - -/* - * Reset - */ - -void ether_reset(void) -{ - D(bug("EtherReset\n")); - - // Remove all protocols - NetProtocol *p = prot_list; - while (p) { - NetProtocol *next = p->next; - delete p; - p = next; - } - prot_list = NULL; -} - - -/* - * Add multicast address - */ - -static int16 ether_do_add_multicast(uint8 *addr) -{ - D(bug("ether_add_multicast\n")); - - // We wouldn't need to do this - // if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr; - - switch (net_if_type) { - case NET_IF_B2ETHER: - if (!PacketAddMulticast( fd, addr)) { - D(bug("WARNING: couldn't enable multicast address\n")); - return eMultiErr; - } - default: - D(bug("ether_add_multicast: noErr\n")); - return noErr; - } -} - - -/* - * Delete multicast address - */ - -int16 ether_do_del_multicast(uint8 *addr) -{ - D(bug("ether_del_multicast\n")); - - // We wouldn't need to do this - // if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr; - - switch (net_if_type) { - case NET_IF_B2ETHER: - if (!PacketDelMulticast( fd, addr)) { - D(bug("WARNING: couldn't disable multicast address\n")); - return eMultiErr; - } - default: - return noErr; - } -} - - -/* - * Attach protocol handler - */ - -int16 ether_attach_ph(uint16 type, uint32 handler) -{ - D(bug("ether_attach_ph type=0x%x, handler=0x%x\n",(int)type,handler)); - - // Already attached? - NetProtocol *p = find_protocol(type); - if (p != NULL) { - D(bug("ether_attach_ph: lapProtErr\n")); - return lapProtErr; - } else { - // No, create and attach - p = new NetProtocol; - p->next = prot_list; - p->type = type; - p->handler = handler; - prot_list = p; - D(bug("ether_attach_ph: noErr\n")); - return noErr; - } -} - - -/* - * Detach protocol handler - */ - -int16 ether_detach_ph(uint16 type) -{ - D(bug("ether_detach_ph type=%08lx\n",(int)type)); - - NetProtocol *p = find_protocol(type); - if (p != NULL) { - NetProtocol *previous = 0; - NetProtocol *q = prot_list; - while(q) { - if (q == p) { - if(previous) { - previous->next = q->next; - } else { - prot_list = q->next; - } - delete p; - return noErr; - } - previous = q; - q = q->next; - } - } - return lapProtErr; -} - -#if MONITOR -static void dump_packet( uint8 *packet, int length ) -{ - char buf[1000], sm[10]; - - *buf = 0; - - if(length > 256) length = 256; - - for (int i=0; inext = 0; - if(send_queue) { - LPPACKET p = send_queue; - // The queue is short. It would be larger overhead to double-link it. - while(p->next) p = p->next; - p->next = Packet; - } else { - send_queue = Packet; - } - LeaveCriticalSection( &send_csection ); -} - -static LPPACKET get_send_head( void ) -{ - LPPACKET Packet = 0; - - EnterCriticalSection( &send_csection ); - if(send_queue) { - Packet = send_queue; - send_queue = send_queue->next; - } - LeaveCriticalSection( &send_csection ); - - return Packet; -} - -static int get_write_packet_pool_sz( void ) -{ - LPPACKET t = write_packet_pool; - int sz = 0; - - while(t) { - t = t->next; - sz++; - } - return(sz); -} - -static void free_write_packets( void ) -{ - LPPACKET next; - int i = 0; - while(write_packet_pool) { - next = write_packet_pool->next; - D(bug("Freeing write packet %ld\n",++i)); - PacketFreePacket(write_packet_pool); - write_packet_pool = next; - } -} - -void recycle_write_packet( LPPACKET Packet ) -{ - EnterCriticalSection( &wpool_csection ); - Packet->next = write_packet_pool; - write_packet_pool = Packet; - D(bug("Pool size after recycling = %ld\n",get_write_packet_pool_sz())); - LeaveCriticalSection( &wpool_csection ); -} - -static LPPACKET get_write_packet( UINT len ) -{ - LPPACKET Packet = 0; - - EnterCriticalSection( &wpool_csection ); - if(write_packet_pool) { - Packet = write_packet_pool; - write_packet_pool = write_packet_pool->next; - Packet->OverLapped.Offset = 0; - Packet->OverLapped.OffsetHigh = 0; - Packet->Length = len; - Packet->BytesReceived = 0; - Packet->bIoComplete = FALSE; - Packet->free = TRUE; - Packet->next = 0; - // actually an auto-reset event. - if(Packet->OverLapped.hEvent) ResetEvent(Packet->OverLapped.hEvent); - } else { - Packet = PacketAllocatePacket(fd,len); - } - - D(bug("Pool size after get wr packet = %ld\n",get_write_packet_pool_sz())); - - LeaveCriticalSection( &wpool_csection ); - - return Packet; -} - -unsigned int WINAPI ether_thread_write_packets(void *arg) -{ - LPPACKET Packet; - - thread_active_1 = true; - - D(bug("ether_thread_write_packets start\n")); - - while(thread_active) { - // must be alertable, otherwise write completion is never called - WaitForSingleObjectEx(int_send_now,INFINITE,TRUE); - while( thread_active && (Packet = get_send_head()) != 0 ) { - switch (net_if_type) { - case NET_IF_ROUTER: - if(router_write_packet((uint8 *)Packet->Buffer, Packet->Length)) { - Packet->bIoComplete = TRUE; - recycle_write_packet(Packet); - } - break; - case NET_IF_FAKE: - Packet->bIoComplete = TRUE; - recycle_write_packet(Packet); - break; - case NET_IF_B2ETHER: - if(!PacketSendPacket( fd, Packet, FALSE, TRUE )) { - // already recycled if async - } - break; - case NET_IF_TAP: - if (!tap_send_packet(fd, Packet, FALSE, TRUE)) { - // already recycled if async - } - break; - case NET_IF_SLIRP: - slirp_input((uint8 *)Packet->Buffer, Packet->Length); - Packet->bIoComplete = TRUE; - recycle_write_packet(Packet); - break; - } - } - } - - D(bug("ether_thread_write_packets exit\n")); - - thread_active_1 = false; - - return(0); -} - -static BOOL write_packet( uint8 *packet, int len ) -{ - LPPACKET Packet; - - D(bug("write_packet\n")); - - Packet = get_write_packet(len); - if(Packet) { - memcpy( Packet->Buffer, packet, len ); - - EnterCriticalSection( &fetch_csection ); - pending_packet_sz[echo_count] = min(sizeof(pending_packet),len); - memcpy( pending_packet[echo_count], packet, pending_packet_sz[echo_count] ); - echo_count = (echo_count+1) & (~(MAX_ECHO-1)); - LeaveCriticalSection( &fetch_csection ); - - insert_send_queue( Packet ); - - ReleaseSemaphore(int_send_now,1,NULL); - return(TRUE); - } else { - return(FALSE); - } -} - -static int16 ether_do_write(uint32 arg) -{ - D(bug("ether_write\n")); - - // Copy packet to buffer - uint8 packet[1514], *p = packet; - int len = ether_arg_to_buffer(arg, p); - - if(len > 1514) { - D(bug("illegal packet length: %d\n",len)); - return eLenErr; - } else { -#if MONITOR - bug("Sending Ethernet packet (%d bytes):\n",(int)len); - dump_packet( packet, len ); -#endif - } - - // Transmit packet - if (!write_packet(packet, len)) { - D(bug("WARNING: couldn't transmit packet\n")); - return excessCollsns; - } else { - // It's up to the protocol drivers to do the error checking. Even if the - // i/o completion routine returns ok, there can be errors, so there is - // no point to wait for write completion and try to make some sense of the - // possible error codes. - return noErr; - } -} - - -static void init_queue(void) -{ - queue_inx = 0; - queue_head = 0; - - for( int i=0; i 0) { - D(bug("ethernet queue full, packet dropped\n")); - } else { - if(sz > 1514) sz = 1514; - queue[queue_inx].sz = sz; - memcpy( queue[queue_inx].buf, buf, sz ); - queue_inx++; - if(queue_inx >= MAX_QUEUE_ITEMS) queue_inx = 0; - if(wait_request) { - wait_request = false; - ReleaseSemaphore(int_sig,1,NULL); - } - } - LeaveCriticalSection( &queue_csection ); -} - -static int dequeue_packet( uint8 *buf ) -{ - int sz; - - if(!thread_active) return(0); - - EnterCriticalSection( &queue_csection ); - sz = queue[queue_head].sz; - if(sz > 0) { - memcpy( buf, queue[queue_head].buf, sz ); - queue[queue_head].sz = 0; - queue_head++; - if(queue_head >= MAX_QUEUE_ITEMS) queue_head = 0; - } - LeaveCriticalSection( &queue_csection ); - return(sz); -} - -static void trigger_queue(void) -{ - EnterCriticalSection( &queue_csection ); - if( queue[queue_head].sz > 0 ) { - D(bug(" packet received, triggering Ethernet interrupt\n")); - SetInterruptFlag(INTFLAG_ETHER); - TriggerInterrupt(); - // of course can't wait here. - } - LeaveCriticalSection( &queue_csection ); -} - -static bool set_wait_request(void) -{ - bool result; - EnterCriticalSection( &queue_csection ); - if(queue[queue_head].sz) { - result = true; - } else { - result = false; - wait_request = true; - } - LeaveCriticalSection( &queue_csection ); - return(result); -} - - -/* - * TAP-Win32 glue - */ - -static LPADAPTER tap_open_adapter(LPCTSTR dev_name) -{ - fd = (LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(*fd)); - if (fd == NULL) - return NULL; - - TCHAR dev_path[MAX_PATH]; - _sntprintf(dev_path, lengthof(dev_path), - TEXT("\\\\.\\Global\\%s.tap"), dev_name); - - HANDLE handle = CreateFile( - dev_path, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, - NULL); - if (handle == NULL || handle == INVALID_HANDLE_VALUE) - return NULL; - - fd->hFile = handle; - return fd; -} - -static void tap_close_adapter(LPADAPTER fd) -{ - if (fd) { - if (fd->hFile) { - tap_set_status(fd, false); - CloseHandle(fd->hFile); - } - GlobalFreePtr(fd); - } -} - -static bool tap_check_version(LPADAPTER fd) -{ - ULONG len; - ULONG info[3] = { 0, }; - - if (!DeviceIoControl(fd->hFile, TAP_IOCTL_GET_VERSION, - &info, sizeof(info), - &info, sizeof(info), &len, NULL) - && !DeviceIoControl(fd->hFile, OLD_TAP_IOCTL_GET_VERSION, - &info, sizeof(info), - &info, sizeof(info), &len, NULL)) - return false; - - if (info[0] > TAP_VERSION_MIN_MAJOR) - return true; - if (info[0] == TAP_VERSION_MIN_MAJOR && info[1] >= TAP_VERSION_MIN_MINOR) - return true; - - return false; -} - -static bool tap_set_status(LPADAPTER fd, ULONG status) -{ - DWORD len = 0; - return DeviceIoControl(fd->hFile, TAP_IOCTL_SET_MEDIA_STATUS, - &status, sizeof (status), - &status, sizeof (status), &len, NULL) != FALSE; -} - -static bool tap_get_mac(LPADAPTER fd, LPBYTE addr) -{ - DWORD len = 0; - return DeviceIoControl(fd->hFile, TAP_IOCTL_GET_MAC, - addr, 6, - addr, 6, &len, NULL) != FALSE; -} - -static VOID CALLBACK tap_write_completion( - DWORD dwErrorCode, - DWORD dwNumberOfBytesTransfered, - LPOVERLAPPED lpOverLapped - ) -{ - LPPACKET lpPacket = CONTAINING_RECORD(lpOverLapped, PACKET, OverLapped); - - lpPacket->bIoComplete = TRUE; - recycle_write_packet(lpPacket); -} - -static bool tap_send_packet( - LPADAPTER fd, - LPPACKET lpPacket, - BOOLEAN Sync, - BOOLEAN RecyclingAllowed) -{ - BOOLEAN Result; - - lpPacket->OverLapped.Offset = 0; - lpPacket->OverLapped.OffsetHigh = 0; - lpPacket->bIoComplete = FALSE; - - if (Sync) { - Result = WriteFile(fd->hFile, - lpPacket->Buffer, - lpPacket->Length, - &lpPacket->BytesReceived, - &lpPacket->OverLapped); - if (Result) { - GetOverlappedResult(fd->hFile, - &lpPacket->OverLapped, - &lpPacket->BytesReceived, - TRUE); - } - lpPacket->bIoComplete = TRUE; - if (RecyclingAllowed) - PacketFreePacket(lpPacket); - } - else { - Result = WriteFileEx(fd->hFile, - lpPacket->Buffer, - lpPacket->Length, - &lpPacket->OverLapped, - tap_write_completion); - - if (!Result && RecyclingAllowed) - recycle_write_packet(lpPacket); - } - - return Result != FALSE; -} - -static bool tap_receive_packet(LPADAPTER fd, LPPACKET lpPacket, BOOLEAN Sync) -{ - BOOLEAN Result; - - lpPacket->OverLapped.Offset = 0; - lpPacket->OverLapped.OffsetHigh = 0; - lpPacket->bIoComplete = FALSE; - - if (Sync) { - Result = ReadFile(fd->hFile, - lpPacket->Buffer, - lpPacket->Length, - &lpPacket->BytesReceived, - &lpPacket->OverLapped); - if (Result) { - Result = GetOverlappedResult(fd->hFile, - &lpPacket->OverLapped, - &lpPacket->BytesReceived, - TRUE); - if (Result) - lpPacket->bIoComplete = TRUE; - else - lpPacket->free = TRUE; - } - } - else { - Result = ReadFileEx(fd->hFile, - lpPacket->Buffer, - lpPacket->Length, - &lpPacket->OverLapped, - packet_read_completion); - - if (!Result) - lpPacket->BytesReceived = 0; - } - - return Result != FALSE; -} - - -/* - * SLIRP output buffer glue - */ - -int slirp_can_output(void) -{ - return 1; -} - -void slirp_output(const uint8 *packet, int len) -{ - enqueue_packet(packet, len); -} - -unsigned int WINAPI slirp_receive_func(void *arg) -{ - D(bug("slirp_receive_func\n")); - thread_active_2 = true; - - while (thread_active) { - // Wait for packets to arrive - fd_set rfds, wfds, xfds; - int nfds, ret, timeout; - - // ... in the output queue - nfds = -1; - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); -#if ! USE_SLIRP_TIMEOUT - timeout = 10000; -#endif - if (nfds < 0) { - /* Windows does not honour the timeout if there is not - descriptor to wait for */ - Delay_usec(timeout); - ret = 0; - } - else { - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = timeout; - ret = select(0, &rfds, &wfds, &xfds, &tv); - } - if (ret >= 0) - slirp_select_poll(&rfds, &wfds, &xfds); - } - - D(bug("slirp_receive_func exit\n")); - thread_active_2 = false; - return 0; -} - - -/* - * Packet reception threads - */ - -VOID CALLBACK packet_read_completion( - DWORD dwErrorCode, - DWORD dwNumberOfBytesTransfered, - LPOVERLAPPED lpOverlapped - ) -{ - EnterCriticalSection( &fetch_csection ); - - LPPACKET lpPacket = CONTAINING_RECORD(lpOverlapped,PACKET,OverLapped); - - D(bug("packet_read_completion bytes=%d, error code=%d\n",dwNumberOfBytesTransfered,dwErrorCode)); - - if(thread_active && !dwErrorCode) { - int count = min(dwNumberOfBytesTransfered,1514); - if(count) { - int j = echo_count; - for(int i=MAX_ECHO; i; i--) { - j--; - if(j < 0) j = MAX_ECHO-1; - if(count == pending_packet_sz[j] && - memcmp(pending_packet[j],lpPacket->Buffer,count) == 0) - { - D(bug("packet_read_completion discarding own packet.\n")); - dwNumberOfBytesTransfered = 0; - - j = (j+1) & (~(MAX_ECHO-1)); - if(j != echo_count) { - D(bug("Wow, this fix made some good after all...\n")); - } - - break; - } - } - // XXX drop packets that are not for us - if (net_if_type == NET_IF_TAP) { - if (memcmp((LPBYTE)lpPacket->Buffer, ether_addr, 6) != 0) - dwNumberOfBytesTransfered = 0; - } - if(dwNumberOfBytesTransfered) { - if(net_if_type != NET_IF_ROUTER || !router_read_packet((uint8 *)lpPacket->Buffer, dwNumberOfBytesTransfered)) { - enqueue_packet( (LPBYTE)lpPacket->Buffer, dwNumberOfBytesTransfered ); - } - } - } - } - - // actually an auto-reset event. - if(lpPacket->OverLapped.hEvent) ResetEvent(lpPacket->OverLapped.hEvent); - - lpPacket->free = TRUE; - lpPacket->bIoComplete = TRUE; - - if(wait_request2) { - wait_request2 = false; - ReleaseSemaphore(int_sig2,1,NULL); - } - - LeaveCriticalSection( &fetch_csection ); -} - -static BOOL has_no_completed_io(void) -{ - BOOL result = TRUE; - - EnterCriticalSection( &fetch_csection ); - - for( int i=0; ibIoComplete) { - result = FALSE; - break; - } - } - if(result) wait_request2 = true; - - LeaveCriticalSection( &fetch_csection ); - return(result); -} - -static bool allocate_read_packets(void) -{ - for( int i=0; ifree) { - packets[i]->free = FALSE; - BOOLEAN Result; - switch (net_if_type) { - case NET_IF_B2ETHER: - Result = PacketReceivePacket(fd, packets[i], FALSE); - break; - case NET_IF_TAP: - Result = tap_receive_packet(fd, packets[i], FALSE); - break; - } - if (Result) { - if(packets[i]->bIoComplete) { - D(bug("Early io completion...\n")); - packet_read_completion( - ERROR_SUCCESS, - packets[i]->BytesReceived, - &packets[i]->OverLapped - ); - } - } else { - packets[i]->free = TRUE; - } - } - } - } - - if(thread_active && has_no_completed_io()) { - D(bug("Waiting for int_sig2\n")); - // "problem": awakens twice in a row. Fix if you increase the pool size. - WaitForSingleObjectEx(int_sig2,INFINITE,TRUE); - } - } - - D(bug("ether_thread_get_packets_nt exit\n")); - - thread_active_2 = false; - - return 0; -} - -unsigned int WINAPI ether_thread_feed_int(void *arg) -{ - bool looping; - - thread_active_3 = true; - - D(bug("ether_thread_feed_int start\n")); - - while(thread_active) { - D(bug("Waiting for int_sig\n")); - WaitForSingleObject(int_sig,INFINITE); - // Looping this way to avoid a race condition. - D(bug("Triggering\n")); - looping = true; - while(thread_active && looping) { - trigger_queue(); - // Wait for interrupt acknowledge by EtherInterrupt() - WaitForSingleObject(int_ack,INFINITE); - if(thread_active) looping = set_wait_request(); - } - D(bug("Queue empty.\n")); - } - - D(bug("ether_thread_feed_int exit\n")); - - thread_active_3 = false; - - return 0; -} - - -/* - * Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers - */ - -static void ether_do_interrupt(void) -{ - // Call protocol handler for received packets - EthernetPacket ether_packet; - uint32 packet = ether_packet.addr(); - ssize_t length; - for (;;) { - - // Read packet from Ethernet device - length = dequeue_packet(Mac2HostAddr(packet)); - if (length < 14) - break; - -#if MONITOR - bug("Receiving Ethernet packet (%d bytes):\n",(int)length); - dump_packet( Mac2HostAddr(packet), length ); -#endif - - // Dispatch packet - ether_dispatch_packet(packet, length); - } -} - -#if DEBUG -#pragma optimize("",on) -#endif diff --git a/BasiliskII/src/Windows/ether_windows.h b/BasiliskII/src/Windows/ether_windows.h deleted file mode 100755 index aed67040..00000000 --- a/BasiliskII/src/Windows/ether_windows.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _ETHER_WINDOWS_H_ -#define _ETHER_WINDOWS_H_ - -void enqueue_packet( const uint8 *buf, int sz ); - -#ifdef SHEEPSHAVER -extern uint8 ether_addr[6]; -#endif - -#endif // _ETHER_WINDOWS_H_ diff --git a/BasiliskII/src/Windows/extfs_windows.cpp b/BasiliskII/src/Windows/extfs_windows.cpp deleted file mode 100755 index f2b8a372..00000000 --- a/BasiliskII/src/Windows/extfs_windows.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/* - * extfs_windows.cpp - MacOS file system for access native file system access, Windows specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "main.h" -#include "extfs.h" -#include "extfs_defs.h" -#include "posix_emu.h" - -#include -#include -#include -#include -#include - - -#define DEBUG 0 -#include "debug.h" - - -// Constants -#define HOST_DIRSEP_CHAR '\\' -#define HOST_DIRSEP_STR "\\" - - -// Default Finder flags -const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited; - - -/* - * Initialization - */ - -void extfs_init(void) -{ - init_posix_emu(); -} - - -/* - * Deinitialization - */ - -void extfs_exit(void) -{ - final_posix_emu(); -} - - -/* - * Add component to path name - */ - -void add_path_component(char *path, const char *component) -{ - int l = strlen(path); - if (l < MAX_PATH_LENGTH-1 && path[l-1] != HOST_DIRSEP_CHAR) { - path[l] = HOST_DIRSEP_CHAR; - path[l+1] = 0; - } - strncat(path, component, MAX_PATH_LENGTH-1); -} - - -/* - * Finder info and resource forks are kept in helper files - * - * Finder info: - * /path/.finf/file - * Resource fork: - * /path/.rsrc/file - * - * The .finf files store a FInfo/DInfo, followed by a FXInfo/DXInfo - * (16+16 bytes) - */ - -static void make_helper_path(const char *src, char *dest, const char *add, bool only_dir = false) -{ - dest[0] = 0; - - // Get pointer to last component of path - const char *last_part = strrchr(src, HOST_DIRSEP_CHAR); - if (last_part) - last_part++; - else - last_part = src; - - // Copy everything before - strncpy(dest, src, last_part-src); - dest[last_part-src] = 0; - - // Add additional component - strncat(dest, add, MAX_PATH_LENGTH-1); - - // Add last component - if (!only_dir) - strncat(dest, last_part, MAX_PATH_LENGTH-1); -} - -static int create_helper_dir(const char *path, const char *add) -{ - char helper_dir[MAX_PATH_LENGTH]; - make_helper_path(path, helper_dir, add, true); - if (helper_dir[strlen(helper_dir) - 1] == HOST_DIRSEP_CHAR) // Remove trailing "\" - helper_dir[strlen(helper_dir) - 1] = 0; - return mkdir(helper_dir, 0777); -} - -static int open_helper(const char *path, const char *add, int flag) -{ - char helper_path[MAX_PATH_LENGTH]; - make_helper_path(path, helper_path, add); - - switch (flag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) { - case _O_WRONLY: - case _O_RDWR: - flag |= O_CREAT; - break; - } - - int fd = open(helper_path, flag, 0666); - if (fd < 0) { - if (/*errno == ENOENT &&*/ (flag & O_CREAT)) { - // One path component was missing, probably the helper - // directory. Try to create it and re-open the file. - int ret = create_helper_dir(path, add); - if (ret < 0) - return ret; - fd = open(helper_path, flag, 0666); - } - } - return fd; -} - -static int open_finf(const char *path, int flag) -{ - return open_helper(path, ".finf" HOST_DIRSEP_STR, flag); -} - -static int open_rsrc(const char *path, int flag) -{ - return open_helper(path, ".rsrc" HOST_DIRSEP_STR, flag); -} - - -/* - * Get/set finder info for file/directory specified by full path - */ - -struct ext2type { - const char *ext; - uint32 type; - uint32 creator; -}; - -static const ext2type e2t_translation[] = { - {".Z", FOURCC('Z','I','V','M'), FOURCC('L','Z','I','V')}, - {".gz", FOURCC('G','z','i','p'), FOURCC('G','z','i','p')}, - {".hqx", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".bin", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".pdf", FOURCC('P','D','F',' '), FOURCC('C','A','R','O')}, - {".ps", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')}, - {".sit", FOURCC('S','I','T','!'), FOURCC('S','I','T','x')}, - {".tar", FOURCC('T','A','R','F'), FOURCC('T','A','R',' ')}, - {".uu", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".uue", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".zip", FOURCC('Z','I','P',' '), FOURCC('Z','I','P',' ')}, - {".8svx", FOURCC('8','S','V','X'), FOURCC('S','N','D','M')}, - {".aifc", FOURCC('A','I','F','C'), FOURCC('T','V','O','D')}, - {".aiff", FOURCC('A','I','F','F'), FOURCC('T','V','O','D')}, - {".au", FOURCC('U','L','A','W'), FOURCC('T','V','O','D')}, - {".mid", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')}, - {".midi", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')}, - {".mp2", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')}, - {".mp3", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')}, - {".wav", FOURCC('W','A','V','E'), FOURCC('T','V','O','D')}, - {".bmp", FOURCC('B','M','P','f'), FOURCC('o','g','l','e')}, - {".gif", FOURCC('G','I','F','f'), FOURCC('o','g','l','e')}, - {".lbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')}, - {".ilbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')}, - {".jpg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')}, - {".jpeg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')}, - {".pict", FOURCC('P','I','C','T'), FOURCC('o','g','l','e')}, - {".png", FOURCC('P','N','G','f'), FOURCC('o','g','l','e')}, - {".sgi", FOURCC('.','S','G','I'), FOURCC('o','g','l','e')}, - {".tga", FOURCC('T','P','I','C'), FOURCC('o','g','l','e')}, - {".tif", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')}, - {".tiff", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')}, - {".htm", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')}, - {".html", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')}, - {".txt", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')}, - {".rtf", FOURCC('T','E','X','T'), FOURCC('M','S','W','D')}, - {".c", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".C", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cc", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".h", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hh", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".s", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".S", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".i", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".mpg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')}, - {".mpeg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')}, - {".mov", FOURCC('M','o','o','V'), FOURCC('T','V','O','D')}, - {".fli", FOURCC('F','L','I',' '), FOURCC('T','V','O','D')}, - {".avi", FOURCC('V','f','W',' '), FOURCC('T','V','O','D')}, - {".qxd", FOURCC('X','D','O','C'), FOURCC('X','P','R','3')}, - {".hfv", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')}, - {".dsk", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')}, - {".img", FOURCC('r','o','h','d'), FOURCC('d','d','s','k')}, - {NULL, 0, 0} // End marker -}; - -void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Set default finder info - Mac_memset(finfo, 0, SIZEOF_FInfo); - if (fxinfo) - Mac_memset(fxinfo, 0, SIZEOF_FXInfo); - WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS); - WriteMacInt32(finfo + fdLocation, (uint32)-1); - - // Read Finder info file - int fd = open_finf(path, O_RDONLY); - if (fd >= 0) { - ssize_t actual = read(fd, Mac2HostAddr(finfo), SIZEOF_FInfo); - if (fxinfo) - actual += read(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo); - close(fd); - if (actual >= SIZEOF_FInfo) - return; - } - - // No Finder info file, translate file name extension to MacOS type/creator - if (!is_dir) { - int path_len = strlen(path); - for (int i=0; e2t_translation[i].ext; i++) { - int ext_len = strlen(e2t_translation[i].ext); - if (path_len < ext_len) - continue; - if (!strcmp(path + path_len - ext_len, e2t_translation[i].ext)) { - WriteMacInt32(finfo + fdType, e2t_translation[i].type); - WriteMacInt32(finfo + fdCreator, e2t_translation[i].creator); - break; - } - } - } -} - -void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Open Finder info file - int fd = open_finf(path, O_RDWR); - if (fd < 0) - return; - - // Write file - write(fd, Mac2HostAddr(finfo), SIZEOF_FInfo); - if (fxinfo) - write(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo); - close(fd); -} - - -/* - * Resource fork emulation functions - */ - -uint32 get_rfork_size(const char *path) -{ - // Open resource file - int fd = open_rsrc(path, O_RDONLY); - if (fd < 0) - return 0; - - // Get size - off_t size = lseek(fd, 0, SEEK_END); - - // Close file and return size - close(fd); - return size < 0 ? 0 : size; -} - -int open_rfork(const char *path, int flag) -{ - return open_rsrc(path, flag); -} - -void close_rfork(const char *path, int fd) -{ - if (fd >= 0) - close(fd); -} - - -/* - * Read "length" bytes from file to "buffer", - * returns number of bytes read (or -1 on error) - */ - -ssize_t extfs_read(int fd, void *buffer, size_t length) -{ - return read(fd, buffer, length); -} - - -/* - * Write "length" bytes from "buffer" to file, - * returns number of bytes written (or -1 on error) - */ - -ssize_t extfs_write(int fd, void *buffer, size_t length) -{ - return write(fd, buffer, length); -} - - -/* - * Remove file/directory (and associated helper files), - * returns false on error (and sets errno) - */ - -bool extfs_remove(const char *path) -{ - // Remove helpers first, don't complain if this fails - char helper_path[MAX_PATH_LENGTH]; - make_helper_path(path, helper_path, ".finf" HOST_DIRSEP_STR, false); - remove(helper_path); - make_helper_path(path, helper_path, ".rsrc" HOST_DIRSEP_STR, false); - remove(helper_path); - - // Now remove file or directory (and helper directories in the directory) - if (remove(path) < 0) { - if (errno == EISDIR || errno == ENOTEMPTY) { - helper_path[0] = 0; - strncpy(helper_path, path, MAX_PATH_LENGTH-1); - add_path_component(helper_path, ".finf"); - rmdir(helper_path); - helper_path[0] = 0; - strncpy(helper_path, path, MAX_PATH_LENGTH-1); - add_path_component(helper_path, ".rsrc"); - rmdir(helper_path); - return rmdir(path) == 0; - } else - return false; - } - return true; -} - - -/* - * Rename/move file/directory (and associated helper files), - * returns false on error (and sets errno) - */ - -bool extfs_rename(const char *old_path, const char *new_path) -{ - // Rename helpers first, don't complain if this fails - char old_helper_path[MAX_PATH_LENGTH], new_helper_path[MAX_PATH_LENGTH]; - make_helper_path(old_path, old_helper_path, ".finf" HOST_DIRSEP_STR, false); - make_helper_path(new_path, new_helper_path, ".finf" HOST_DIRSEP_STR, false); - create_helper_dir(new_path, ".finf" HOST_DIRSEP_STR); - rename(old_helper_path, new_helper_path); - make_helper_path(old_path, old_helper_path, ".rsrc" HOST_DIRSEP_STR, false); - make_helper_path(new_path, new_helper_path, ".rsrc" HOST_DIRSEP_STR, false); - create_helper_dir(new_path, ".rsrc" HOST_DIRSEP_STR); - rename(old_helper_path, new_helper_path); - - // Now rename file - return rename(old_path, new_path) == 0; -} - - -// Convert from the host OS filename encoding to MacRoman -const char *host_encoding_to_macroman(const char *filename) -{ - return filename; -} - -// Convert from MacRoman to host OS filename encoding -const char *macroman_to_host_encoding(const char *filename) -{ - return filename; -} - diff --git a/BasiliskII/src/Windows/gencomp.vcxproj b/BasiliskII/src/Windows/gencomp.vcxproj deleted file mode 100644 index b2c92701..00000000 --- a/BasiliskII/src/Windows/gencomp.vcxproj +++ /dev/null @@ -1,182 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04} - Win32Proj - gencomp - 8.1 - - - - Application - true - v140 - Unicode - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - Application - false - v140 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - $(Configuration)\$(ProjectName)\ - - - true - - - false - $(Configuration)\$(ProjectName)\ - - - false - - - - - - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - - - - - - - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - true - true - - - - - - - - - - - - - Document - "$(OutDir)build68k" "%(Identity)" > ..\uae_cpu\cpudefs.cpp - "$(OutDir)build68k" "%(Identity)" > ..\uae_cpu\cpudefs.cpp - "$(OutDir)build68k" "%(Identity)" > ..\uae_cpu\cpudefs.cpp - "$(OutDir)build68k" "%(Identity)" > ..\uae_cpu\cpudefs.cpp - Generating cpudefs.cpp... - Generating cpudefs.cpp... - Generating cpudefs.cpp... - Generating cpudefs.cpp... - ..\uae_cpu\cpudefs.cpp - ..\uae_cpu\cpudefs.cpp - ..\uae_cpu\cpudefs.cpp - ..\uae_cpu\cpudefs.cpp - $(OutDir)build68k.exe - $(OutDir)build68k.exe - $(OutDir)build68k.exe - $(OutDir)build68k.exe - - - - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/gencomp.vcxproj.filters b/BasiliskII/src/Windows/gencomp.vcxproj.filters deleted file mode 100644 index 861ff2a3..00000000 --- a/BasiliskII/src/Windows/gencomp.vcxproj.filters +++ /dev/null @@ -1,36 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/gencpu.vcxproj b/BasiliskII/src/Windows/gencpu.vcxproj deleted file mode 100644 index c688794b..00000000 --- a/BasiliskII/src/Windows/gencpu.vcxproj +++ /dev/null @@ -1,182 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48} - Win32Proj - gencpu - 8.1 - - - - Application - true - v140 - Unicode - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - Application - false - v140 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - $(Configuration)\$(ProjectName)\ - - - true - - - false - $(Configuration)\$(ProjectName)\ - - - false - - - - - - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - - - - - - - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - . - - - Console - true - true - true - - - - - - - - - - - - - Document - "$(OutDir)build68k" "%(Identity)" > ..\uae_cpu\cpudefs.cpp - "$(OutDir)build68k" "%(Identity)" > ..\uae_cpu\cpudefs.cpp - Generating cpudefs.cpp... - Generating cpudefs.cpp... - ..\uae_cpu\cpudefs.cpp - ..\uae_cpu\cpudefs.cpp - $(OutDir)build68k.exe - $(OutDir)build68k.exe - "$(OutDir)build68k" "%(Identity)" > ..\uae_cpu\cpudefs.cpp - "$(OutDir)build68k" "%(Identity)" > ..\uae_cpu\cpudefs.cpp - Generating cpudefs.cpp... - Generating cpudefs.cpp... - ..\uae_cpu\cpudefs.cpp - ..\uae_cpu\cpudefs.cpp - $(OutDir)build68k.exe - $(OutDir)build68k.exe - - - - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/gencpu.vcxproj.filters b/BasiliskII/src/Windows/gencpu.vcxproj.filters deleted file mode 100644 index d8db474e..00000000 --- a/BasiliskII/src/Windows/gencpu.vcxproj.filters +++ /dev/null @@ -1,36 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - - - - \ No newline at end of file diff --git a/BasiliskII/src/Windows/main_windows.cpp b/BasiliskII/src/Windows/main_windows.cpp deleted file mode 100755 index 7d555c98..00000000 --- a/BasiliskII/src/Windows/main_windows.cpp +++ /dev/null @@ -1,703 +0,0 @@ -/* - * main_windows.cpp - Startup code for Windows - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include -typedef std::basic_string tstring; - -#include "cpu_emulation.h" -#include "sys.h" -#include "rom_patches.h" -#include "xpram.h" -#include "timer.h" -#include "video.h" -#include "cdrom.h" -#include "emul_op.h" -#include "prefs.h" -#include "prefs_editor.h" -#include "macos_util.h" -#include "user_strings.h" -#include "version.h" -#include "main.h" -#include "vm_alloc.h" -#include "sigsegv.h" -#include "util_windows.h" - -#if USE_JIT -extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp -#endif - -#ifdef ENABLE_MON -# include "mon.h" -#endif - -#define DEBUG 0 -#include "debug.h" - - -// Constants -const TCHAR ROM_FILE_NAME[] = TEXT("ROM"); -const int SCRATCH_MEM_SIZE = 0x10000; // Size of scratch memory area - - -// CPU and FPU type, addressing mode -int CPUType; -bool CPUIs68060; -int FPUType; -bool TwentyFourBitAddressing; - - -// Global variables -HANDLE emul_thread = NULL; // Handle of MacOS emulation thread (main thread) - -static uint8 last_xpram[XPRAM_SIZE]; // Buffer for monitoring XPRAM changes -static bool xpram_thread_active = false; // Flag: XPRAM watchdog installed -static volatile bool xpram_thread_cancel = false; // Flag: Cancel XPRAM thread -static SDL_Thread *xpram_thread = NULL; // XPRAM watchdog - -static bool tick_thread_active = false; // Flag: 60Hz thread installed -static volatile bool tick_thread_cancel = false; // Flag: Cancel 60Hz thread -static SDL_Thread *tick_thread; // 60Hz thread - -static SDL_mutex *intflag_lock = NULL; // Mutex to protect InterruptFlags -#define LOCK_INTFLAGS SDL_LockMutex(intflag_lock) -#define UNLOCK_INTFLAGS SDL_UnlockMutex(intflag_lock) - -#if USE_SCRATCHMEM_SUBTERFUGE -uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes -#endif - -#if REAL_ADDRESSING -static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped -#endif - - -// Prototypes -static int xpram_func(void *arg); -static int tick_func(void *arg); -static void one_tick(...); - - -/* - * Ersatz functions - */ - -extern "C" { - -#ifndef HAVE_STRDUP -char *strdup(const char *s) -{ - char *n = (char *)malloc(strlen(s) + 1); - strcpy(n, s); - return n; -} -#endif - -} - - -/* - * Map memory that can be accessed from the Mac side - */ - -void *vm_acquire_mac(size_t size) -{ - return vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); -} - - -/* - * SIGSEGV handler - */ - -static sigsegv_return_t sigsegv_handler(sigsegv_info_t *sip) -{ - const uintptr fault_address = (uintptr)sigsegv_get_fault_address(sip); -#if ENABLE_VOSF - // Handle screen fault - extern bool Screen_fault_handler(sigsegv_info_t *sip); - if (Screen_fault_handler(sip)) - return SIGSEGV_RETURN_SUCCESS; -#endif - -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - // Ignore writes to ROM - if (((uintptr)fault_address - (uintptr)ROMBaseHost) < ROMSize) - return SIGSEGV_RETURN_SKIP_INSTRUCTION; - - // Ignore all other faults, if requested - if (PrefsFindBool("ignoresegv")) - return SIGSEGV_RETURN_SKIP_INSTRUCTION; -#endif - - return SIGSEGV_RETURN_FAILURE; -} - -/* - * Dump state when everything went wrong after a SEGV - */ - -static void sigsegv_dump_state(sigsegv_info_t *sip) -{ - const sigsegv_address_t fault_address = sigsegv_get_fault_address(sip); - const sigsegv_address_t fault_instruction = sigsegv_get_fault_instruction_address(sip); - fprintf(stderr, "Caught SIGSEGV at address %p", fault_address); - if (fault_instruction != SIGSEGV_INVALID_ADDRESS) - fprintf(stderr, " [IP=%p]", fault_instruction); - fprintf(stderr, "\n"); - uaecptr nextpc; - extern void m68k_dumpstate(uaecptr *nextpc); - m68k_dumpstate(&nextpc); -#if USE_JIT && JIT_DEBUG - extern void compiler_dumpstate(void); - compiler_dumpstate(); -#endif - VideoQuitFullScreen(); -#ifdef ENABLE_MON - char *arg[4] = {"mon", "-m", "-r", NULL}; - mon(3, arg); - QuitEmulator(); -#endif -} - - -/* - * Main program - */ - -static void usage(const char *prg_name) -{ - printf( - "Usage: %s [OPTION...]\n" - "\nUnix options:\n" - " --config FILE\n read/write configuration from/to FILE\n" - " --display STRING\n X display to use\n" - " --break ADDRESS\n set ROM breakpoint\n" - " --rominfo\n dump ROM information\n", prg_name - ); - LoadPrefs(NULL); // read the prefs file so PrefsPrintUsage() will print the correct default values - PrefsPrintUsage(); - exit(0); -} - -int main(int argc, char **argv) -{ - char str[256]; - bool cd_boot = false; - - // Initialize variables - RAMBaseHost = NULL; - ROMBaseHost = NULL; - srand(unsigned(time(NULL))); - tzset(); - - // Print some info - printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - printf(" %s\n", GetString(STR_ABOUT_TEXT2)); - - // Parse command line arguments - for (int i=1; i i) { - k -= i; - for (int j=i+k; jm); -} - -void B2_unlock_mutex(B2_mutex *mutex) -{ - if (mutex) - SDL_UnlockMutex(mutex->m); -} - -void B2_delete_mutex(B2_mutex *mutex) -{ - delete mutex; -} - - -/* - * Interrupt flags (must be handled atomically!) - */ - -uint32 InterruptFlags = 0; - -void SetInterruptFlag(uint32 flag) -{ - LOCK_INTFLAGS; - InterruptFlags |= flag; - UNLOCK_INTFLAGS; -} - -void ClearInterruptFlag(uint32 flag) -{ - LOCK_INTFLAGS; - InterruptFlags &= ~flag; - UNLOCK_INTFLAGS; -} - - -/* - * XPRAM watchdog thread (saves XPRAM every minute) - */ - -static void xpram_watchdog(void) -{ - if (memcmp(last_xpram, XPRAM, XPRAM_SIZE)) { - memcpy(last_xpram, XPRAM, XPRAM_SIZE); - SaveXPRAM(); - } -} - -static int xpram_func(void *arg) -{ - while (!xpram_thread_cancel) { - for (int i=0; i<60 && !xpram_thread_cancel; i++) - Delay_usec(999999); // Only wait 1 second so we quit promptly when xpram_thread_cancel becomes true - xpram_watchdog(); - } - return 0; -} - - -/* - * 60Hz thread (really 60.15Hz) - */ - -static void one_second(void) -{ - // Pseudo Mac 1Hz interrupt, update local time - WriteMacInt32(0x20c, TimerDateTime()); - - SetInterruptFlag(INTFLAG_1HZ); - TriggerInterrupt(); -} - -static void one_tick(...) -{ - static int tick_counter = 0; - if (++tick_counter > 60) { - tick_counter = 0; - one_second(); - } - - // Trigger 60Hz interrupt - if (ROMVersion != ROM_VERSION_CLASSIC || HasMacStarted()) { - SetInterruptFlag(INTFLAG_60HZ); - TriggerInterrupt(); - } -} - -static int tick_func(void *arg) -{ - uint64 start = GetTicks_usec(); - int64 ticks = 0; - uint64 next = GetTicks_usec(); - while (!tick_thread_cancel) { - one_tick(); - next += 16625; - int64 delay = next - GetTicks_usec(); - if (delay > 0) - Delay_usec(uint32(delay)); - else if (delay < -16625) - next = GetTicks_usec(); - ticks++; - } - uint64 end = GetTicks_usec(); - D(bug("%Ld ticks in %Ld usec = %f ticks/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start))); - return 0; -} - - -/* - * Get the main window handle - */ - -#ifdef USE_SDL_VIDEO -#include -HWND GetMainWindowHandle(void) -{ - SDL_SysWMinfo wmInfo; - SDL_VERSION(&wmInfo.version); - return SDL_GetWMInfo(&wmInfo) ? wmInfo.window : NULL; -} -#endif - - -/* - * Display alert - */ - -static void display_alert(int title_id, const char *text, int flags) -{ - HWND hMainWnd = GetMainWindowHandle(); - MessageBoxA(hMainWnd, text, GetString(title_id), MB_OK | flags); -} -static void display_alert(int title_id, const wchar_t *text, int flags) -{ - HWND hMainWnd = GetMainWindowHandle(); - MessageBoxW(hMainWnd, text, GetStringW(title_id).get(), MB_OK | flags); -} - - -/* - * Display error alert - */ - -void ErrorAlert(const char *text) -{ - if (PrefsFindBool("nogui")) - return; - - VideoQuitFullScreen(); - display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP); -} -void ErrorAlert(const wchar_t *text) -{ - if (PrefsFindBool("nogui")) - return; - - VideoQuitFullScreen(); - display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP); -} - - -/* - * Display warning alert - */ - -void WarningAlert(const char *text) -{ - if (PrefsFindBool("nogui")) - return; - - display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONINFORMATION); -} -void WarningAlert(const wchar_t *text) -{ - if (PrefsFindBool("nogui")) - return; - - display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONINFORMATION); -} - - -/* - * Display choice alert - */ - -bool ChoiceAlert(const char *text, const char *pos, const char *neg) -{ - printf(GetString(STR_SHELL_WARNING_PREFIX), text); - return false; //!! -} diff --git a/BasiliskII/src/Windows/posix_emu.cpp b/BasiliskII/src/Windows/posix_emu.cpp deleted file mode 100755 index 518a526f..00000000 --- a/BasiliskII/src/Windows/posix_emu.cpp +++ /dev/null @@ -1,1125 +0,0 @@ -/* - * posix_emu.cpp -- posix and virtual desktop - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// TODO: UNC names. Customizable "Virtual Desktop" location. - -#include "sysdeps.h" -#define NO_POSIX_API_HOOK -#include "posix_emu.h" -#include "user_strings.h" -#include "util_windows.h" -#include "main.h" -#include "extfs_defs.h" -#include "prefs.h" -#include - - -#define DEBUG_EXTFS 0 - -#if DEBUG_EXTFS - -// This must be always on. -#define DEBUG 1 -#undef OutputDebugString -#define OutputDebugString extfs_log_write -extern void extfs_log_write( char *s ); -#define EXTFS_LOG_FILE_NAME "extfs.log" -#include "debug.h" - -enum { - DB_EXTFS_NONE=0, - DB_EXTFS_NORMAL, - DB_EXTFS_LOUD -}; -static int16 debug_extfs = DB_EXTFS_NONE; -static HANDLE extfs_log_file = INVALID_HANDLE_VALUE; - -static void extfs_log_open( char *path ) -{ - if(debug_extfs == DB_EXTFS_NONE) return; - - DeleteFile( path ); - extfs_log_file = CreateFile( - path, - GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ, - NULL, - CREATE_ALWAYS, - // FILE_FLAG_WRITE_THROUGH|FILE_FLAG_NO_BUFFERING, - FILE_FLAG_WRITE_THROUGH, - NULL - ); - if( extfs_log_file == INVALID_HANDLE_VALUE ) { - ErrorAlert( "Could not create the EXTFS log file." ); - } -} - -static void extfs_log_close( void ) -{ - if(debug_extfs == DB_EXTFS_NONE) return; - - if( extfs_log_file != INVALID_HANDLE_VALUE ) { - CloseHandle( extfs_log_file ); - extfs_log_file = INVALID_HANDLE_VALUE; - } -} - -static void extfs_log_write( char *s ) -{ - DWORD bytes_written; - - // should have been checked already. - if(debug_extfs == DB_EXTFS_NONE) return; - - if( extfs_log_file != INVALID_HANDLE_VALUE ) { - - DWORD count = strlen(s); - if (0 == WriteFile(extfs_log_file, s, count, &bytes_written, NULL) || - (int)bytes_written != count) - { - extfs_log_close(); - ErrorAlert( "extfs log file write error (out of disk space?). Log closed." ); - } else { - FlushFileBuffers( extfs_log_file ); - } - } -} -#else - -#define DEBUG 0 -#include "debug.h" - -#endif // DEBUG_EXTFS - -int my_errno = 0; - -#define VIRTUAL_ROOT_ID ((HANDLE)0xFFFFFFFE) - -static LPCTSTR desktop_name = TEXT("Virtual Desktop"); -static const char *custom_icon_name = "Icon\r"; -#define my_computer GetString(STR_EXTFS_VOLUME_NAME) - -static TCHAR lb1[MAX_PATH_LENGTH]; -static TCHAR lb2[MAX_PATH_LENGTH]; - -#define MRP(path) translate(path,lb1) -#define MRP2(path) translate(path,lb2) - -#define DISABLE_ERRORS UINT prevmode = SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS) -#define RESTORE_ERRORS SetErrorMode(prevmode); - -static TCHAR host_drive_list[512]; -static TCHAR virtual_root[248]; // Not _MAX_PATH - -const uint8 my_comp_icon[2670] = { - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0xD8, 0x00, 0x00, 0x08, 0xD8, 0x00, 0x00, 0x00, 0x96, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x79, 0x79, 0x79, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xC0, 0xCC, 0xCC, 0xCC, - 0xCC, 0xD7, 0x97, 0x97, 0x97, 0x97, 0x97, 0xC0, 0xC0, 0xC0, 0xC0, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, - 0xCD, 0xDB, 0xD9, 0x79, 0x79, 0x7E, 0x79, 0x0C, 0xDD, 0xCD, 0xDD, 0xCD, 0xCD, 0xDC, 0xDD, 0xCD, - 0xCC, 0xED, 0xED, 0x97, 0x97, 0x97, 0x97, 0x0C, 0xE7, 0x78, 0x77, 0x97, 0x97, 0x97, 0x97, 0x97, - 0xDC, 0xED, 0xDE, 0x79, 0x79, 0x79, 0x99, 0x0C, 0xD9, 0x7E, 0x5E, 0x65, 0x5E, 0x65, 0xD9, 0x79, - 0xCD, 0xDE, 0xDD, 0x97, 0xE7, 0x9E, 0x77, 0xC0, 0x97, 0x9D, 0xCD, 0xCC, 0xC7, 0xCC, 0xE7, 0x97, - 0xCC, 0xED, 0xEE, 0x79, 0x79, 0x79, 0x7E, 0xCC, 0x57, 0xD5, 0xD7, 0xD5, 0xDD, 0x5D, 0xD9, 0x7E, - 0xCD, 0xDE, 0xDE, 0x79, 0x97, 0x97, 0x99, 0x0C, 0x87, 0xCD, 0x75, 0xC7, 0x5C, 0x7D, 0xD9, 0x79, - 0xCD, 0xDD, 0xED, 0xE7, 0x7E, 0x79, 0x77, 0xCC, 0xE7, 0xB0, 0x00, 0xC0, 0x0C, 0xCD, 0xE7, 0x97, - 0xDC, 0xED, 0xEE, 0x79, 0x97, 0x86, 0x79, 0xC0, 0xE7, 0xD0, 0x2C, 0xC1, 0xC2, 0xCD, 0xD9, 0x79, - 0xCD, 0xDE, 0xDD, 0x97, 0x99, 0x79, 0x97, 0x0C, 0xE7, 0xB0, 0xD0, 0xDC, 0xCC, 0xCD, 0xD6, 0x87, - 0xDD, 0xDE, 0xED, 0x79, 0x77, 0xE7, 0x79, 0x0C, 0x58, 0xDC, 0x0C, 0x0C, 0xCC, 0xCD, 0xE9, 0x79, - 0xCD, 0xDD, 0xD5, 0x99, 0x97, 0x99, 0x79, 0xC0, 0x87, 0xD0, 0xC0, 0xC0, 0xC0, 0xCD, 0xD7, 0xE7, - 0xDD, 0xDE, 0xD7, 0x97, 0x79, 0x77, 0xE7, 0x0C, 0xE7, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x79, 0x79, - 0xCD, 0xDE, 0xD9, 0x79, 0x97, 0xE9, 0x79, 0x0C, 0x97, 0x79, 0x79, 0x79, 0x79, 0x79, 0x97, 0x97, - 0xDC, 0xED, 0xE7, 0x97, 0x79, 0x97, 0x97, 0x0C, 0xCD, 0xD7, 0xD7, 0xD7, 0xE7, 0xE7, 0x7E, 0x79, - 0xCD, 0xDE, 0x79, 0x79, 0x97, 0x7E, 0x79, 0xC0, 0xCC, 0xCC, 0x0C, 0xCC, 0x0D, 0xCC, 0xDC, 0xDC, - 0xDC, 0xED, 0x97, 0x97, 0x77, 0x99, 0x79, 0xCC, 0xCC, 0xCC, 0xDC, 0xCC, 0xDC, 0xCC, 0xCC, 0x8D, - 0xCD, 0xDE, 0x79, 0x79, 0x96, 0x77, 0x97, 0x97, 0x97, 0x90, 0xCC, 0xCD, 0xCD, 0xDD, 0xDD, 0xCC, - 0xDD, 0xD9, 0x76, 0x87, 0x97, 0x99, 0x7E, 0x7C, 0x0C, 0xCC, 0xDD, 0xDD, 0xED, 0xDE, 0xDD, 0xEE, - 0xDE, 0xD5, 0xBD, 0xDE, 0x79, 0x79, 0x9C, 0xC0, 0xCC, 0xDD, 0xDD, 0xDD, 0xDE, 0xDD, 0xED, 0xDE, - 0xDE, 0xDD, 0xDE, 0xDE, 0x79, 0x79, 0x70, 0xCD, 0xCC, 0xCC, 0xCC, 0xCC, 0xDC, 0xDD, 0xDD, 0xDD, - 0xDD, 0xDD, 0xED, 0xED, 0x97, 0x97, 0x90, 0xCC, 0x8D, 0xCC, 0xDC, 0xCD, 0xCC, 0xCC, 0xCC, 0xCC, - 0xCC, 0xEE, 0xDE, 0xDE, 0x79, 0x7E, 0x70, 0xCC, 0x88, 0xDC, 0xCC, 0xCC, 0xCD, 0xDD, 0xDD, 0xDC, - 0xCD, 0xDD, 0xED, 0xED, 0x97, 0x97, 0xEC, 0xCC, 0xCC, 0xCC, 0xDC, 0xCC, 0xCD, 0xDD, 0xED, 0xDD, - 0xDC, 0xED, 0xED, 0xEE, 0x79, 0x79, 0xDC, 0x0D, 0xCC, 0xDC, 0xCC, 0xCD, 0xCC, 0xCC, 0xCC, 0x0C, - 0xDC, 0xDE, 0xDE, 0xED, 0x97, 0xDC, 0xCC, 0xDC, 0xCD, 0xCC, 0xDC, 0xCD, 0xCC, 0xCC, 0xCD, 0xCC, - 0xCC, 0xED, 0xED, 0x79, 0xDD, 0xC0, 0xCD, 0xCC, 0xDC, 0xCD, 0xCC, 0xDC, 0xCC, 0xDC, 0xDD, 0xCD, - 0xCD, 0xED, 0x97, 0x97, 0xDD, 0xCC, 0xCC, 0x00, 0xC0, 0xDD, 0xCD, 0xCC, 0xCC, 0xCD, 0xD0, 0xDC, - 0xDD, 0xF7, 0x99, 0x79, 0x97, 0x9D, 0xDD, 0xDD, 0xCC, 0xC0, 0xCC, 0x0C, 0xDC, 0xDC, 0xCD, 0xCD, - 0xDF, 0x79, 0x77, 0x97, 0x79, 0x79, 0x79, 0x79, 0xDD, 0xDE, 0xDC, 0xCC, 0xCC, 0xC0, 0xC0, 0xDD, - 0xE9, 0x79, 0x97, 0x99, 0x97, 0xE7, 0xE7, 0x97, 0x97, 0x9D, 0x79, 0xDD, 0xDD, 0xDD, 0xCD, 0xDE, - 0x79, 0x79, 0x7E, 0x77, 0x00, 0x00, 0x04, 0x00, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0xF5, - 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, - 0x2B, 0x2B, 0xF9, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0xF6, - 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF7, 0xF7, 0xF7, - 0xF7, 0xF8, 0x81, 0xFA, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0xF7, 0xF8, 0x81, 0x81, 0x81, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0xA5, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, - 0xF8, 0xF8, 0x81, 0xFA, 0xFB, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0xA5, 0xC2, 0xC2, 0xFB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFB, 0xC2, 0xC2, 0xC2, - 0xF7, 0xF8, 0x81, 0x81, 0xFB, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0x2B, - 0xA5, 0xC2, 0xC2, 0xFB, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x81, 0xC2, 0xC2, 0xC2, - 0xF7, 0xF8, 0x81, 0x81, 0xFB, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0x2B, - 0xA5, 0xC2, 0xF9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF9, 0xFB, 0xC2, 0xC2, 0xC2, - 0xF7, 0xF8, 0x81, 0x81, 0xFB, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0xA5, 0xC2, 0xF9, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0xF9, 0x81, 0xC2, 0xC2, 0xC2, - 0xF8, 0x56, 0xFA, 0x81, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0xA5, 0xC2, 0xF9, 0xF5, 0xF5, 0xF5, 0xF6, 0xF6, 0xF6, 0xF6, 0x2B, 0xF9, 0xFB, 0xC2, 0xC2, 0xC2, - 0xF8, 0x56, 0x81, 0x81, 0xFB, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0xA5, 0xC2, 0xF9, 0xF5, 0x0A, 0xF6, 0x2B, 0x0A, 0xF6, 0x0A, 0x2B, 0xF9, 0x81, 0xC2, 0xC2, 0xC2, - 0xF8, 0x56, 0x81, 0x81, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0xA5, 0xC2, 0xF9, 0xF5, 0xF8, 0xF6, 0x56, 0xF7, 0xF7, 0xF8, 0x2B, 0xF9, 0x81, 0xC2, 0xC2, 0xC2, - 0xF8, 0x56, 0x81, 0x81, 0xFB, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0xA5, 0xC2, 0xF9, 0xF5, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0x2B, 0x2B, 0xF9, 0xFB, 0xC2, 0xC2, 0xC2, - 0xF8, 0x56, 0xFA, 0x81, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0xA5, 0xC2, 0xF9, 0xF6, 0xF6, 0xF5, 0xF6, 0xF6, 0xF6, 0xF6, 0x2B, 0xF9, 0x81, 0xC2, 0xC2, 0xC2, - 0xF8, 0x56, 0x81, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0xA5, 0xC2, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xC2, 0xC2, 0xC2, 0xC2, - 0xF8, 0x56, 0x81, 0x81, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0xA5, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, - 0xF8, 0x56, 0x81, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0xF7, 0x56, 0xF8, 0x7A, 0x7A, 0x9E, 0x9E, 0x9E, 0x9E, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, - 0xF8, 0x56, 0x81, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, - 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF7, 0xF7, 0xF8, 0xF8, - 0xF8, 0x56, 0x81, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF7, 0xF7, - 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x56, 0xB9, 0xF8, - 0xF8, 0x56, 0x81, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, - 0xC2, 0xC2, 0xC2, 0xF6, 0x2B, 0x2B, 0xF7, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0xF8, - 0xF8, 0x56, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, - 0xF6, 0xF6, 0x2B, 0xF8, 0x56, 0xFA, 0xF9, 0x81, 0x81, 0x81, 0xFA, 0x81, 0x81, 0x81, 0xFB, 0x81, - 0xFB, 0xFB, 0xFB, 0x81, 0xFA, 0xFA, 0xFA, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xF6, 0xF6, - 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFB, - 0x81, 0xFB, 0xF9, 0xFA, 0xFA, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, 0xF7, - 0xF8, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF8, 0xF8, 0x56, 0x56, 0xF9, 0xF9, 0xF9, 0xFA, - 0xFA, 0xFA, 0xFA, 0x81, 0x81, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, 0xF7, - 0x93, 0xA0, 0xF7, 0xF7, 0xF8, 0xF7, 0xF7, 0xF8, 0xF7, 0xF7, 0xF7, 0xF7, 0x2B, 0x2B, 0x2B, 0x2B, - 0x2B, 0x2B, 0x81, 0xFB, 0x81, 0xFB, 0xFB, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, 0xF7, - 0xA0, 0xA0, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x56, 0x56, 0xF9, 0xF9, 0xF9, 0xF8, 0xF7, - 0xF7, 0xF7, 0xFB, 0xFB, 0x81, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, 0xF7, - 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF9, 0xF9, 0xFB, 0xFB, 0xFB, 0xF8, 0xF9, - 0xF9, 0xF7, 0x81, 0xFB, 0xFB, 0x81, 0xFB, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xF8, 0x2B, 0x2B, 0x56, - 0x2B, 0x2B, 0xF9, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF8, - 0xF8, 0xF7, 0xFB, 0xFB, 0x81, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xF8, 0xF8, 0xF6, 0xF6, 0xF9, 0xF8, - 0x2B, 0xF9, 0xF8, 0x2B, 0xF9, 0x2B, 0x2B, 0xF9, 0x2B, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, - 0xF7, 0xF7, 0x81, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xF9, 0xF8, 0xF6, 0xF6, 0xF7, 0xF9, 0xF8, 0x2B, - 0xF9, 0xF8, 0xF6, 0xF9, 0xF8, 0xF6, 0xF9, 0xF8, 0xF6, 0x2B, 0xF9, 0x2B, 0xF9, 0x56, 0x2B, 0xF9, - 0x2B, 0xF9, 0xAC, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xFA, 0xF9, 0xF8, 0x2B, 0x2B, 0x2B, 0xF5, 0xF5, - 0xF5, 0xF5, 0xF9, 0xF8, 0xF6, 0xF9, 0xF8, 0xF6, 0x2B, 0xF8, 0x2B, 0xF9, 0x56, 0x2B, 0x56, 0x2B, - 0x56, 0x81, 0xAC, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xFA, 0xFA, 0xFA, 0xF9, 0xF8, - 0xF8, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF5, 0x2B, 0xF9, 0xF6, 0xF9, 0xF8, 0xF7, 0xF9, 0x2B, 0xF9, - 0x81, 0xAC, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, - 0xFA, 0xFA, 0xFA, 0xFA, 0xF9, 0xF8, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF5, 0xF5, 0xF5, 0x56, 0x81, - 0xAC, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, - 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xFA, 0xF9, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF8, 0x81, 0x81, - 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0x00, 0x00, 0x01, 0x00, 0x03, 0xFF, 0xFF, 0xE0, - 0x02, 0x00, 0x00, 0x38, 0x02, 0xFF, 0xFF, 0x3C, 0x02, 0xFF, 0xFF, 0x3C, 0x02, 0xFF, 0xFF, 0x3C, - 0x02, 0xF0, 0x0F, 0x3C, 0x02, 0xFF, 0xFF, 0x3C, 0x02, 0xFF, 0xFF, 0x7C, 0x02, 0xE0, 0x1F, 0x7C, - 0x02, 0xE0, 0x1F, 0x7C, 0x02, 0xE0, 0x1F, 0x7C, 0x02, 0xE0, 0x1F, 0x7C, 0x02, 0xE0, 0x1F, 0x78, - 0x02, 0xFF, 0xFF, 0x78, 0x02, 0xFF, 0xFF, 0x78, 0x02, 0x1F, 0xFF, 0x70, 0x02, 0x00, 0x00, 0x70, - 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x1F, 0xFF, 0xFF, - 0x02, 0x00, 0x3F, 0xFF, 0x02, 0x40, 0x00, 0x3F, 0x02, 0xC0, 0x7C, 0x3F, 0x02, 0x00, 0x7D, 0xBF, - 0x0F, 0x20, 0x00, 0x3F, 0x32, 0x49, 0x00, 0x3C, 0xC4, 0x92, 0x2D, 0x70, 0xE0, 0x24, 0x1A, 0xE0, - 0x1F, 0x00, 0xA5, 0xC0, 0x00, 0xFC, 0x03, 0x80, 0x00, 0x03, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0xE0, - 0x03, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, - 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, - 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xF8, - 0x03, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xF0, - 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, - 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, - 0x0F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE0, - 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x40, - 0x1F, 0xFC, 0x10, 0x06, 0x10, 0x06, 0x10, 0x06, 0x10, 0x06, 0x10, 0x06, 0x10, 0x06, 0x10, 0x04, - 0x1F, 0xFC, 0x0F, 0xFE, 0x0F, 0xFF, 0x18, 0x67, 0x34, 0x06, 0x69, 0x64, 0x72, 0xC8, 0x3F, 0xF0, - 0x1F, 0xFC, 0x1F, 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x1F, 0xFC, - 0x1F, 0xFC, 0x07, 0xFF, 0x1F, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x7F, 0xFE, 0xFF, 0xFC, 0x07, 0xF8, - 0x00, 0x00, 0x00, 0x80, 0x79, 0x7C, 0x0C, 0x0C, 0xCC, 0xCC, 0xCD, 0x97, 0x97, 0x90, 0xE7, 0x97, - 0x97, 0x97, 0xDD, 0xD9, 0x79, 0x7C, 0xE7, 0xD5, 0x5E, 0x58, 0xCE, 0xD7, 0x97, 0x9C, 0xDD, 0x5D, - 0x7D, 0xB7, 0xDD, 0x59, 0x79, 0x7C, 0x9D, 0x10, 0x1D, 0xD9, 0xCE, 0xD7, 0x97, 0x9C, 0xDD, 0x0C, - 0xCC, 0xE7, 0xDD, 0xD9, 0x79, 0x7C, 0xED, 0xDD, 0xDD, 0x79, 0xCE, 0xE7, 0xE7, 0x90, 0xE7, 0x77, - 0x97, 0x97, 0xDD, 0x79, 0x79, 0x7C, 0xCC, 0xDC, 0xCD, 0xC8, 0xDD, 0x97, 0x97, 0x99, 0x7C, 0xDD, - 0xDD, 0xDE, 0xDE, 0xDE, 0x7E, 0x7C, 0xCC, 0xCC, 0xCD, 0xCD, 0xDD, 0xDE, 0x99, 0x0C, 0x8C, 0xCC, - 0xCC, 0xCC, 0xCD, 0xED, 0x77, 0xCC, 0xCC, 0xCD, 0xDD, 0xED, 0xCE, 0xDE, 0x9C, 0xCD, 0xCD, 0xCD, - 0x0D, 0xCC, 0xCE, 0xE7, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xCC, 0xDE, 0x99, 0x97, 0x97, 0x9D, 0xDD, - 0xDD, 0xDE, 0xE9, 0x77, 0x00, 0x00, 0x01, 0x00, 0xC2, 0xC2, 0xC2, 0xF5, 0xF5, 0xF5, 0xF6, 0xF6, - 0xF6, 0x2B, 0x2B, 0x2B, 0xF7, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xC2, 0xC2, 0xC2, - 0xC2, 0xC2, 0xC2, 0xC2, 0xF8, 0x81, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xC2, 0x81, 0xAA, - 0xAA, 0xAA, 0xFB, 0xC2, 0xF8, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xF9, 0x7F, 0x7F, - 0x7F, 0x56, 0x81, 0xC2, 0xF8, 0x81, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xF9, 0x0A, 0xF6, - 0x0A, 0x56, 0xFB, 0xC2, 0xF8, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xF9, 0xF6, 0xF6, - 0xF6, 0x56, 0x81, 0xC2, 0x56, 0x81, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xF9, 0xF9, 0xF9, - 0xF9, 0xF9, 0xC2, 0xC2, 0xF8, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xC2, 0xC2, 0xC2, - 0xC2, 0xC2, 0xC2, 0xC2, 0x56, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0x2B, 0x2B, 0x2B, 0xF7, 0xF7, - 0xF7, 0xF7, 0xF7, 0xB9, 0x56, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0x56, 0xF9, - 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0x81, 0xFA, 0x81, 0xC2, 0xC2, 0xC2, 0xF6, 0xF6, 0xF7, 0x2B, 0x2B, - 0x2B, 0xF8, 0xF8, 0xF8, 0xF9, 0xFA, 0x81, 0xFB, 0xC2, 0xC2, 0xF5, 0xF7, 0x93, 0xF7, 0xF7, 0xF7, - 0xF7, 0x2B, 0x2B, 0x2B, 0x2B, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xF5, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, - 0xF9, 0xFB, 0xFB, 0xF9, 0xF7, 0xFB, 0x81, 0xFB, 0xC2, 0xF6, 0xF8, 0xF9, 0x2B, 0xF9, 0x2B, 0xF9, - 0xF6, 0xF8, 0x2B, 0xF8, 0xF7, 0xFB, 0xFB, 0xC2, 0xF9, 0xF7, 0xF9, 0xF7, 0xF9, 0xF7, 0xF9, 0x2B, - 0xF9, 0x2B, 0xF8, 0x2B, 0x81, 0xAC, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF9, 0xF9, 0xF9, - 0xF9, 0xF9, 0xF9, 0x81, 0xAC, 0xC2, 0xC2, 0xC2, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0xD8, - 0x00, 0x00, 0x08, 0xD8, 0x00, 0x00, 0x00, 0x96, 0x02, 0x1C, 0xC1, 0xC4, 0x18, 0x9C, 0x00, 0x00, - 0x00, 0x1C, 0x00, 0x96, 0x00, 0x05, 0x69, 0x63, 0x6C, 0x34, 0x00, 0x00, 0x00, 0x32, 0x69, 0x63, - 0x6C, 0x38, 0x00, 0x00, 0x00, 0x3E, 0x49, 0x43, 0x4E, 0x23, 0x00, 0x00, 0x00, 0x4A, 0x69, 0x63, - 0x73, 0x23, 0x00, 0x00, 0x00, 0x56, 0x69, 0x63, 0x73, 0x34, 0x00, 0x00, 0x00, 0x62, 0x69, 0x63, - 0x73, 0x38, 0x00, 0x00, 0x00, 0x6E, 0xBF, 0xB9, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1C, - 0xE2, 0x10, 0xBF, 0xB9, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0x04, 0x02, 0x1C, 0xE1, 0xAC, 0xBF, 0xB9, - 0xFF, 0xFF, 0x00, 0x00, 0x06, 0x08, 0x02, 0x1C, 0xE1, 0xA4, 0xBF, 0xB9, 0xFF, 0xFF, 0x00, 0x00, - 0x07, 0x0C, 0x02, 0x1C, 0xE1, 0xF8, 0xBF, 0xB9, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0x50, 0x02, 0x1C, - 0xE1, 0xDC, 0xBF, 0xB9, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xD4, 0x02, 0x1C, 0xE1, 0xD0 -}; - -static bool use_streams[ 'Z'-'A'+1 ]; - -static bool is_ntfs_volume(LPCTSTR rootdir) -{ - bool ret = false; - TCHAR tst_file[_MAX_PATH], tst_stream[_MAX_PATH]; - _sntprintf( tst_file, lengthof(tst_file), TEXT("%sb2query.tmp"), rootdir ); - _sntprintf( tst_stream, lengthof(tst_stream), TEXT("%s:AFP_AfpInfo"), tst_file ); - if(!exists(tst_file)) { - if(create_file( tst_file, 0 )) { - if(create_file( tst_stream, 0 )) { - ret = true; - } - DeleteFile( tst_file ); - } - } - return ret; -} - - -// !!UNC -void init_posix_emu(void) -{ - if(!validate_stat_struct) { - ErrorAlert( "Invalid struct my_stat -- edit posix_emu.h" ); - QuitEmulator(); - } - -#if DEBUG_EXTFS - debug_extfs = PrefsFindInt16("debugextfs"); - - debug_extfs = DB_EXTFS_LOUD; - - if(debug_extfs != DB_EXTFS_NONE) { - extfs_log_open( EXTFS_LOG_FILE_NAME ); - } -#endif - - // We cannot use ExtFS "RootPath" because of the virtual desktop. - if(PrefsFindBool("enableextfs")) { - PrefsReplaceString("extfs", ""); - } else { - PrefsRemoveItem("extfs"); - D(bug("extfs disabled by user\n")); -#if DEBUG_EXTFS - extfs_log_close(); -#endif - return; - } - - const char *extdrives = PrefsFindString("extdrives"); - - // Set up drive list. - size_t outinx = 0; - for( TCHAR letter = TEXT('A'); letter <= TEXT('Z'); letter++ ) { - if(extdrives && !strchr(extdrives,letter)) continue; - TCHAR rootdir[20]; - _sntprintf( rootdir, lengthof(rootdir), TEXT("%c:\\"), letter ); - use_streams[ letter - 'A' ] = false; - switch(GetDriveType(rootdir)) { - case DRIVE_FIXED: - case DRIVE_REMOTE: - case DRIVE_RAMDISK: - // TODO: NTFS AFP? - // fall - case DRIVE_REMOVABLE: - case DRIVE_CDROM: - if(outinx < lengthof(host_drive_list)) { - host_drive_list[outinx] = letter; - outinx += 2; - } - } - } - - // Set up virtual desktop root. - // TODO: this should be customizable. - GetModuleFileName( NULL, virtual_root, lengthof(virtual_root) ); - TCHAR *p = _tcsrchr( virtual_root, TEXT('\\') ); - if(p) { - _tcscpy( ++p, desktop_name ); - } else { - // should never happen - _sntprintf( virtual_root, lengthof(virtual_root), TEXT("C:\\%s"), desktop_name ); - } - CreateDirectory( virtual_root, 0 ); - - // Set up an icon looking like "My Computer" - // Can be overwritten just like any other folder custom icon. - if(my_access(custom_icon_name,0) != 0) { - int fd = my_creat( custom_icon_name, 0 ); - if(fd >= 0) { - my_close(fd); - fd = open_rfork( custom_icon_name, O_RDWR|O_CREAT ); - if(fd >= 0) { - my_write( fd, my_comp_icon, sizeof(my_comp_icon) ); - my_close(fd); - static uint8 host_finfo[SIZEOF_FInfo]; - uint32 finfo = Host2MacAddr(host_finfo); - get_finfo(custom_icon_name, finfo, 0, false); - WriteMacInt16(finfo + fdFlags, kIsInvisible); - set_finfo(custom_icon_name, finfo, 0, false); - get_finfo(my_computer, finfo, 0, true); - WriteMacInt16(finfo + fdFlags, ReadMacInt16(finfo + fdFlags) | kHasCustomIcon); - set_finfo(my_computer, finfo, 0, true); - } else { - my_remove(custom_icon_name); - } - } - } -} - -void final_posix_emu(void) -{ -#if DEBUG_EXTFS - extfs_log_close(); -#endif -} - -static void charset_host2mac( char *s ) -{ - int i, len=strlen(s), code; - - for( i=len-3; i>=0; i-- ) { - if( s[i] == '%' && isxdigit(s[i+1]) && isxdigit(s[i+2]) ) { - sscanf( &s[i], "%%%02X", &code ); - memmove( &s[i], &s[i+2], strlen(&s[i+2])+1 ); - s[i] = code; - } - } -} - -static void charset_mac2host( LPTSTR s ) -{ - size_t len = _tcslen(s); - - D(bug(TEXT("charset_mac2host(%s)...\n"), s)); - - for( size_t i=len; i-->0; ) { - bool convert = false; - switch( (unsigned char)s[i] ) { - // case '\r': // handled by "default" - // case '\n': - // case '\t': - case '/': - // case '\\': // Backslash is tricky -- "s" is a full path! - // case ':': - case '*': - case '?': - case '"': - case '<': - case '>': - case '|': - case '%': - convert = true; - break; - default: - if((unsigned char)s[i] < ' ') convert = true; - break; - } - if(convert) { - TCHAR sml[10]; - _sntprintf( sml, lengthof(sml), TEXT("%%%02X"), s[i] ); - memmove( &s[i+2], &s[i], (_tcslen(&s[i])+1) * sizeof(TCHAR) ); - memmove( &s[i], sml, 3 * sizeof(TCHAR) ); - } - } - D(bug(TEXT("charset_mac2host = %s\n"), s)); -} - -static void make_mask( - TCHAR *mask, - LPCTSTR dir, - LPCTSTR a1, - LPCTSTR a2 -) -{ - _tcscpy( mask, dir ); - - size_t len = _tcslen(mask); - if( len && mask[len-1] != '\\' ) _tcscat( mask, TEXT("\\") ); - - if( a1 ) _tcscat( mask, a1 ); - if( a2 ) _tcscat( mask, a2 ); -} - -// !!UNC -static LPTSTR translate( LPCTSTR path, TCHAR *buffer ) -{ - TCHAR *l = host_drive_list; - const TCHAR *p = path; - - while(*l) { - if(_totupper(p[1]) == _totupper(*l)) break; - l += _tcslen(l) + 1; - } - - if(p[0] == TEXT('\\') && *l && (p[2] == 0 || p[2] == TEXT(':') || p[2] == TEXT('\\'))) { - p += 2; - if(*p == TEXT(':')) p++; - if(*p == TEXT('\\')) p++; - _sntprintf( buffer, MAX_PATH_LENGTH, TEXT("%c:\\%s"), *l, p ); - } else { - if(*path == TEXT('\\')) { - _sntprintf( buffer, MAX_PATH_LENGTH, TEXT("%s%s"), virtual_root, path ); - } else { - int len = _tcslen(path); - if(len == 0 || path[len-1] == TEXT('\\')) { - make_mask( buffer, virtual_root, path, tstr(my_computer).get() ); - } else { - make_mask( buffer, virtual_root, path, 0 ); - } - } - } - charset_mac2host( buffer ); - - return buffer; -} - -// helpers -static void strip_trailing_bs( LPTSTR path ) -{ - size_t len = _tcslen(path); - if(len > 0 && path[len-1] == TEXT('\\')) path[len-1] = 0; -} - -#if 0 /* defined is util_windows.cpp */ -static int exists( const char *p ) -{ - WIN32_FIND_DATA fdata; - - int result = 0; - - HANDLE h = FindFirstFile( p, &fdata ); - if(h != INVALID_HANDLE_VALUE) { - result = 1; - FindClose( h ); - } - - D(bug("exists(%s) = %d\n", p, result)); - - return result; -} -#endif - -static int is_dir( LPCTSTR p ) -{ - WIN32_FIND_DATA fdata; - - int result = 0; - - HANDLE h = FindFirstFile( p, &fdata ); - if(h != INVALID_HANDLE_VALUE) { - result = (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - FindClose( h ); - } - return result; -} - -static int myRemoveDirectory( LPCTSTR source ) -{ - HANDLE fh; - WIN32_FIND_DATA FindFileData; - int ok, result = 1; - TCHAR mask[_MAX_PATH]; - - D(bug(TEXT("removing folder %s\n"), source)); - - make_mask( mask, source, TEXT("*.*"), 0 ); - - fh = FindFirstFile( mask, &FindFileData ); - ok = fh != INVALID_HANDLE_VALUE; - while(ok) { - make_mask( mask, source, FindFileData.cFileName, 0 ); - D(bug(TEXT("removing item %s\n"), mask)); - int isdir = (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - if(isdir) { - // must delete ".finf", ".rsrc" but not ".", ".." - if(_tcscmp(FindFileData.cFileName,TEXT(".")) && _tcscmp(FindFileData.cFileName,TEXT(".."))) { - result = myRemoveDirectory( mask ); - if(!result) break; - } - } else { - D(bug(TEXT("DeleteFile %s\n"), mask)); - result = DeleteFile( mask ); - if(!result) break; - } - ok = FindNextFile( fh, &FindFileData ); - } - if(fh != INVALID_HANDLE_VALUE) FindClose( fh ); - if(result) { - D(bug(TEXT("RemoveDirectory %s\n"), source)); - result = RemoveDirectory( source ); - } - return result; -} - -static void make_folders( LPCTSTR path ) -{ - TCHAR local_path[_MAX_PATH], *p; - _tcscpy( local_path, path ); - p = _tcsrchr( local_path, TEXT('\\') ); - if(p) { - *p = 0; - if(_tcslen(local_path) > 3) { - make_folders(local_path); - _tmkdir(local_path); - } - } -} - -// !!UNC -static bool is_same_drive( LPCTSTR p1, LPCTSTR p2 ) -{ - return _totupper(*p1) == _totupper(*p2); -} - -// Used when the drives are known to be different. -// Can't use MoveFileEx() etc because of the Win9x limitations. -// It would simulate CopyFile*() -- DeleteFile*() anyway -static int file_move_copy( LPCTSTR src, LPCTSTR dst, bool delete_old ) -{ - int result = 0; - my_errno = 0; - - D(bug(TEXT("file_copy %s -> %s\n"), src, dst)); - - // Fail if exists -- it's up to MacOS to move things to Trash - if(CopyFile(src,dst,TRUE)) { - if(delete_old && !DeleteFile(src)) { - result = -1; - my_errno = EACCES; - } - } else { - result = -1; - if(exists(src)) - my_errno = EACCES; - else - my_errno = ENOENT; - } - return result; -} - -static int file_move( LPCTSTR src, LPCTSTR dst ) -{ - return file_move_copy( src, dst, true ); -} - -static int file_copy( LPCTSTR src, LPCTSTR dst ) -{ - return file_move_copy( src, dst, false ); -} - -static int folder_copy( LPCTSTR folder_src, LPCTSTR folder_dst ) -{ - HANDLE fh; - WIN32_FIND_DATA FindFileData; - int ok, result = 0; - TCHAR mask[_MAX_PATH]; - - D(bug(TEXT("copying folder %s -> \n"), folder_src, folder_dst)); - - my_errno = 0; - - if(!CreateDirectory( folder_dst, 0 )) { - my_errno = EACCES; - return -1; - } - - make_mask( mask, folder_src, TEXT("*.*"), 0 ); - - fh = FindFirstFile( mask, &FindFileData ); - ok = fh != INVALID_HANDLE_VALUE; - while(ok) { - make_mask( mask, folder_src, FindFileData.cFileName, 0 ); - int isdir = (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - TCHAR target[_MAX_PATH]; - make_mask( target, folder_dst, FindFileData.cFileName, 0 ); - D(bug(TEXT("copying item %s -> %s\n"), mask, target)); - if(isdir) { - if(_tcscmp(FindFileData.cFileName,TEXT(".")) && _tcscmp(FindFileData.cFileName,TEXT(".."))) { - result = folder_copy( mask, target ); - if(result < 0) break; - } - } else { - result = file_copy( mask, target ); - if(result < 0) break; - } - ok = FindNextFile( fh, &FindFileData ); - } - if(fh != INVALID_HANDLE_VALUE) FindClose( fh ); - return result; -} - -// dir enumeration -void closedir( struct DIR *d ) -{ - DISABLE_ERRORS; - if(d) { - if(d->h != INVALID_HANDLE_VALUE && d->h != VIRTUAL_ROOT_ID) { - FindClose( d->h ); - } - delete d; - } - RESTORE_ERRORS; -} - -static int make_dentry( struct DIR *d ) -{ - int ok = 0; - - memset( &d->de, 0, sizeof(d->de) ); - if(d->h != INVALID_HANDLE_VALUE) { - if( (d->FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && - *d->FindFileData.cFileName == TEXT('.')) - { - ok = 0; - } else { - strlcpy( d->de.d_name, d->FindFileData.cFileName, lengthof(d->de.d_name) ); - charset_host2mac( d->de.d_name ); - ok = 1; - } - } - return ok; -} - -struct dirent *readdir( struct DIR *d ) -{ - DISABLE_ERRORS; - - dirent *de = 0; - - if(d) { - if(d->h != INVALID_HANDLE_VALUE) { - if(d->h == VIRTUAL_ROOT_ID) { - make_dentry(d); - de = &d->de; - d->vname_list += _tcslen(d->vname_list) + 1; - if(*d->vname_list) { - _tcscpy( d->FindFileData.cFileName, d->vname_list ); - d->FindFileData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; - } else { - // Out of static drive entries. Continue with other stuff. - TCHAR mask[MAX_PATH_LENGTH]; - make_mask( mask, virtual_root, TEXT("*.*"), 0 ); - d->h = FindFirstFile( mask, &d->FindFileData ); - } - } else { - int done = 0; - do { - if(make_dentry(d)) { - de = &d->de; - done = 1; - } - if(!FindNextFile( d->h, &d->FindFileData )) { - FindClose( d->h ); - d->h = INVALID_HANDLE_VALUE; - done = 1; - } - } while(!done); - } - } - } - - if(de) { - D(bug("readdir found %s\n", de->d_name)); - } - - RESTORE_ERRORS; - - return de; -} - -struct DIR *opendir( const char *path ) -{ - DISABLE_ERRORS; - auto tpath = tstr(path); - DIR *d = new DIR; - if(d) { - memset( d, 0, sizeof(DIR) ); - if(*tpath.get() == 0) { - d->vname_list = host_drive_list; - if(d->vname_list) { - d->h = VIRTUAL_ROOT_ID; - _tcscpy( d->FindFileData.cFileName, d->vname_list ); - d->FindFileData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; - } else { - d->h = INVALID_HANDLE_VALUE; - } - } else { - TCHAR mask[MAX_PATH_LENGTH]; - make_mask( mask, MRP(tpath.get()), TEXT("*.*"), 0 ); - - D(bug(TEXT("opendir path=%s, mask=%s\n"), tpath.get(), mask)); - - d->h = FindFirstFile( mask, &d->FindFileData ); - if(d->h == INVALID_HANDLE_VALUE) { - delete d; - d = 0; - } - } - } - - D(bug(TEXT("opendir(%s,%s) = %08x\n"), tpath.get(), MRP(tpath.get()), d)); - - RESTORE_ERRORS; - - return d; -} - -static void dump_stat( const struct my_stat *st ) -{ - D(bug("stat: size = %ld, mode = %ld, a = %ld, m = %ld, c = %ld\n", st->st_size, st->st_mode, st->st_atime, st->st_mtime, st->st_ctime)); -} - - - -// Exported hook functions -int my_stat( const char *path, struct my_stat *st ) -{ - DISABLE_ERRORS; - - auto tpath = tstr(path); - int result; - - if(*tpath.get() == 0) { - /// virtual root - memset( st, 0, sizeof(struct my_stat) ); - st->st_mode = _S_IFDIR; - result = 0; - my_errno = 0; - } else { - result = _tstat( MRP(tpath.get()), (struct _stat *)st ); - if(result < 0) { - my_errno = errno; - } else { - my_errno = 0; - } - } - - D(bug(TEXT("stat(%s,%s) = %d\n"), tpath.get(), MRP(tpath.get()), result)); - if(result >= 0) dump_stat( st ); - RESTORE_ERRORS; - return result; -} - -int my_fstat( int fd, struct my_stat *st ) -{ - DISABLE_ERRORS; - int result = _fstat( fd, (struct _stat *)st ); - if(result < 0) { - my_errno = errno; - } else { - my_errno = 0; - } - D(bug("fstat(%d) = %d\n", fd, result)); - if(result >= 0) dump_stat( st ); - RESTORE_ERRORS; - return result; -} - -int my_open( const char *path, int mode, ... ) -{ - DISABLE_ERRORS; - int result; - auto tpath = tstr(path); - LPCTSTR p = MRP(tpath.get()); - - // Windows "open" does not handle _O_CREAT and _O_BINARY as it should - if(mode & _O_CREAT) { - if(exists(p)) { - result = _topen( p, mode & ~_O_CREAT ); - D(bug(TEXT("open-nocreat(%s,%s,%d) = %d\n"), tpath.get(), p, mode, result)); - } else { - result = _tcreat( p, _S_IWRITE|_S_IREAD ); - if(result < 0) { - make_folders(p); - result = _tcreat( p, _S_IWRITE|_S_IREAD ); - } - D(bug(TEXT("open-creat(%s,%s,%d) = %d\n"), tpath.get(), p, mode, result)); - } - } else { - result = _topen( p, mode ); - D(bug(TEXT("open(%s,%s,%d) = %d\n"), tpath.get(), p, mode, result)); - } - if(result < 0) { - my_errno = errno; - } else { - setmode(result, _O_BINARY); - my_errno = 0; - } - RESTORE_ERRORS; - return result; -} - -int my_rename( const char *old_path, const char *new_path ) -{ - DISABLE_ERRORS; - int result = -1; - auto told_path = tstr(old_path); - auto tnew_path = tstr(new_path); - LPCTSTR p_old = MRP(told_path.get()); - LPCTSTR p_new = MRP2(tnew_path.get()); - - result = my_access(old_path,0); - if(result < 0) { - // my_errno already set - } else { - if(is_same_drive(p_old,p_new)) { - result = _trename( p_old, p_new ); - if(result != 0) { // by definition, rename may also return a positive value to indicate an error - my_errno = errno; - } else { - my_errno = 0; - } - } else { - if(is_dir(p_old)) { - result = folder_copy( p_old, p_new ); - // my_errno already set - if(result >= 0) { - if(myRemoveDirectory( p_old )) { - my_errno = 0; - result = 0; - } else { - // there is no proper error code for this failure. - my_errno = EACCES; - result = -1; - } - } - } else { - result = file_move( p_old, p_new ); - // my_errno already set - } - } - } - D(bug(TEXT("rename(%s,%s,%s,%s) = %d\n"), told_path.get(), p_old, tnew_path.get(), p_new, result)); - RESTORE_ERRORS; - return result; -} - -int my_access( const char *path, int mode ) -{ - DISABLE_ERRORS; - auto tpath = tstr(path); - LPCTSTR p = MRP(tpath.get()); - WIN32_FIND_DATA fdata; - - int result; - - if(is_dir(p)) { - // access does not work for folders. - HANDLE h = FindFirstFile( p, &fdata ); - if(h != INVALID_HANDLE_VALUE) { - FindClose( h ); - if(mode == W_OK) { - if( (fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0 ) { - result = 0; - my_errno = 0; - } else { - result = -1; - my_errno = EACCES; - } - } else { - result = 0; - my_errno = 0; - } - } else { - result = -1; - my_errno = ENOENT; - } - } else { - // W_OK, F_OK are ok. - result = _taccess(p,mode); - if(result < 0) { - my_errno = errno; - } else { - my_errno = 0; - } - } - - D(bug(TEXT("access(%s,%s,%d) = %d\n"), tpath.get(), p, mode, result)); - RESTORE_ERRORS; - return result; -} - -int my_mkdir( const char *path, int mode ) -{ - DISABLE_ERRORS; - auto tpath = tstr(path); - LPTSTR p = MRP(tpath.get()); - strip_trailing_bs(p); - int result = _tmkdir( p ); - if(result < 0) { - make_folders(p); - result = _tmkdir( p ); - } - if(result < 0) { - my_errno = errno; - } else { - my_errno = 0; - } - D(bug(TEXT("mkdir(%s,%s,%d) = %d\n"), tpath.get(), p, mode, result)); - RESTORE_ERRORS; - return result; -} - -int my_remove( const char *path ) -{ - DISABLE_ERRORS; - auto tpath = tstr(path); - LPTSTR p = MRP(tpath.get()); - strip_trailing_bs(p); - int result; - if(is_dir(p)) { - result = myRemoveDirectory( p ); - } else { - D(bug(TEXT("DeleteFile %s\n"), p)); - result = DeleteFile( p ); - } - if(result) { - result = 0; - my_errno = 0; - } else { - result = -1; - if(exists(p)) { - my_errno = EACCES; - } else { - my_errno = ENOENT; - } - } - D(bug(TEXT("remove(%s,%s) = %d\n"), tpath.get(), p, result)); - RESTORE_ERRORS; - return result; -} - -int my_creat( const char *path, int mode ) -{ - DISABLE_ERRORS; - auto tpath = tstr(path); - LPCTSTR p = MRP(tpath.get()); - int result = _tcreat( p, _S_IWRITE|_S_IREAD ); // note mode - if(result < 0) { - make_folders(p); - result = _tcreat( p, _S_IWRITE|_S_IREAD ); // note mode - } - if(result < 0) { - my_errno = errno; - } else { - setmode(result, _O_BINARY); - my_errno = 0; - } - D(bug(TEXT("creat(%s,%s,%d) = %d\n"), tpath.get(), p, mode,result)); - RESTORE_ERRORS; - return result; -} - -int my_chsize( int fd, size_t sz ) -{ - DISABLE_ERRORS; - int result = chsize(fd,sz); - if(result < 0) { - my_errno = errno; - } else { - my_errno = 0; - } - RESTORE_ERRORS; - return result; -} - -int my_close( int fd ) -{ - DISABLE_ERRORS; - int result = close(fd); - if(result < 0) { - my_errno = errno; - } else { - my_errno = 0; - } - RESTORE_ERRORS; - D(bug("close(%d) = %d\n", fd, result)); - return result; -} - -long my_lseek( int fd, long offset, int origin ) -{ - DISABLE_ERRORS; - int result = lseek( fd, offset, origin ); - if(result < 0) { - my_errno = errno; - } else { - my_errno = 0; - } - RESTORE_ERRORS; - return result; -} - -int my_read( int fd, void *buffer, unsigned int count ) -{ - DISABLE_ERRORS; - int result = read( fd, buffer, count ); - if(result < 0) { - my_errno = errno; - } else { - my_errno = 0; - } - RESTORE_ERRORS; - D(bug("read(%ld,%08x,%ld) = %d\n", fd, buffer, count, result)); - - return result; -} - -int my_write( int fd, const void *buffer, unsigned int count ) -{ - DISABLE_ERRORS; - int result = write( fd, buffer, count ); - if(result < 0) { - my_errno = errno; - } else { - my_errno = 0; - } - RESTORE_ERRORS; - D(bug("write(%ld,%08x,%ld) = %d\n", fd, buffer, count, result)); - return result; -} diff --git a/BasiliskII/src/Windows/posix_emu.h b/BasiliskII/src/Windows/posix_emu.h deleted file mode 100755 index f5077558..00000000 --- a/BasiliskII/src/Windows/posix_emu.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * posix_emu.h - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include "extfs.h" - -void init_posix_emu(void); -void final_posix_emu(void); - -typedef struct dirent { - char d_name[MAX_PATH_LENGTH]; -} dirent; - -typedef struct DIR { - HANDLE h; - WIN32_FIND_DATA FindFileData; - dirent de; - TCHAR *vname_list; -} DIR; - -// emulated -DIR *opendir( const char *path ); -void closedir( DIR *d ); -struct dirent *readdir( DIR *d ); - -// access() mode: exists? -#ifndef F_OK -#define F_OK 0 -#endif -// access() mode: can do r/w? -#ifndef W_OK -#define W_OK 6 -#endif - -// hook stat functions to create virtual desktop -// because of errno all used funcs must be hooked. -int my_stat( const char *, struct my_stat * ); -int my_fstat( int, struct my_stat * ); -int my_open( const char *, int, ... ); -int my_rename( const char *, const char * ); -int my_access( const char *, int ); -int my_mkdir( const char *path, int mode ); -int my_remove( const char * ); -int my_creat( const char *path, int mode ); -int my_creat( const char *path, int mode ); -int my_close( int fd ); -long my_lseek( int fd, long, int); -int my_read( int fd, void *, unsigned int); -int my_write( int fd, const void *, unsigned int); -int my_chsize( int fd, unsigned int size ); -int my_locking( int fd, int mode, long nbytes ); - -extern int my_errno; - -// must hook all other functions that manipulate file names -#ifndef NO_POSIX_API_HOOK -#define stat my_stat -#define fstat my_fstat -#define open my_open -#define rename my_rename -#define access my_access -#define mkdir my_mkdir -#define remove my_remove -#define creat my_creat -#define close my_close -#define lseek my_lseek -#define read my_read -#define write my_write -#define ftruncate my_chsize -#define locking my_locking - -#undef errno -#define errno my_errno -#endif //!NO_POSIX_API_HOOK - -#ifndef S_ISDIR -#define S_ISDIR(stat_mode) (((stat_mode) & _S_IFDIR) != 0) -#endif - -// can't #define "stat" unless there's a replacement for "struct stat" -struct my_stat { - _dev_t st_dev; - _ino_t st_ino; - unsigned short st_mode; - short st_nlink; - short st_uid; - short st_gid; - _dev_t st_rdev; - _off_t st_size; - time_t st_atime; - time_t st_mtime; - time_t st_ctime; -}; - -// Your compiler may have different "struct stat" -> edit "struct my_stat" -#define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct stat) ) - -#define st_crtime st_ctime diff --git a/BasiliskII/src/Windows/prefs_editor_gtk.cpp b/BasiliskII/src/Windows/prefs_editor_gtk.cpp deleted file mode 100644 index a659c4e0..00000000 --- a/BasiliskII/src/Windows/prefs_editor_gtk.cpp +++ /dev/null @@ -1,1769 +0,0 @@ -/* - * prefs_editor_gtk.cpp - Preferences editor, Unix implementation using GTK+ - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include - -#include "user_strings.h" -#include "version.h" -#include "cdrom.h" -#include "xpram.h" -#include "prefs.h" -#include "prefs_editor.h" -#include "util_windows.h" -#include "b2ether/inc/b2ether_hl.h" - - -// Global variables -static GtkWidget *win; // Preferences window -static bool start_clicked = true; // Return value of PrefsEditor() function - - -// Prototypes -static void create_volumes_pane(GtkWidget *top); -static void create_scsi_pane(GtkWidget *top); -static void create_graphics_pane(GtkWidget *top); -static void create_input_pane(GtkWidget *top); -static void create_serial_pane(GtkWidget *top); -static void create_ethernet_pane(GtkWidget *top); -static void create_memory_pane(GtkWidget *top); -static void create_jit_pane(GtkWidget *top); -static void read_settings(void); - - -/* - * SheepShaver glue - */ - -#ifdef SHEEPSHAVER -#define DISABLE_SCSI 1 -#define PROGRAM_NAME "SheepShaver" -enum { - STR_WINDOW_LAB = STR_WINDOW_CTRL, - STR_FULLSCREEN_LAB = STR_FULLSCREEN_CTRL, - STR_SERIALA_CTRL = STR_SERPORTA_CTRL, - STR_SERIALB_CTRL = STR_SERPORTB_CTRL, -}; -#else -#define DISABLE_SCSI 1 /* XXX merge code from original Basilisk II for Windows */ -#define PROGRAM_NAME "BasiliskII" -#endif - - -/* - * Utility functions - */ - -struct opt_desc { - int label_id; - GtkSignalFunc func; -}; - -struct combo_desc { - int label_id; -}; - -struct file_req_assoc { - file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {} - GtkWidget *req; - GtkWidget *entry; -}; - -static void cb_browse_ok(GtkWidget *button, file_req_assoc *assoc) -{ - gchar *file = (char *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); - gtk_entry_set_text(GTK_ENTRY(assoc->entry), file); - gtk_widget_destroy(assoc->req); - delete assoc; -} - -static void cb_browse(GtkWidget *widget, void *user_data) -{ - GtkWidget *req = gtk_file_selection_new(GetString(STR_BROWSE_TITLE)); - gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(cb_browse_ok), new file_req_assoc(req, (GtkWidget *)user_data)); - gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_widget_show(req); -} - -static GtkWidget *make_browse_button(GtkWidget *entry) -{ - GtkWidget *button; - - button = gtk_button_new_with_label(GetString(STR_BROWSE_CTRL)); - gtk_widget_show(button); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc)cb_browse, (void *)entry); - return button; -} - -static void add_menu_item(GtkWidget *menu, const char *label, GtkSignalFunc func, gpointer data = NULL) -{ - GtkWidget *item = gtk_menu_item_new_with_label(label); - gtk_widget_show(item); - gtk_signal_connect(GTK_OBJECT(item), "activate", func, data); - gtk_menu_append(GTK_MENU(menu), item); -} - -static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func) -{ - add_menu_item(menu, GetString(label_id), func, NULL); -} - -static GtkWidget *make_pane(GtkWidget *notebook, int title_id) -{ - GtkWidget *frame, *label, *box; - - frame = gtk_frame_new(NULL); - gtk_widget_show(frame); - gtk_container_border_width(GTK_CONTAINER(frame), 4); - - label = gtk_label_new(GetString(title_id)); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label); - - box = gtk_vbox_new(FALSE, 4); - gtk_widget_show(box); - gtk_container_set_border_width(GTK_CONTAINER(box), 4); - gtk_container_add(GTK_CONTAINER(frame), box); - return box; -} - -static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *buttons) -{ - GtkWidget *bb, *button; - - bb = gtk_hbutton_box_new(); - gtk_widget_show(bb); - gtk_container_set_border_width(GTK_CONTAINER(bb), border); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bb), GTK_BUTTONBOX_DEFAULT_STYLE); - gtk_button_box_set_spacing(GTK_BUTTON_BOX(bb), 4); - gtk_box_pack_start(GTK_BOX(top), bb, FALSE, FALSE, 0); - - while (buttons->label_id) { - button = gtk_button_new_with_label(GetString(buttons->label_id)); - gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", buttons->func, NULL); - gtk_box_pack_start(GTK_BOX(bb), button, TRUE, TRUE, 0); - buttons++; - } - return bb; -} - -static GtkWidget *make_separator(GtkWidget *top) -{ - GtkWidget *sep = gtk_hseparator_new(); - gtk_box_pack_start(GTK_BOX(top), sep, FALSE, FALSE, 0); - gtk_widget_show(sep); - return sep; -} - -static GtkWidget *make_table(GtkWidget *top, int x, int y) -{ - GtkWidget *table = gtk_table_new(x, y, FALSE); - gtk_widget_show(table); - gtk_box_pack_start(GTK_BOX(top), table, FALSE, FALSE, 0); - return table; -} - -static GtkWidget *table_make_option_menu(GtkWidget *table, int row, int label_id, const opt_desc *options, int active) -{ - GtkWidget *label, *opt, *menu; - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - opt = gtk_option_menu_new(); - gtk_widget_show(opt); - menu = gtk_menu_new(); - - while (options->label_id) { - add_menu_item(menu, options->label_id, options->func); - options++; - } - gtk_menu_set_active(GTK_MENU(menu), active); - - gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu); - gtk_table_attach(GTK_TABLE(table), opt, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - return menu; -} - -static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, GList *glist) -{ - GtkWidget *label, *combo; - char str[32]; - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - combo = gtk_combo_new(); - gtk_widget_show(combo); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist); - - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value); - gtk_table_attach(GTK_TABLE(table), combo, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - - return combo; -} - -static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, const combo_desc *options) -{ - GList *glist = NULL; - while (options->label_id) { - glist = g_list_append(glist, (void *)GetString(options->label_id)); - options++; - } - - return table_make_combobox(table, row, label_id, default_value, glist); -} - -static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id, const char *prefs_item, bool only_dirs = false) -{ - GtkWidget *box, *label, *entry, *button; - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - const char *str = PrefsFindString(prefs_item); - if (str == NULL) - str = ""; - - box = gtk_hbox_new(FALSE, 4); - gtk_widget_show(box); - gtk_table_attach(GTK_TABLE(table), box, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - - entry = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(entry), str); - gtk_widget_show(entry); - gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); - - button = make_browse_button(entry); - gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); - g_object_set_data(G_OBJECT(entry), "chooser_button", button); - return entry; -} - -static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc *options, int active) -{ - GtkWidget *box, *label, *opt, *menu; - - box = gtk_hbox_new(FALSE, 4); - gtk_widget_show(box); - gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0); - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); - - opt = gtk_option_menu_new(); - gtk_widget_show(opt); - menu = gtk_menu_new(); - - while (options->label_id) { - add_menu_item(menu, options->label_id, options->func); - options++; - } - gtk_menu_set_active(GTK_MENU(menu), active); - - gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu); - gtk_box_pack_start(GTK_BOX(box), opt, FALSE, FALSE, 0); - return menu; -} - -static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *prefs_item, bool only_dirs = false) -{ - GtkWidget *box, *label, *entry; - - box = gtk_hbox_new(FALSE, 4); - gtk_widget_show(box); - gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0); - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); - - const char *str = PrefsFindString(prefs_item); - if (str == NULL) - str = ""; - - entry = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(entry), str); - gtk_widget_show(entry); - gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); - return entry; -} - -static const gchar *get_file_entry_path(GtkWidget *entry) -{ - return gtk_entry_get_text(GTK_ENTRY(entry)); -} - -static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func) -{ - GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id)); - gtk_widget_show(button); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), PrefsFindBool(prefs_item)); - gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button); - gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0); - return button; -} - -static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *default_value, GList *glist) -{ - GtkWidget *box, *label, *combo; - - box = gtk_hbox_new(FALSE, 4); - gtk_widget_show(box); - gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0); - - label = gtk_label_new(GetString(label_id)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); - - combo = gtk_combo_new(); - gtk_widget_show(combo); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist); - - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value); - gtk_box_pack_start(GTK_BOX(box), combo, TRUE, TRUE, 0); - - return combo; -} - -static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *default_value, const combo_desc *options) -{ - GList *glist = NULL; - while (options->label_id) { - glist = g_list_append(glist, (void *)GetString(options->label_id)); - options++; - } - - return make_combobox(top, label_id, default_value, glist); -} - - -/* - * Show preferences editor - * Returns true when user clicked on "Start", false otherwise - */ - -// Window closed -static gint window_closed(void) -{ - return FALSE; -} - -// Window destroyed -static void window_destroyed(void) -{ - gtk_main_quit(); -} - -// "Start" button clicked -static void cb_start(...) -{ - start_clicked = true; - read_settings(); - SavePrefs(); - gtk_widget_destroy(win); -} - -// "Zap PRAM" button clicked -static void cb_zap_pram(...) -{ - ZapPRAM(); -} - -// "Quit" button clicked -static void cb_quit(...) -{ - start_clicked = false; - gtk_widget_destroy(win); -} - -// "OK" button of "About" dialog clicked -static void dl_quit(GtkWidget *dialog) -{ - gtk_widget_destroy(dialog); -} - -// "About" button clicked -static void cb_about(...) -{ - GtkWidget *dialog; - - GtkWidget *label, *button; - - char str[512]; - sprintf(str, - PROGRAM_NAME "\nVersion %d.%d\n\n" - "Copyright (C) 1997-2008 Christian Bauer et al.\n" - "E-mail: cb@cebix.net\n" -#ifdef SHEEPSHAVER - "http://sheepshaver.cebix.net/\n\n" -#else - "http://basilisk.cebix.net/\n\n" -#endif - PROGRAM_NAME " comes with ABSOLUTELY NO\n" - "WARRANTY. This is free software, and\n" - "you are welcome to redistribute it\n" - "under the terms of the GNU General\n" - "Public License.\n", - VERSION_MAJOR, VERSION_MINOR - ); - - dialog = gtk_dialog_new(); - gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE)); - gtk_container_border_width(GTK_CONTAINER(dialog), 5); - gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150); - - label = gtk_label_new(str); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); - - button = gtk_button_new_with_label(GetString(STR_OK_BUTTON)); - gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog)); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_widget_grab_default(button); - - gtk_widget_show(dialog); -} - -// Menu item descriptions -static GtkItemFactoryEntry menu_items[] = { - {(gchar *)GetString(STR_PREFS_MENU_FILE_GTK), NULL, NULL, 0, ""}, - {(gchar *)GetString(STR_PREFS_ITEM_START_GTK), "S", GTK_SIGNAL_FUNC(cb_start), 0, NULL}, - {(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK), NULL, GTK_SIGNAL_FUNC(cb_zap_pram), 0, NULL}, - {(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK), NULL, NULL, 0, ""}, - {(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "Q", GTK_SIGNAL_FUNC(cb_quit), 0, NULL}, - {(gchar *)GetString(STR_HELP_MENU_GTK), NULL, NULL, 0, ""}, - {(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), "H", GTK_SIGNAL_FUNC(cb_about), 0, NULL} -}; - -void PrefsMigrate(void) -{ - // Ethernet - const char *ether = PrefsFindString("ether"); - if (ether && ether[0] == '{') { - PrefsReplaceString("etherguid", ether); - PrefsReplaceString("ether", "b2ether"); - } - if (PrefsFindBool("routerenabled")) { - PrefsRemoveItem("etherguid"); - PrefsReplaceString("ether", "router"); - } -} - -bool PrefsEditor(void) -{ - // Create window - win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE)); - gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL); - gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL); - - // Create window contents - GtkWidget *box = gtk_vbox_new(FALSE, 4); - gtk_widget_show(box); - gtk_container_add(GTK_CONTAINER(win), box); - - GtkAccelGroup *accel_group = gtk_accel_group_new(); - GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "
", accel_group); - gtk_item_factory_create_items(item_factory, sizeof(menu_items) / sizeof(menu_items[0]), menu_items, NULL); -#if GTK_CHECK_VERSION(1,3,15) - gtk_window_add_accel_group(GTK_WINDOW(win), accel_group); -#else - gtk_accel_group_attach(accel_group, GTK_OBJECT(win)); -#endif - GtkWidget *menu_bar = gtk_item_factory_get_widget(item_factory, "
"); - gtk_widget_show(menu_bar); - gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0); - - GtkWidget *notebook = gtk_notebook_new(); - gtk_widget_show(notebook); - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP); - gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), FALSE); - gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0); - - create_volumes_pane(notebook); -#ifndef DISABLE_SCSI - create_scsi_pane(notebook); -#endif - create_graphics_pane(notebook); - create_input_pane(notebook); - create_serial_pane(notebook); - create_ethernet_pane(notebook); - create_memory_pane(notebook); - create_jit_pane(notebook); - - static const opt_desc buttons[] = { - {STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)}, - {STR_QUIT_BUTTON, GTK_SIGNAL_FUNC(cb_quit)}, - {0, NULL} - }; - make_button_box(box, 4, buttons); - - // Show window and enter main loop - gtk_widget_show(win); - gtk_main(); - return start_clicked; -} - - -/* - * "Volumes" pane - */ - -static GtkWidget *w_enableextfs, *w_extdrives, *w_cdrom_drive; -static GtkWidget *volume_list; -static int selected_volume; - -// Set sensitivity of widgets -static void set_volumes_sensitive(void) -{ - const bool enable_extfs = PrefsFindBool("enableextfs"); - gtk_widget_set_sensitive(w_extdrives, enable_extfs); - const bool no_cdrom = PrefsFindBool("nocdrom"); - gtk_widget_set_sensitive(w_cdrom_drive, !no_cdrom); -} - -// Volume in list selected -static void cl_selected(GtkWidget *list, int row, int column) -{ - selected_volume = row; -} - -// Volume selected for addition -static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc) -{ - gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); - gtk_clist_append(GTK_CLIST(volume_list), &file); - gtk_widget_destroy(assoc->req); - delete assoc; -} - -// Volume selected for creation -static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc) -{ - gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); - - const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry)); - size_t size = atoi(str) << 20; - - int fd = _open(file, _O_WRONLY | _O_CREAT | _O_BINARY | _O_TRUNC, _S_IREAD | _S_IWRITE); - if (fd >= 0) { - if (_chsize(fd, size) == 0) - gtk_clist_append(GTK_CLIST(volume_list), &file); - _close(fd); - } - gtk_widget_destroy(GTK_WIDGET(assoc->req)); - delete assoc; -} - -// "Add Volume" button clicked -static void cb_add_volume(...) -{ - GtkWidget *req = gtk_file_selection_new(GetString(STR_ADD_VOLUME_TITLE)); - gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(add_volume_ok), new file_req_assoc(req, NULL)); - gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_widget_show(req); -} - -// "Create Hardfile" button clicked -static void cb_create_volume(...) -{ - GtkWidget *req = gtk_file_selection_new(GetString(STR_CREATE_VOLUME_TITLE)); - - GtkWidget *box = gtk_hbox_new(FALSE, 4); - gtk_widget_show(box); - GtkWidget *label = gtk_label_new(GetString(STR_HARDFILE_SIZE_CTRL)); - gtk_widget_show(label); - GtkWidget *entry = gtk_entry_new(); - gtk_widget_show(entry); - char str[32]; - sprintf(str, "%d", 40); - gtk_entry_set_text(GTK_ENTRY(entry), str); - gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(req)->main_vbox), box, FALSE, FALSE, 0); - - gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(create_volume_ok), new file_req_assoc(req, entry)); - gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_widget_show(req); -} - -// "Remove Volume" button clicked -static void cb_remove_volume(...) -{ - gtk_clist_remove(GTK_CLIST(volume_list), selected_volume); -} - -// "Boot From" selected -static void mn_boot_any(...) {PrefsReplaceInt32("bootdriver", 0);} -static void mn_boot_cdrom(...) {PrefsReplaceInt32("bootdriver", CDROMRefNum);} - -// "Enable external file system" button toggled -static void tb_enableextfs(GtkWidget *widget) -{ - PrefsReplaceBool("enableextfs", GTK_TOGGLE_BUTTON(widget)->active); - set_volumes_sensitive(); -} - -// "No CD-ROM Driver" button toggled -static void tb_nocdrom(GtkWidget *widget) -{ - PrefsReplaceBool("nocdrom", GTK_TOGGLE_BUTTON(widget)->active); - set_volumes_sensitive(); -} - -// Add names of CD-ROM devices -static GList *add_cdrom_names(void) -{ - GList *glist = NULL; - - char rootdir[4] = "X:\\"; - for (char letter = 'C'; letter <= 'Z'; letter++) { - rootdir[0] = letter; - if (GetDriveType(rootdir) == DRIVE_CDROM) - glist = g_list_append(glist, strdup(rootdir)); - } - - return glist; -} - -// "Enable polling" button toggled -static void tb_pollmedia(GtkWidget *widget) -{ - PrefsReplaceBool("pollmedia", GTK_TOGGLE_BUTTON(widget)->active); -} - -// Read settings from widgets and set preferences -static void read_volumes_settings(void) -{ - while (PrefsFindString("disk")) - PrefsRemoveItem("disk"); - - for (int i=0; irows; i++) { - char *str; - gtk_clist_get_text(GTK_CLIST(volume_list), i, 0, &str); - PrefsAddString("disk", str); - } - - const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_cdrom_drive)->entry)); - if (str && strlen(str)) - PrefsReplaceString("cdrom", str); - else - PrefsRemoveItem("cdrom"); - - PrefsReplaceString("extdrives", get_file_entry_path(w_extdrives)); -} - -// Create "Volumes" pane -static void create_volumes_pane(GtkWidget *top) -{ - GtkWidget *box, *scroll, *menu; - - box = make_pane(top, STR_VOLUMES_PANE_TITLE); - - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_widget_show(scroll); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - volume_list = gtk_clist_new(1); - gtk_widget_show(volume_list); - gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE); - gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE); - gtk_clist_set_reorderable(GTK_CLIST(volume_list), true); - gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL); - char *str; - int32 index = 0; - while ((str = const_cast(PrefsFindString("disk", index++))) != NULL) - gtk_clist_append(GTK_CLIST(volume_list), &str); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), volume_list); - gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0); - selected_volume = 0; - - static const opt_desc buttons[] = { - {STR_ADD_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_add_volume)}, - {STR_CREATE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_create_volume)}, - {STR_REMOVE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_remove_volume)}, - {0, NULL}, - }; - make_button_box(box, 0, buttons); - make_separator(box); - - static const opt_desc options[] = { - {STR_BOOT_ANY_LAB, GTK_SIGNAL_FUNC(mn_boot_any)}, - {STR_BOOT_CDROM_LAB, GTK_SIGNAL_FUNC(mn_boot_cdrom)}, - {0, NULL} - }; - int bootdriver = PrefsFindInt32("bootdriver"), active = 0; - switch (bootdriver) { - case 0: active = 0; break; - case CDROMRefNum: active = 1; break; - } - menu = make_option_menu(box, STR_BOOTDRIVER_CTRL, options, active); - - make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", GTK_SIGNAL_FUNC(tb_nocdrom)); - - GList *glist = add_cdrom_names(); - str = const_cast(PrefsFindString("cdrom")); - if (str == NULL) - str = ""; - w_cdrom_drive = make_combobox(box, STR_CDROM_DRIVE_CTRL, str, glist); - - make_checkbox(box, STR_POLLMEDIA_CTRL, "pollmedia", GTK_SIGNAL_FUNC(tb_pollmedia)); - - make_separator(box); - w_enableextfs = make_checkbox(box, STR_EXTFS_ENABLE_CTRL, "enableextfs", GTK_SIGNAL_FUNC(tb_enableextfs)); - w_extdrives = make_file_entry(box, STR_EXTFS_DRIVES_CTRL, "extdrives", true); - - set_volumes_sensitive(); -} - - -/* - * "JIT Compiler" pane - */ - -#ifndef SHEEPSHAVER -static GtkWidget *w_jit_fpu; -static GtkWidget *w_jit_atraps; -static GtkWidget *w_jit_cache_size; -static GtkWidget *w_jit_lazy_flush; -static GtkWidget *w_jit_follow_const_jumps; -#endif - -// Set sensitivity of widgets -static void set_jit_sensitive(void) -{ -#ifndef SHEEPSHAVER - const bool jit_enabled = PrefsFindBool("jit"); - gtk_widget_set_sensitive(w_jit_fpu, jit_enabled); - gtk_widget_set_sensitive(w_jit_cache_size, jit_enabled); - gtk_widget_set_sensitive(w_jit_lazy_flush, jit_enabled); - gtk_widget_set_sensitive(w_jit_follow_const_jumps, jit_enabled); -#endif -} - -// "Use JIT Compiler" button toggled -static void tb_jit(GtkWidget *widget) -{ - PrefsReplaceBool("jit", GTK_TOGGLE_BUTTON(widget)->active); - set_jit_sensitive(); -} - -// "Compile FPU Instructions" button toggled -#ifndef SHEEPSHAVER -static void tb_jit_fpu(GtkWidget *widget) -{ - PrefsReplaceBool("jitfpu", GTK_TOGGLE_BUTTON(widget)->active); -} -#endif - -// "Lazy translation cache invalidation" button toggled -#ifndef SHEEPSHAVER -static void tb_jit_lazy_flush(GtkWidget *widget) -{ - PrefsReplaceBool("jitlazyflush", GTK_TOGGLE_BUTTON(widget)->active); -} -#endif - -// "Translate through constant jumps (inline blocks)" button toggled -#ifndef SHEEPSHAVER -static void tb_jit_follow_const_jumps(GtkWidget *widget) -{ - PrefsReplaceBool("jitinline", GTK_TOGGLE_BUTTON(widget)->active); -} -#endif - -// Read settings from widgets and set preferences -static void read_jit_settings(void) -{ -#if USE_JIT - bool jit_enabled = PrefsFindBool("jit"); - if (jit_enabled) { -#ifndef SHEEPSHAVER - const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_jit_cache_size)->entry)); - PrefsReplaceInt32("jitcachesize", atoi(str)); -#endif - } -#endif -} - -// "Use built-in 68k DR emulator" button toggled -#ifdef SHEEPSHAVER -static void tb_jit_68k(GtkWidget *widget) -{ - PrefsReplaceBool("jit68k", GTK_TOGGLE_BUTTON(widget)->active); -} -#endif - -// Create "JIT Compiler" pane -static void create_jit_pane(GtkWidget *top) -{ -#if USE_JIT - GtkWidget *box, *table, *label, *menu; - char str[32]; - - box = make_pane(top, STR_JIT_PANE_TITLE); - make_checkbox(box, STR_JIT_CTRL, "jit", GTK_SIGNAL_FUNC(tb_jit)); - -#ifndef SHEEPSHAVER - w_jit_fpu = make_checkbox(box, STR_JIT_FPU_CTRL, "jitfpu", GTK_SIGNAL_FUNC(tb_jit_fpu)); - - // Translation cache size - static const combo_desc options[] = { - STR_JIT_CACHE_SIZE_2MB_LAB, - STR_JIT_CACHE_SIZE_4MB_LAB, - STR_JIT_CACHE_SIZE_8MB_LAB, - STR_JIT_CACHE_SIZE_16MB_LAB, - 0 - }; - sprintf(str, "%d", PrefsFindInt32("jitcachesize")); - w_jit_cache_size = make_combobox(box, STR_JIT_CACHE_SIZE_CTRL, str, options); - - // Lazy translation cache invalidation - w_jit_lazy_flush = make_checkbox(box, STR_JIT_LAZY_CINV_CTRL, "jitlazyflush", GTK_SIGNAL_FUNC(tb_jit_lazy_flush)); - - // Follow constant jumps (inline basic blocks) - w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", GTK_SIGNAL_FUNC(tb_jit_follow_const_jumps)); -#endif - - set_jit_sensitive(); -#endif - -#ifdef SHEEPSHAVER - make_checkbox(box, STR_JIT_68K_CTRL, "jit68k", GTK_SIGNAL_FUNC(tb_jit_68k)); -#endif -} - -/* - * "SCSI" pane - */ - -static GtkWidget *w_scsi[7]; - -// Read settings from widgets and set preferences -static void read_scsi_settings(void) -{ -#ifndef DISABLE_SCSI - for (int id=0; id<7; id++) { - char prefs_name[32]; - sprintf(prefs_name, "scsi%d", id); - const char *str = get_file_entry_path(w_scsi[id]); - if (str && strlen(str)) - PrefsReplaceString(prefs_name, str); - else - PrefsRemoveItem(prefs_name); - } -#endif -} - -// Create "SCSI" pane -static void create_scsi_pane(GtkWidget *top) -{ -#ifndef DISABLE_SCSI - GtkWidget *box; - - box = make_pane(top, STR_SCSI_PANE_TITLE); - - for (int id=0; id<7; id++) { - char prefs_name[32]; - sprintf(prefs_name, "scsi%d", id); - w_scsi[id] = make_file_entry(box, STR_SCSI_ID_0 + id, prefs_name); - } -#endif -} - - -/* - * "Graphics/Sound" pane - */ - -// Display types -enum { - DISPLAY_WINDOW, - DISPLAY_SCREEN -}; - -static GtkWidget *w_frameskip, *w_display_x, *w_display_y; -static GtkWidget *l_frameskip, *l_display_x, *l_display_y; -static int display_type; -static int dis_width, dis_height; - -// Hide/show graphics widgets -static void hide_show_graphics_widgets(void) -{ - switch (display_type) { - case DISPLAY_WINDOW: - gtk_widget_show(w_frameskip); gtk_widget_show(l_frameskip); - break; - case DISPLAY_SCREEN: - gtk_widget_hide(w_frameskip); gtk_widget_hide(l_frameskip); - break; - } -} - -// "Window" video type selected -static void mn_window(...) -{ - display_type = DISPLAY_WINDOW; - hide_show_graphics_widgets(); -} - -// "Fullscreen" video type selected -static void mn_fullscreen(...) -{ - display_type = DISPLAY_SCREEN; - hide_show_graphics_widgets(); - PrefsReplaceInt32("frameskip", 1); -} - -// "5 Hz".."60Hz" selected -static void mn_5hz(...) {PrefsReplaceInt32("frameskip", 12);} -static void mn_7hz(...) {PrefsReplaceInt32("frameskip", 8);} -static void mn_10hz(...) {PrefsReplaceInt32("frameskip", 6);} -static void mn_15hz(...) {PrefsReplaceInt32("frameskip", 4);} -static void mn_30hz(...) {PrefsReplaceInt32("frameskip", 2);} -static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);} -static void mn_dynamic(...) {PrefsReplaceInt32("frameskip", 0);} - -// QuickDraw acceleration -#ifdef SHEEPSHAVER -static void tb_gfxaccel(GtkWidget *widget) -{ - PrefsReplaceBool("gfxaccel", GTK_TOGGLE_BUTTON(widget)->active); -} -#endif - -// Set sensitivity of widgets -static void set_graphics_sensitive(void) -{ - const bool sound_enabled = !PrefsFindBool("nosound"); -} - -// "Disable Sound Output" button toggled -static void tb_nosound(GtkWidget *widget) -{ - PrefsReplaceBool("nosound", GTK_TOGGLE_BUTTON(widget)->active); - set_graphics_sensitive(); -} - -// Read graphics preferences -static void parse_graphics_prefs(void) -{ - display_type = DISPLAY_WINDOW; -#ifdef SHEEPSHAVER - dis_width = 640; - dis_height = 480; -#else - dis_width = 512; - dis_height = 384; -#endif - - const char *str = PrefsFindString("screen"); - if (str) { - if (sscanf(str, "win/%d/%d", &dis_width, &dis_height) == 2) - display_type = DISPLAY_WINDOW; - else if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2) - display_type = DISPLAY_SCREEN; - } -} - -// Read settings from widgets and set preferences -static void read_graphics_settings(void) -{ - const char *str; - - str = gtk_entry_get_text(GTK_ENTRY(w_display_x)); - dis_width = atoi(str); - - str = gtk_entry_get_text(GTK_ENTRY(w_display_y)); - dis_height = atoi(str); - - char pref[256]; - switch (display_type) { - case DISPLAY_WINDOW: - sprintf(pref, "win/%d/%d", dis_width, dis_height); - break; - case DISPLAY_SCREEN: - sprintf(pref, "dga/%d/%d", dis_width, dis_height); - break; - default: - PrefsRemoveItem("screen"); - return; - } - PrefsReplaceString("screen", pref); -} - -// Create "Graphics/Sound" pane -static void create_graphics_pane(GtkWidget *top) -{ - GtkWidget *box, *table, *label, *opt, *menu, *combo; - char str[32]; - - parse_graphics_prefs(); - - box = make_pane(top, STR_GRAPHICS_SOUND_PANE_TITLE); - table = make_table(box, 2, 5); - - label = gtk_label_new(GetString(STR_VIDEO_TYPE_CTRL)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - opt = gtk_option_menu_new(); - gtk_widget_show(opt); - menu = gtk_menu_new(); - add_menu_item(menu, STR_WINDOW_LAB, GTK_SIGNAL_FUNC(mn_window)); - add_menu_item(menu, STR_FULLSCREEN_LAB, GTK_SIGNAL_FUNC(mn_fullscreen)); - switch (display_type) { - case DISPLAY_WINDOW: - gtk_menu_set_active(GTK_MENU(menu), 0); - break; - case DISPLAY_SCREEN: - gtk_menu_set_active(GTK_MENU(menu), 1); - break; - } - gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu); - gtk_table_attach(GTK_TABLE(table), opt, 1, 2, 0, 1, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4); - - l_frameskip = gtk_label_new(GetString(STR_FRAMESKIP_CTRL)); - gtk_widget_show(l_frameskip); - gtk_table_attach(GTK_TABLE(table), l_frameskip, 0, 1, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - w_frameskip = gtk_option_menu_new(); - gtk_widget_show(w_frameskip); - menu = gtk_menu_new(); - add_menu_item(menu, STR_REF_5HZ_LAB, GTK_SIGNAL_FUNC(mn_5hz)); - add_menu_item(menu, STR_REF_7_5HZ_LAB, GTK_SIGNAL_FUNC(mn_7hz)); - add_menu_item(menu, STR_REF_10HZ_LAB, GTK_SIGNAL_FUNC(mn_10hz)); - add_menu_item(menu, STR_REF_15HZ_LAB, GTK_SIGNAL_FUNC(mn_15hz)); - add_menu_item(menu, STR_REF_30HZ_LAB, GTK_SIGNAL_FUNC(mn_30hz)); - add_menu_item(menu, STR_REF_60HZ_LAB, GTK_SIGNAL_FUNC(mn_60hz)); - add_menu_item(menu, STR_REF_DYNAMIC_LAB, GTK_SIGNAL_FUNC(mn_dynamic)); - int frameskip = PrefsFindInt32("frameskip"); - int item = -1; - switch (frameskip) { - case 12: item = 0; break; - case 8: item = 1; break; - case 6: item = 2; break; - case 4: item = 3; break; - case 2: item = 4; break; - case 1: item = 5; break; - case 0: item = 6; break; - } - if (item >= 0) - gtk_menu_set_active(GTK_MENU(menu), item); - gtk_option_menu_set_menu(GTK_OPTION_MENU(w_frameskip), menu); - gtk_table_attach(GTK_TABLE(table), w_frameskip, 1, 2, 1, 2, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4); - - l_display_x = gtk_label_new(GetString(STR_DISPLAY_X_CTRL)); - gtk_widget_show(l_display_x); - gtk_table_attach(GTK_TABLE(table), l_display_x, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - combo = gtk_combo_new(); - gtk_widget_show(combo); - GList *glist1 = NULL; - glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_512_LAB)); - glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_640_LAB)); - glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_800_LAB)); - glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_1024_LAB)); - glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_MAX_LAB)); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist1); - if (dis_width) - sprintf(str, "%d", dis_width); - else - strcpy(str, GetString(STR_SIZE_MAX_LAB)); - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str); - gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 2, 3, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4); - w_display_x = GTK_COMBO(combo)->entry; - - l_display_y = gtk_label_new(GetString(STR_DISPLAY_Y_CTRL)); - gtk_widget_show(l_display_y); - gtk_table_attach(GTK_TABLE(table), l_display_y, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - combo = gtk_combo_new(); - gtk_widget_show(combo); - GList *glist2 = NULL; - glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_384_LAB)); - glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_480_LAB)); - glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_600_LAB)); - glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_768_LAB)); - glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_MAX_LAB)); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist2); - if (dis_height) - sprintf(str, "%d", dis_height); - else - strcpy(str, GetString(STR_SIZE_MAX_LAB)); - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str); - gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4); - w_display_y = GTK_COMBO(combo)->entry; - -#ifdef SHEEPSHAVER - make_checkbox(box, STR_GFXACCEL_CTRL, "gfxaccel", GTK_SIGNAL_FUNC(tb_gfxaccel)); -#endif - - make_separator(box); - make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound)); - - set_graphics_sensitive(); - - hide_show_graphics_widgets(); -} - - -/* - * "Input" pane - */ - -static GtkWidget *w_keycode_file; -static GtkWidget *w_mouse_wheel_lines; - -// Set sensitivity of widgets -static void set_input_sensitive(void) -{ - const bool use_keycodes = PrefsFindBool("keycodes"); - gtk_widget_set_sensitive(w_keycode_file, use_keycodes); - gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_keycode_file), "chooser_button")), use_keycodes); - gtk_widget_set_sensitive(w_mouse_wheel_lines, PrefsFindInt32("mousewheelmode") == 1); -} - -// "Use Raw Keycodes" button toggled -static void tb_keycodes(GtkWidget *widget) -{ - PrefsReplaceBool("keycodes", GTK_TOGGLE_BUTTON(widget)->active); - set_input_sensitive(); -} - -// "Mouse Wheel Mode" selected -static void mn_wheel_page(...) {PrefsReplaceInt32("mousewheelmode", 0); set_input_sensitive();} -static void mn_wheel_cursor(...) {PrefsReplaceInt32("mousewheelmode", 1); set_input_sensitive();} - -// Read settings from widgets and set preferences -static void read_input_settings(void) -{ - const char *str = get_file_entry_path(w_keycode_file); - if (str && strlen(str)) - PrefsReplaceString("keycodefile", str); - else - PrefsRemoveItem("keycodefile"); - - PrefsReplaceInt32("mousewheellines", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w_mouse_wheel_lines))); -} - -// Create "Input" pane -static void create_input_pane(GtkWidget *top) -{ - GtkWidget *box, *hbox, *menu, *label, *button; - GtkObject *adj; - - box = make_pane(top, STR_INPUT_PANE_TITLE); - - make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes)); - - hbox = gtk_hbox_new(FALSE, 4); - gtk_widget_show(hbox); - gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0); - - label = gtk_label_new(GetString(STR_KEYCODES_CTRL)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - const char *str = PrefsFindString("keycodefile"); - if (str == NULL) - str = ""; - - w_keycode_file = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str); - gtk_widget_show(w_keycode_file); - gtk_box_pack_start(GTK_BOX(hbox), w_keycode_file, TRUE, TRUE, 0); - - button = make_browse_button(w_keycode_file); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - g_object_set_data(G_OBJECT(w_keycode_file), "chooser_button", button); - - make_separator(box); - - static const opt_desc options[] = { - {STR_MOUSEWHEELMODE_PAGE_LAB, GTK_SIGNAL_FUNC(mn_wheel_page)}, - {STR_MOUSEWHEELMODE_CURSOR_LAB, GTK_SIGNAL_FUNC(mn_wheel_cursor)}, - {0, NULL} - }; - int wheelmode = PrefsFindInt32("mousewheelmode"), active = 0; - switch (wheelmode) { - case 0: active = 0; break; - case 1: active = 1; break; - } - menu = make_option_menu(box, STR_MOUSEWHEELMODE_CTRL, options, active); - - hbox = gtk_hbox_new(FALSE, 4); - gtk_widget_show(hbox); - gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0); - - label = gtk_label_new(GetString(STR_MOUSEWHEELLINES_CTRL)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - adj = gtk_adjustment_new(PrefsFindInt32("mousewheellines"), 1, 1000, 1, 5, 0); - w_mouse_wheel_lines = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 0.0, 0); - gtk_widget_show(w_mouse_wheel_lines); - gtk_box_pack_start(GTK_BOX(hbox), w_mouse_wheel_lines, FALSE, FALSE, 0); - - set_input_sensitive(); -} - - -/* - * "Serial" pane - */ - -static GtkWidget *w_seriala, *w_portfile0; -static GtkWidget *w_serialb, *w_portfile1; - -// Set sensitivity of widgets -static void set_serial_sensitive(void) -{ - const char *str; - bool is_file; - - str = gtk_entry_get_text(GTK_ENTRY(w_seriala)); - is_file = strcmp(str, "FILE") == 0; - gtk_widget_set_sensitive(w_portfile0, is_file); - gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_portfile0), "chooser_button")), is_file); - - str = gtk_entry_get_text(GTK_ENTRY(w_serialb)); - is_file = strcmp(str, "FILE") == 0; - gtk_widget_set_sensitive(w_portfile1, is_file); - gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_portfile1), "chooser_button")), is_file); -} - -// Read settings from widgets and set preferences -static void read_serial_settings(void) -{ - const char *str; - - str = gtk_entry_get_text(GTK_ENTRY(w_seriala)); - PrefsReplaceString("seriala", str); - - str = gtk_entry_get_text(GTK_ENTRY(w_serialb)); - PrefsReplaceString("serialb", str); - - str = gtk_entry_get_text(GTK_ENTRY(w_portfile0)); - PrefsReplaceString("portfile0", str); - - str = gtk_entry_get_text(GTK_ENTRY(w_portfile1)); - PrefsReplaceString("portfile1", str); -} - -// Port changed in combo -static void cb_serial_port_changed(...) -{ - set_serial_sensitive(); -} - -// Add names of serial devices -static GList *add_serial_names(void) -{ - GList *glist = NULL; - - static const char *port_names[] = { - "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", - "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", - "FILE", - NULL - }; - - for (int i = 0; port_names[i] != NULL; i++) - glist = g_list_append(glist, (void *)port_names[i]); - - return glist; -} - -// Create "Serial" pane -static void create_serial_pane(GtkWidget *top) -{ - GtkWidget *box, *hbox, *table, *label, *combo, *sep, *entry; - GtkObject *adj; - - box = make_pane(top, STR_SERIAL_PANE_TITLE); - table = make_table(box, 2, 5); - - GList *glist = add_serial_names(); - const char *str = PrefsFindString("seriala"); - combo = table_make_combobox(table, 0, STR_SERIALA_CTRL, str, glist); - w_seriala = GTK_COMBO(combo)->entry; - gtk_signal_connect(GTK_OBJECT(w_seriala), "changed", GTK_SIGNAL_FUNC(cb_serial_port_changed), NULL); - - w_portfile0 = table_make_file_entry(table, 1, STR_FILE_CTRL, "portfile0"); - - sep = gtk_hseparator_new(); - gtk_widget_show(sep); - gtk_table_attach(GTK_TABLE(table), sep, 0, 2, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - str = PrefsFindString("serialb"); - combo = table_make_combobox(table, 3, STR_SERIALB_CTRL, str, glist); - w_serialb = GTK_COMBO(combo)->entry; - gtk_signal_connect(GTK_OBJECT(w_serialb), "changed", GTK_SIGNAL_FUNC(cb_serial_port_changed), NULL); - - w_portfile1 = table_make_file_entry(table, 4, STR_FILE_CTRL, "portfile1"); - - set_serial_sensitive(); -} - - -/* - * "Ethernet" pane - */ - -static GtkWidget *w_ftp_port_list, *w_tcp_port_list; - -// Set sensitivity of widgets -static void set_ethernet_sensitive(void) -{ - const char *str = PrefsFindString("ether"); - - bool is_router = str && strcmp(str, "router") == 0; - gtk_widget_set_sensitive(w_ftp_port_list, is_router); - gtk_widget_set_sensitive(w_tcp_port_list, is_router); -} - -// Read settings from widgets and set preferences -static void read_ethernet_settings(void) -{ - const char *str = PrefsFindString("ether"); - - bool is_router = str && strcmp(str, "router") == 0; - if (is_router) { - str = gtk_entry_get_text(GTK_ENTRY(w_ftp_port_list)); - PrefsReplaceString("ftp_port_list", str); - str = gtk_entry_get_text(GTK_ENTRY(w_tcp_port_list)); - PrefsReplaceString("tcp_port", str); - } -} - -// Ethernet emulation type changed in menulist -static void cb_ether_changed(...) -{ - set_ethernet_sensitive(); -} - -// Ethernet option "None" selected -static void mn_ether_none(void) -{ - PrefsRemoveItem("ether"); - PrefsRemoveItem("etherguid"); -} - -// Ethernet option "Basilisk II Router" selected -static void mn_ether_router(void) -{ - PrefsReplaceString("ether", "router"); - PrefsRemoveItem("etherguid"); -} - -// Ethernet option "Basilisk II Slirp" selected -static void mn_ether_slirp(void) -{ - PrefsReplaceString("ether", "slirp"); - PrefsRemoveItem("etherguid"); -} - -// Ethernet option for Basilisk II driver selected -static void mn_ether_b2ether(GtkWidget *, const char *guid) -{ - PrefsReplaceString("ether", "b2ether"); - PrefsReplaceString("etherguid", guid); -} - -// Ethernet option for Basilisk II driver selected -static void mn_ether_tap(GtkWidget *, const char *guid) -{ - PrefsReplaceString("ether", "tap"); - PrefsReplaceString("etherguid", guid); -} - -// Create ethernet interfaces menu -static int create_ether_menu(GtkWidget *menu) -{ - int active = -1; - int n_items = 0; - const char *ether = PrefsFindString("ether"); - const char *etherguid = PrefsFindString("etherguid"); - - // No Ethernet - add_menu_item(menu, STR_NONE_LAB, (GtkSignalFunc)mn_ether_none); - if (ether == NULL) - active = n_items; - n_items++; - - // Basilisk II Router - add_menu_item(menu, "Basilisk II Router", (GtkSignalFunc)mn_ether_router); - if (ether && strcmp(ether, "router") == 0) - active = n_items; - n_items++; - - // Basilisk II Slirp - add_menu_item(menu, "Basilisk II Slirp", (GtkSignalFunc)mn_ether_slirp); - if (ether && strcmp(ether, "slirp") == 0) - active = n_items; - n_items++; - - // Basilisk II Ethernet Adapter - PacketOpenAdapter("", 0); - { - ULONG sz; - char names[1024]; - sz = sizeof(names); - if (PacketGetAdapterNames(NULL, names, &sz) == ERROR_SUCCESS) { - char *p = names; - while (*p) { - const char DEVICE_HEADER[] = "\\Device\\B2ether_"; - if (strnicmp(p, DEVICE_HEADER, sizeof(DEVICE_HEADER) - 1) == 0) { - LPADAPTER fd = PacketOpenAdapter(p + sizeof(DEVICE_HEADER) - 1, 0); - if (fd) { - char guid[256]; - sprintf(guid, "%s", p + sizeof(DEVICE_HEADER) - 1); - const char *name = ether_guid_to_name(guid); - if (name && (name = g_locale_to_utf8(name, -1, NULL, NULL, NULL))) { - add_menu_item(menu, name, (GtkSignalFunc)mn_ether_b2ether, strdup(guid)); - if (etherguid && strcmp(guid, etherguid) == 0 && - ether && strcmp(ether, "b2ether") == 0) - active = n_items; - n_items++; - } - PacketCloseAdapter(fd); - } - } - p += strlen(p) + 1; - } - } - } - PacketCloseAdapter(NULL); - - // TAP-Win32 - const char *tap_devices; - if ((tap_devices = ether_tap_devices()) != NULL) { - const char *guid = tap_devices; - while (*guid) { - const char *name = ether_guid_to_name(guid); - if (name && (name = g_locale_to_utf8(name, -1, NULL, NULL, NULL))) { - add_menu_item(menu, name, (GtkSignalFunc)mn_ether_tap, strdup(guid)); - if (etherguid && strcmp(guid, etherguid) == 0 && - ether && strcmp(ether, "tap") == 0) - active = n_items; - n_items++; - } - guid += strlen(guid) + 1; - } - free((char *)tap_devices); - } - - return active; -} - -// Create "Ethernet" pane -static void create_ethernet_pane(GtkWidget *top) -{ - GtkWidget *box, *hbox, *table, *label, *sep, *entry, *opt, *menu, *item; - - box = make_pane(top, STR_NETWORK_PANE_TITLE); - table = make_table(box, 2, 5); - - label = gtk_label_new(GetString(STR_ETHERNET_IF_CTRL)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - opt = gtk_option_menu_new(); - gtk_widget_show(opt); - menu = gtk_menu_new(); - int active = create_ether_menu(menu); - if (active >= 0) - gtk_menu_set_active(GTK_MENU(menu), active); - gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu); - gtk_table_attach(GTK_TABLE(table), opt, 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - gtk_signal_connect(GTK_OBJECT(opt), "changed", GTK_SIGNAL_FUNC(cb_ether_changed), NULL); - - sep = gtk_hseparator_new(); - gtk_widget_show(sep); - gtk_table_attach(GTK_TABLE(table), sep, 0, 2, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - label = gtk_label_new(GetString(STR_ETHER_FTP_PORT_LIST_CTRL)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - entry = gtk_entry_new(); - const char *str = PrefsFindString("ftp_port_list"); - if (str == NULL) - str = ""; - gtk_entry_set_text(GTK_ENTRY(entry), str); - gtk_widget_show(entry); - gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 2, 3, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - w_ftp_port_list = entry; - - label = gtk_label_new(GetString(STR_ETHER_TCP_PORT_LIST_CTRL)); - gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - entry = gtk_entry_new(); - str = PrefsFindString("tcp_port"); - if (str == NULL) - str = ""; - gtk_entry_set_text(GTK_ENTRY(entry), str); - gtk_widget_show(entry); - gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 3, 4, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); - w_tcp_port_list = entry; - - set_ethernet_sensitive(); -} - - -/* - * "Memory/Misc" pane - */ - -static GtkWidget *w_ramsize; -static GtkWidget *w_rom_file; - -// Don't use CPU when idle? -static void tb_idlewait(GtkWidget *widget) -{ - PrefsReplaceBool("idlewait", GTK_TOGGLE_BUTTON(widget)->active); -} - -// "Ignore SEGV" button toggled -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION -static void tb_ignoresegv(GtkWidget *widget) -{ - PrefsReplaceBool("ignoresegv", GTK_TOGGLE_BUTTON(widget)->active); -} -#endif - -// Model ID selected -static void mn_modelid_5(...) {PrefsReplaceInt32("modelid", 5);} -static void mn_modelid_14(...) {PrefsReplaceInt32("modelid", 14);} - -// CPU/FPU type -static void mn_cpu_68020(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", false);} -static void mn_cpu_68020_fpu(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", true);} -static void mn_cpu_68030(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", false);} -static void mn_cpu_68030_fpu(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", true);} -static void mn_cpu_68040(...) {PrefsReplaceInt32("cpu", 4); PrefsReplaceBool("fpu", true);} - -// Read settings from widgets and set preferences -static void read_memory_settings(void) -{ - const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_ramsize)->entry)); - PrefsReplaceInt32("ramsize", atoi(str) << 20); - - str = get_file_entry_path(w_rom_file); - if (str && strlen(str)) - PrefsReplaceString("rom", str); - else - PrefsRemoveItem("rom"); - -} - -// Create "Memory/Misc" pane -static void create_memory_pane(GtkWidget *top) -{ - GtkWidget *box, *hbox, *table, *label, *scale, *menu; - - box = make_pane(top, STR_MEMORY_MISC_PANE_TITLE); - table = make_table(box, 2, 5); - - static const combo_desc options[] = { -#ifndef SHEEPSHAVER - STR_RAMSIZE_2MB_LAB, -#endif - STR_RAMSIZE_4MB_LAB, - STR_RAMSIZE_8MB_LAB, - STR_RAMSIZE_16MB_LAB, - STR_RAMSIZE_32MB_LAB, - STR_RAMSIZE_64MB_LAB, - STR_RAMSIZE_128MB_LAB, - STR_RAMSIZE_256MB_LAB, - STR_RAMSIZE_512MB_LAB, - STR_RAMSIZE_1024MB_LAB, - 0 - }; - char default_ramsize[16]; - sprintf(default_ramsize, "%d", PrefsFindInt32("ramsize") >> 20); - w_ramsize = table_make_combobox(table, 0, STR_RAMSIZE_CTRL, default_ramsize, options); - -#ifndef SHEEPSHAVER - static const opt_desc model_options[] = { - {STR_MODELID_5_LAB, GTK_SIGNAL_FUNC(mn_modelid_5)}, - {STR_MODELID_14_LAB, GTK_SIGNAL_FUNC(mn_modelid_14)}, - {0, NULL} - }; - int modelid = PrefsFindInt32("modelid"), active = 0; - switch (modelid) { - case 5: active = 0; break; - case 14: active = 1; break; - } - table_make_option_menu(table, 2, STR_MODELID_CTRL, model_options, active); -#endif - -#if EMULATED_68K - static const opt_desc cpu_options[] = { - {STR_CPU_68020_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020)}, - {STR_CPU_68020_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020_fpu)}, - {STR_CPU_68030_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030)}, - {STR_CPU_68030_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030_fpu)}, - {STR_CPU_68040_LAB, GTK_SIGNAL_FUNC(mn_cpu_68040)}, - {0, NULL} - }; - int cpu = PrefsFindInt32("cpu"); - bool fpu = PrefsFindBool("fpu"); - active = 0; - switch (cpu) { - case 2: active = fpu ? 1 : 0; break; - case 3: active = fpu ? 3 : 2; break; - case 4: active = 4; - } - table_make_option_menu(table, 3, STR_CPU_CTRL, cpu_options, active); -#endif - - w_rom_file = table_make_file_entry(table, 4, STR_ROM_FILE_CTRL, "rom"); - - make_checkbox(box, STR_IDLEWAIT_CTRL, "idlewait", GTK_SIGNAL_FUNC(tb_idlewait)); - -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv)); -#endif -} - - -/* - * Read settings from widgets and set preferences - */ - -static void read_settings(void) -{ - read_volumes_settings(); - read_scsi_settings(); - read_graphics_settings(); - read_input_settings(); - read_serial_settings(); - read_ethernet_settings(); - read_memory_settings(); - read_jit_settings(); -} - - -/* - * Fake unused data and functions - */ - -uint8 XPRAM[XPRAM_SIZE]; -void MountVolume(void *fh) { } -void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { } -void recycle_write_packet(LPPACKET) { } -VOID CALLBACK packet_read_completion(DWORD, DWORD, LPOVERLAPPED) { } - - -/* - * Add default serial prefs (must be added, even if no ports present) - */ - -void SysAddSerialPrefs(void) -{ - PrefsAddString("seriala", "COM1"); - PrefsAddString("serialb", "COM2"); -} - - -/* - * Display alerts - */ - -static void display_alert(int title_id, const char *text, int flags) -{ - MessageBox(NULL, text, GetString(title_id), MB_OK | flags); -} - -void ErrorAlert(const char *text) -{ - display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP); -} - -void WarningAlert(const char *text) -{ - display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONSTOP); -} - - -/* - * Start standalone GUI - */ - -int main(int argc, char *argv[]) -{ - // Init GTK - gtk_set_locale(); - gtk_init(&argc, &argv); - - // Read preferences - PrefsInit(NULL, argc, argv); - - // Migrate preferences - PrefsMigrate(); - - // Show preferences editor - bool start = PrefsEditor(); - - // Exit preferences - PrefsExit(); - - // Transfer control to the executable - if (start) { - char path[_MAX_PATH]; - bool ok = GetModuleFileName(NULL, path, sizeof(path)) != 0; - if (ok) { - char b2_path[_MAX_PATH]; - char *p = strrchr(path, '\\'); - *++p = '\0'; - SetCurrentDirectory(path); - strcpy(b2_path, path); - strcat(b2_path, PROGRAM_NAME); - strcat(b2_path, ".exe"); - HINSTANCE h = ShellExecute(GetDesktopWindow(), "open", - b2_path, "", path, SW_SHOWNORMAL); - if ((int)h <= 32) - ok = false; - } - if (!ok) { - ErrorAlert("Coult not start " PROGRAM_NAME " executable"); - return 1; - } - } - - return 0; -} diff --git a/BasiliskII/src/Windows/prefs_windows.cpp b/BasiliskII/src/Windows/prefs_windows.cpp deleted file mode 100755 index ed837b86..00000000 --- a/BasiliskII/src/Windows/prefs_windows.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * prefs_windows.cpp - Preferences handling, Windows specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include - -#include -typedef std::basic_string tstring; - -#include "prefs.h" - - -// Platform-specific preferences items -prefs_desc platform_prefs_items[] = { - {"keycodes", TYPE_BOOLEAN, false, "use keycodes rather than keysyms to decode keyboard"}, - {"keycodefile", TYPE_STRING, false, "path of keycode translation file"}, - {"mousewheelmode", TYPE_INT32, false, "mouse wheel support mode (0=page up/down, 1=cursor up/down)"}, - {"mousewheellines", TYPE_INT32, false, "number of lines to scroll in mouse wheel mode 1"}, -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - {"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"}, -#endif - {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, - {"enableextfs", TYPE_BOOLEAN, false, "enable extfs system"}, - {"debugextfs", TYPE_BOOLEAN, false, "debug extfs system"}, - {"extdrives", TYPE_STRING, false, "define allowed extfs drives"}, - {"pollmedia", TYPE_BOOLEAN, false, "poll for new media (e.g. cd, floppy)"}, - {"etherguid", TYPE_STRING, false, "GUID of the ethernet device to use"}, - {"etherpermanentaddress", TYPE_BOOLEAN, false, "use permanent NIC address to identify itself"}, - {"ethermulticastmode", TYPE_INT32, false, "how to multicast packets"}, - {"etherfakeaddress", TYPE_STRING, false, "optional fake hardware address"}, - {"routerenabled", TYPE_BOOLEAN, false, "enable NAT/Router module"}, - {"ftp_port_list", TYPE_STRING, false, "FTP ports list"}, - {"tcp_port", TYPE_STRING, false, "TCP ports list"}, - {"portfile0", TYPE_STRING, false, "output file for serial port 0"}, - {"portfile1", TYPE_STRING, false, "output file for serial port 1"}, - - {NULL, TYPE_END, false, NULL} // End of list -}; - - -// Prefs file name and path -const TCHAR PREFS_FILE_NAME[] = TEXT("BasiliskII_prefs"); -tstring UserPrefsPath; -static tstring prefs_path; - - -/* - * Load preferences from settings file - */ - -void LoadPrefs(const char *vmdir) -{ - // Construct prefs path - if (UserPrefsPath.empty()) { - int pwd_len = GetCurrentDirectory(0, NULL); - prefs_path.resize(pwd_len); - pwd_len = GetCurrentDirectory(pwd_len, &prefs_path.front()); - prefs_path[pwd_len] = TEXT('\\'); - prefs_path += PREFS_FILE_NAME; - } else - prefs_path = UserPrefsPath; - - // Read preferences from settings file - FILE *f = _tfopen(prefs_path.c_str(), TEXT("r")); - if (f != NULL) { - - // Prefs file found, load settings - LoadPrefsFromStream(f); - fclose(f); - - } else { - - // No prefs file, save defaults - SavePrefs(); - } -} - - -/* - * Save preferences to settings file - */ - -void SavePrefs(void) -{ - FILE *f; - if ((f = _tfopen(prefs_path.c_str(), TEXT("w"))) != NULL) { - SavePrefsToStream(f); - fclose(f); - } -} - - -/* - * Add defaults of platform-specific prefs items - * You may also override the defaults set in PrefsInit() - */ - -void AddPlatformPrefsDefaults(void) -{ - PrefsAddBool("keycodes", false); - PrefsReplaceBool("pollmedia", true); - PrefsReplaceBool("enableextfs", false); - PrefsReplaceString("extfs", ""); - PrefsReplaceString("extdrives", "CDEFGHIJKLMNOPQRSTUVWXYZ"); - PrefsReplaceInt32("mousewheelmode", 1); - PrefsReplaceInt32("mousewheellines", 3); -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - PrefsAddBool("ignoresegv", false); -#endif - PrefsAddBool("idlewait", true); - PrefsReplaceBool("etherpermanentaddress", true); - PrefsReplaceInt32("ethermulticastmode", 0); - PrefsReplaceString("ftp_port_list", "21"); - PrefsReplaceString("seriala", "COM1"); - PrefsReplaceString("serialb", "COM2"); - PrefsReplaceString("portfile0", "C:\\B2TEMP0.OUT"); - PrefsReplaceString("portfile1", "C:\\B2TEMP1.OUT"); -} diff --git a/BasiliskII/src/Windows/router/arp.cpp b/BasiliskII/src/Windows/router/arp.cpp deleted file mode 100755 index 69a11879..00000000 --- a/BasiliskII/src/Windows/router/arp.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * arp.cpp - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "main.h" -#include "cpu_emulation.h" -#include "prefs.h" -#include "ether_windows.h" -#include "ether.h" -#include "router.h" -#include "router_types.h" -#include "iphelp.h" -#include "arp.h" -#include "icmp.h" -#include "dump.h" - - -#if DEBUG -#pragma optimize("",off) -#endif - -#include "debug.h" - - -// ARP queries can be replied immediately. - -bool write_arp( arp_t *req, int len ) -{ - D(bug("write_arp() len=%d, htype=%d, ptype=%04x, opcode=%d, halen=%d, palen=%d\r\n",len, ntohs(req->htype), ntohs(req->ptype), ntohs(req->opcode), req->halen, req->palen)); - - start_icmp_listen(); - - bool result = false; - - if( len >= sizeof(arp_t) && - req->htype == htons(arp_hwtype_enet) && - req->ptype == htons(mac_type_ip4) && - req->opcode == htons(arp_request) && - req->halen == 6 && - req->palen == 4 - ) - { - if(memcmp( req->srcp, req->dstp, 4 ) == 0) { - // No reply. MacOS is making sure that there are no duplicate ip addresses. - // Update localhost (==Mac) ip address (needed by incoming icmp) - macos_ip_address = ntohl( *((uint32 *)&req->srcp[0]) ); - D(bug("Mac ip: %02x %02x %02x %02x\r\n", req->srcp[0], req->srcp[1], req->srcp[2], req->srcp[3])); - } else { - arp_t arp; - - D(bug("Source NIC: %02x %02x %02x %02x\r\n", req->srcp[0], req->srcp[1], req->srcp[2], req->srcp[3])); - D(bug("Dest NIC: %02x %02x %02x %02x\r\n", req->dstp[0], req->dstp[1], req->dstp[2], req->dstp[3])); - - // memcpy( arp.mac.dest, req->mac.src, 6 ); - memcpy( arp.mac.dest, ether_addr, 6 ); - memcpy( arp.mac.src, router_mac_addr, 6 ); - arp.mac.type = htons(mac_type_arp); - arp.htype = htons(arp_hwtype_enet); - arp.ptype = htons(mac_type_ip4); - arp.halen = 6; - arp.palen = 4; - arp.opcode = htons(arp_reply); - memcpy( arp.srch, router_mac_addr, 6 ); - memcpy( arp.srcp, req->dstp, 4 ); - // memcpy( arp.dsth, req->srch, 6 ); - memcpy( arp.dsth, ether_addr, 6 ); - memcpy( arp.dstp, req->srcp, 4 ); - - // Update here, too, just in case. - macos_ip_address = ntohl( *((uint32 *)&req->srcp[0]) ); - - enqueue_packet( (uint8 *)&arp, sizeof(arp) ); - } - result = true; - } - return result; -} diff --git a/BasiliskII/src/Windows/router/arp.h b/BasiliskII/src/Windows/router/arp.h deleted file mode 100755 index c44443d9..00000000 --- a/BasiliskII/src/Windows/router/arp.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * arp.h - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _ARP_H_ -#define _ARP_H_ - -bool write_arp( arp_t *req, int len ); - -#endif // _ARP_H_ diff --git a/BasiliskII/src/Windows/router/dump.cpp b/BasiliskII/src/Windows/router/dump.cpp deleted file mode 100755 index 4d3fe731..00000000 --- a/BasiliskII/src/Windows/router/dump.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * dump.cpp - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "main.h" -#include "dump.h" - -#if DEBUG -#pragma optimize("",off) -#endif - -#include "debug.h" - - -void dump_bytes( uint8 *packet, int length ) -{ -#if DEBUG - char buf[1000], sm[10]; - - *buf = 0; - - if(length > 256) length = 256; - - for (int i=0; i -#include "dump.h" -#include "prefs.h" -#include "ftp.h" - -#if DEBUG -#pragma optimize("",off) -#endif - -#include "debug.h" - -static int m_ftp_port_count = 0; -#define MAX_FTP_PORTS 100 -static uint16 m_ftp_ports[MAX_FTP_PORTS]; - -bool ftp_is_ftp_port( uint16 port ) -{ - for( int i=0; i> 24, - (ip >> 16) & 0xFF, - (ip >> 8) & 0xFF, - ip & 0xFF, - (port >> 8) & 0xFF, - port & 0xFF, - 0x0d, 0x0a - ); - - count = strlen(buf); - - D(bug("ftp_modify_port_command: \"%s\"\r\n", buf )); -} - -// this should be robust. rather skip it than do anything dangerous. -void ftp_parse_port_command( - char *buf, - uint32 count, - uint16 &ftp_data_port, - bool is_pasv -) -{ - ftp_data_port = 0; - - if( !count ) return; - - uint8 b[100]; - uint32 ftp_ip = 0; - - // make it a c-string - if( count >= sizeof(b) ) count = sizeof(b)-1; - memcpy( b, buf, count ); - b[ count ] = 0; - - for( uint32 i=0; i 'z' ) { - b[i] = ' '; - } else { - b[i] = tolower(b[i]); - } - } - - // D(bug("FTP: \"%s\"\r\n", b )); - - char *s = (char *)b; - - while( *s == ' ' ) s++; - - if(is_pasv) { - /* - LOCAL SERVER: ..227 Entering Passive Mode (192,168,0,2,6,236). 0d 0a - */ - if( atoi(s) == 227 && strstr(s,"passive") ) { - while( *s && *s != '(' ) s++; - if( *s++ == 0 ) s = 0; - } else { - s = 0; - } - } else { - /* - LOCAL CLIENT: PORT 192,168,0,1,14,147 0d 0a - */ - if( strncmp(s,"port ",5) == 0 ) { - s += 5; - } else { - s = 0; - } - } - - if(s && *s) { - // get remote ip (used only for verification) - for( uint32 i=0; i<4; i++ ) { - while( *s == ' ' ) s++; - if(!isdigit(*s)) { - ftp_ip = 0; - break; - } - ftp_ip = (ftp_ip << 8) + atoi(s); - while( *s && *s != ',' ) s++; - if(!*s) { - ftp_ip = 0; - break; - } - s++; - } - - if(ftp_ip) { - // get local port - for( uint32 i=0; i<2; i++ ) { - while( *s == ' ' ) s++; - if(!isdigit(*s)) { - ftp_data_port = 0; - break; - } - ftp_data_port = (ftp_data_port << 8) + atoi(s); - while( *s && *s != ',' && *s != ')' ) s++; - if(!*s) - break; - else - s++; - } - } - } - if(ftp_data_port) { - D(bug("ftp_parse_port_command: \"%s\"; port is %d\r\n", b, ftp_data_port )); - } -} diff --git a/BasiliskII/src/Windows/router/ftp.h b/BasiliskII/src/Windows/router/ftp.h deleted file mode 100755 index 5dc6dfda..00000000 --- a/BasiliskII/src/Windows/router/ftp.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * ftp.h - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _FTP_H_ -#define _FTP_H_ - -// Read the preferences. -void init_ftp(); - -// Compares against a list provided by the user. -bool ftp_is_ftp_port( uint16 port ); - -// Determine whether this is a ftp client PORT command or ftp server entering to passive mode. -void ftp_parse_port_command( - char *buf, - uint32 count, - uint16 &ftp_data_port, - bool is_pasv -); - -// Build a new command using ip and port. -void ftp_modify_port_command( - char *buf, - int &count, - const uint32 max_size, - const uint32 ip, - const uint16 port, - const bool is_pasv -); - -#endif // _FTP_H_ diff --git a/BasiliskII/src/Windows/router/icmp.cpp b/BasiliskII/src/Windows/router/icmp.cpp deleted file mode 100755 index d6cb0e0e..00000000 --- a/BasiliskII/src/Windows/router/icmp.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - * icmp.cpp - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "main.h" -#include "cpu_emulation.h" -#include "ws2tcpip.h" -#include "prefs.h" -#include "ether_windows.h" -#include "ether.h" -#include "router.h" -#include "router_types.h" -#include "dynsockets.h" -#include "ipsocket.h" -#include "iphelp.h" -#include "icmp.h" -#include "dump.h" - - -#if DEBUG -#pragma optimize("",off) -#endif - -#include "debug.h" - - -// Saved for cleanup. -static socket_t *icmp_incoming_s = 0; - - -void stop_icmp_listen() -{ - if(icmp_incoming_s) { - delete icmp_incoming_s; - icmp_incoming_s = 0; - } -} - -void start_icmp_listen() -{ - if(!icmp_incoming_s) { - icmp_incoming_s = new socket_t(IPPROTO_ICMP); - - icmp_incoming_s->permanent = TRUE; - icmp_incoming_s->s = _socket( AF_INET, SOCK_RAW, IPPROTO_ICMP ); - - memset( &icmp_incoming_s->from, 0, icmp_incoming_s->from_len ); - icmp_incoming_s->from.sin_family = AF_INET; - - if(icmp_incoming_s->s == INVALID_SOCKET) { - D(bug("Failed to create icmp listening socket (NT/no admin?)\r\n" )); - delete icmp_incoming_s; - icmp_incoming_s = 0; - } else { - D(bug("icmp listening socket created\r\n" )); - raw_sockets_available = true; - struct sockaddr_in to; - memset( &to, 0, sizeof(to) ); - to.sin_family = AF_INET; - if( _bind ( icmp_incoming_s->s, (const struct sockaddr *)&to, sizeof(to) ) == SOCKET_ERROR ) { - D(bug("Listening to inbound icmp failed, error code = %d\r\n", _WSAGetLastError() )); - _closesocket( icmp_incoming_s->s ); - delete icmp_incoming_s; - icmp_incoming_s = 0; - } else { - D(bug("icmp listening socket bound\r\n" )); - if(!icmp_incoming_s->b_recfrom()) { - D(bug("b_recfrom() from inbound icmp failed, error code = %d\r\n", _WSAGetLastError() )); - // _closesocket( icmp_incoming_s->s ); - // delete icmp_incoming_s; - // icmp_incoming_s = 0; - } - } - } - } -} - -void CALLBACK icmp_read_completion( - DWORD error, - DWORD bytes_read, - LPWSAOVERLAPPED lpOverlapped, - DWORD flags -) -{ - D(bug("icmp_read_completion(error=0x%x, bytes_read=%d, flags=0x%x)\r\n", error, bytes_read, flags)); - - socket_t *cmpl = (socket_t *)lpOverlapped->hEvent; - - if(error == 0 && macos_ip_address != 0) { - if(bytes_read > 1460) { - D(bug("discarding oversized icmp packet, size = \r\n", bytes_read)); - } else { - int icmp_size = sizeof(mac_t) + bytes_read; - icmp_t *icmp = (icmp_t *)malloc( icmp_size ); - if(icmp) { - mac_t *mac = (mac_t *)icmp; - ip_t *ip = (ip_t *)icmp; - - memcpy( mac->dest, ether_addr, 6 ); - memcpy( mac->src, router_mac_addr, 6 ); - mac->type = htons(mac_type_ip4); - - // Copy payload (used by ICMP checksum) - memcpy( (char *)icmp + sizeof(mac_t), cmpl->buffers[0].buf, bytes_read ); - - switch( icmp->type ) { - // May need to patch the returned ip header. - case icmp_Destination_unreachable: - case icmp_Source_quench: - case icmp_Redirect: - case icmp_Time_exceeded: - case icmp_Parameter_problem: - ip_t *ip_if = (ip_t *)( (char *)icmp + sizeof(icmp_t) + sizeof(uint32) - sizeof(mac_t) ); - - // This would be needed (traceroute) - // ip_if->ident = ??; - - // Cannot fix some fields, this should be enough: - ip_if->src = htonl(macos_ip_address); - - if(ip_if->proto == ip_proto_udp) { - udp_t *udp_if = (udp_t *)ip_if; - // udp_if->src_port = ... don't know!; - } else if(ip_if->proto == ip_proto_tcp) { - tcp_t *tcp_if = (tcp_t *)ip_if; - // tcp_if->src_port = ... don't know!; - } - break; - } - - make_icmp_checksum( icmp, icmp_size ); - - // Replace the target ip address - ip->dest = htonl(macos_ip_address); - ip->ttl--; - make_ip4_checksum( ip ); - - dump_bytes( (uint8 *)icmp, icmp_size ); - - if( ip->ttl == 0 ) { - D(bug("icmp packet ttl expired\r\n")); - } else { - enqueue_packet( (uint8 *)icmp, icmp_size ); - } - free(icmp); - } - } - } - - memset( &cmpl->from, 0, cmpl->from_len ); - - if(is_router_shutting_down) { - delete cmpl; - } else if(cmpl->s == INVALID_SOCKET || !cmpl->b_recfrom()) { - // delete cmpl; - } -} - -void write_icmp( icmp_t *icmp, int len ) -{ - struct in_addr ia; - ia.s_addr = icmp->ip.dest; - D(bug("write_icmp(%s)\r\n", _inet_ntoa(ia) )); - - if(!raw_sockets_available) { - D(bug("write_icmp() cannot proceed, raw sockets not available\r\n" )); - return; - } - - if(len < sizeof(icmp_t)) { - D(bug("Too small icmp packet(%d), dropped\r\n", len)); - return; - } - - // must be updated, ttl changed - make_icmp_checksum( icmp, len ); - - SOCKET s = _socket( AF_INET, SOCK_RAW, IPPROTO_ICMP ); - if(s != INVALID_SOCKET) { - struct sockaddr_in to; - memset( &to, 0, sizeof(to) ); - to.sin_family = AF_INET; - to.sin_addr.s_addr = icmp->ip.dest; - - char *data = (char *)icmp + sizeof(ip_t); - int dlen = len - sizeof(ip_t); - - int ttl = icmp->ip.ttl; - if(_setsockopt( s, IPPROTO_IP, IP_TTL, (const char *)&ttl, sizeof(int) ) == SOCKET_ERROR ) { - D(bug("could not set ttl to %d.\r\n", ttl)); - } else { - D(bug("ttl set to %d.\r\n", ttl)); - } - - if(SOCKET_ERROR == _sendto( s, data, dlen, 0, (struct sockaddr *)&to, sizeof(to) )) { - D(bug("Failed to send icmp via raw socket\r\n" )); - } - _closesocket(s); - } else { - D(bug("Could not create raw socket for icmp\r\n" )); - } -} diff --git a/BasiliskII/src/Windows/router/icmp.h b/BasiliskII/src/Windows/router/icmp.h deleted file mode 100755 index a3c30621..00000000 --- a/BasiliskII/src/Windows/router/icmp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * icmp.h - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _ICMP_H_ -#define _ICMP_H_ - -void start_icmp_listen(); -void stop_icmp_listen(); - -void write_icmp( icmp_t *icmp, int len ); - -void CALLBACK icmp_read_completion( - DWORD error, - DWORD bytes_read, - LPWSAOVERLAPPED lpOverlapped, - DWORD flags -); - -#endif // _ICMP_H_ diff --git a/BasiliskII/src/Windows/router/iphelp.cpp b/BasiliskII/src/Windows/router/iphelp.cpp deleted file mode 100755 index e77466e1..00000000 --- a/BasiliskII/src/Windows/router/iphelp.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - * iphelp.cpp - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "main.h" -#include "cpu_emulation.h" -#include "ether_windows.h" -#include "ether.h" -#include "router.h" -#include "router_types.h" -#include "tcp.h" -#include "icmp.h" -#include "udp.h" -#include "iphelp.h" -#include "dump.h" - - -#if DEBUG -#pragma optimize("",off) -#endif - -#include "debug.h" - - -void make_icmp_checksum( icmp_t *icmp, int len ) -{ - icmp->checksum = 0; - - uint16 sz = (len-sizeof(ip_t))/2; - uint16 *p = (uint16 *)( (uint8 *)icmp + sizeof(ip_t) ); - - uint32 sum32 = 0; - for( int i=0; ichecksum = htons((uint16)sum32); -} - -void make_tcp_checksum( tcp_t *tcp, int len ) -{ - tcp->checksum = 0; - - int tcp_len = len - sizeof(ip_t); - uint16 sz = tcp_len/2; - uint16 *p = (uint16 *)( (uint8 *)tcp + sizeof(ip_t) ); - - uint32 sum32 = 0; - for( int i=0; iip.src)); - pseudo.src_hi = HIWORD(ntohl(tcp->ip.src)); - pseudo.dest_lo = LOWORD(ntohl(tcp->ip.dest)); - pseudo.dest_hi = HIWORD(ntohl(tcp->ip.dest)); - pseudo.proto = (uint16)tcp->ip.proto; - pseudo.msg_len = tcp->header_len >> 2; - - int datalen = len - sizeof(tcp_t); - pseudo.msg_len += datalen; - - p = (uint16 *)&pseudo; - - for( int i=0; ichecksum = htons((uint16)sum32); -} - -void make_ip4_checksum( ip_t *ip ) -{ - ip->checksum = 0; - uint16 sz = ip->header_len * 2; - uint16 *p = (uint16 *)( (uint8 *)ip + sizeof(mac_t) ); - - uint32 sum32 = 0; - for( int i=0; ichecksum = htons((uint16)sum32); -} - -void make_udp_checksum( udp_t *udp ) -{ - udp->checksum = 0; - return; - - // UDP checksums are optional. - - /* - uint16 sz = ntohs(udp->msg_len) / 2; - uint16 *p = (uint16 *)( (uint8 *)udp + sizeof(ip_t) ); - - uint32 sum32 = 0; - for( int i=0; iip.src)); - pseudo.src_hi = HIWORD(ntohl(udp->ip.src)); - pseudo.dest_lo = LOWORD(ntohl(udp->ip.dest)); - pseudo.dest_hi = HIWORD(ntohl(udp->ip.dest)); - pseudo.proto = (uint16)udp->ip.proto; - pseudo.msg_len = ntohs(udp->msg_len); // ??? - - p = (uint16 *)&pseudo; - - for( i=0; ichecksum = htons((uint16)sum32); - */ -} - -void error_winsock_2_icmp( int err, ip_t *ip_err, int dlen_err ) -{ - int type = -1, code = -1, msg_size = 0; - - switch( err ) { - case WSAEHOSTUNREACH: - case WSAETIMEDOUT: - type = icmp_Destination_unreachable; - code = 1; // Host unreachable - msg_size = (ip_err->header_len << 2) + 4 + 8; // ip header + unused + 64 msg bits - break; - case WSAENETDOWN: - case WSAENETUNREACH: - type = icmp_Destination_unreachable; - code = 0; // Network unreachable - msg_size = (ip_err->header_len << 2) + 4 + 8; // ip header + unused + 64 msg bits - break; - case WSAETTLEXCEEDED: - type = icmp_Time_exceeded; - code = 0; // Transit TTL exceeded - msg_size = (ip_err->header_len << 2) + 4 + 8; // ip header + unused + 64 msg bits - break; - } - - if(type >= 0 && macos_ip_address != 0) { - D(bug("sending icmp error reply. type=%d, code=%d, msg_size=%d\r\n", type, code, msg_size)); - - int icmp_size = sizeof(icmp_t) + msg_size; - - icmp_t *icmp = (icmp_t *)malloc( icmp_size ); - if(icmp) { - mac_t *mac = (mac_t *)icmp; - ip_t *ip = (ip_t *)icmp; - - memcpy( mac->dest, ether_addr, 6 ); - memcpy( mac->src, router_mac_addr, 6 ); - mac->type = htons(mac_type_ip4); - - ip->version = 4; - ip->header_len = 5; - ip->tos = 0; - ip->total_len = htons(sizeof(icmp_t) - sizeof(mac_t) + msg_size); - - ip->ident = htons(next_ip_ident_number++); - ip->flags_n_frag_offset = 0; - ip->ttl = 128; - ip->proto = ip_proto_icmp; - ip->src = htonl(router_ip_address); - ip->dest = htonl(macos_ip_address); - make_ip4_checksum( ip ); - - icmp->type = type; - icmp->code = code; - - // zero out the unused field - memset( (char *)icmp + sizeof(icmp_t), 0, sizeof(uint32) ); - - // copy 64 bits of original message - memcpy( - (char *)icmp + sizeof(icmp_t) + sizeof(uint32), - (char *)ip_err + sizeof(mac_t), - msg_size - ); - - make_icmp_checksum( icmp, icmp_size ); - - dump_bytes( (uint8 *)icmp, icmp_size ); - - enqueue_packet( (uint8 *)icmp, icmp_size ); - free(icmp); - } - } -} diff --git a/BasiliskII/src/Windows/router/iphelp.h b/BasiliskII/src/Windows/router/iphelp.h deleted file mode 100755 index 513616da..00000000 --- a/BasiliskII/src/Windows/router/iphelp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * iphelp.h - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _IPHELP_H_ -#define _IPHELP_H_ - -// Fake ttl exceeded code. -#define WSAETTLEXCEEDED (WSABASEERR + 1999 + 17) - -void error_winsock_2_icmp( int err, ip_t *ip_err, int dlen_err ); - -void make_icmp_checksum( icmp_t *icmp, int len ); -void make_ip4_checksum( ip_t *ip ); -void make_udp_checksum( udp_t *udp ); -void make_tcp_checksum( tcp_t *tcp, int len ); - -#endif // _IPHELP_H_ diff --git a/BasiliskII/src/Windows/router/ipsocket.cpp b/BasiliskII/src/Windows/router/ipsocket.cpp deleted file mode 100755 index 21fef9a9..00000000 --- a/BasiliskII/src/Windows/router/ipsocket.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * ipsocket.cpp - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "main.h" -#include "cpu_emulation.h" -#include "ws2tcpip.h" -#include "prefs.h" -#include "ether_windows.h" -#include "ether.h" -#include "router.h" -#include "router_types.h" -#include "dynsockets.h" -#include "ipsocket.h" -#include "icmp.h" -#include "tcp.h" -#include "udp.h" -#include "dump.h" - - -#if DEBUG -#pragma optimize("",off) -#endif - -#include "debug.h" - - -socket_t::socket_t( int _proto ) -{ - s = INVALID_SOCKET; - proto = _proto; - - ip_src = ip_dest = 0; - src_port = dest_port = 0; - - memset( &overlapped, 0, sizeof(overlapped) ); - overlapped.hEvent = (HANDLE)this; - - bytes_received = 0; - flags = 0; - from_len = sizeof(struct sockaddr_in); - memset( &from, 0, sizeof(from) ); - from.sin_family = AF_INET; - - buffer_count = 1; - buffers[0].len = 1460; - buffers[0].buf = new char [buffers[0].len]; - - out_buffers[0].len = 1460; - out_buffers[0].buf = new char [out_buffers[0].len]; - - socket_ttl = GetTickCount() + 60000L; - permanent = false; -} - -socket_t::~socket_t() -{ - if(s != INVALID_SOCKET) { - _closesocket( s ); // slam! - s = INVALID_SOCKET; - } - delete [] out_buffers[0].buf; - delete [] buffers[0].buf; -} - -int socket_t::WSARecvFrom() -{ - return _WSARecvFrom( - s, - buffers, - buffer_count, - &bytes_received, - &flags, - (struct sockaddr *)&from, - &from_len, - &overlapped, - proto == IPPROTO_UDP ? udp_read_completion : icmp_read_completion - ); -} - -bool socket_t::b_recfrom() -{ - bool result; - - int ret = WSARecvFrom(); - - if(ret == SOCKET_ERROR) { - int socket_error = _WSAGetLastError(); - if(socket_error == WSA_IO_PENDING) { - D(bug("WSARecvFrom() i/o pending\r\n")); - result = true; - } else { - D(bug("_WSAGetLastError() returned %d\r\n", socket_error)); - result = false; - } - } else /*if(ret == 0) */ { - D(bug("WSARecvFrom() ok\r\n")); - // Completion routine call is already scheduled. - result = true; - } - return result; -} - -void socket_t::set_ttl( uint8 ttl ) -{ - int _ttl = ttl; // defensive programming, I know VCx - - if(_setsockopt( s, IPPROTO_IP, IP_TTL, (const char *)&_ttl, sizeof(int) ) == SOCKET_ERROR ) { - D(bug("could not set ttl to %d.\r\n", ttl)); - } else { - D(bug("ttl set to %d.\r\n", ttl)); - } -} - - -#define MAX_OPEN_SOCKETS 1024 -static socket_t *all_sockets[MAX_OPEN_SOCKETS]; -static int open_sockets = 0; - -int get_socket_index( uint16 src_port, uint16 dest_port, int proto ) -{ - int result = -1; - for( int i=0; isrc_port == src_port && cmpl->dest_port == dest_port && cmpl->proto == proto ) { - result = i; - break; - } - } - return result; -} - -int get_socket_index( uint16 src_port, int proto ) -{ - int result = -1; - for( int i=0; isrc_port == src_port && cmpl->proto == proto ) { - result = i; - break; - } - } - return result; -} - -int get_socket_index( socket_t *cmpl ) -{ - int result = -1; - for( int i=0; isrc_port, cmpl->dest_port)); - - EnterCriticalSection( &router_section ); - int i = get_socket_index( cmpl ); - if( i >= 0 ) { - delete all_sockets[i]; - all_sockets[i] = all_sockets[--open_sockets]; - } else { - D(bug("Deleted socket not in table!\r\n")); - // delete cmpl; - } - LeaveCriticalSection( &router_section ); -} - -socket_t *find_socket( uint16 src_port, uint16 dest_port, int proto ) -{ - socket_t *result = 0; - EnterCriticalSection( &router_section ); - int i = get_socket_index( src_port, dest_port, proto ); - if( i >= 0 ) { - result = all_sockets[i]; - } else { - i = get_socket_index( src_port, proto ); - if( i >= 0 ) { - delete_socket( all_sockets[i] ); - } - } - LeaveCriticalSection( &router_section ); - - D(bug("find_socket(%d,%d): %s\r\n", src_port, dest_port, result ? "found" : "not found")); - - return result; -} - -void add_socket( socket_t *cmpl ) -{ - D(bug("adding socket(%d,%d)\r\n", cmpl->src_port, cmpl->dest_port)); - - EnterCriticalSection( &router_section ); - if( open_sockets < MAX_OPEN_SOCKETS ) { - all_sockets[open_sockets++] = cmpl; - } else { - // Urgchiyuppijee! (that's finnish language, meaning "do something about this") - delete all_sockets[0]; - all_sockets[0] = cmpl; - } - LeaveCriticalSection( &router_section ); -} - -void close_old_sockets() -{ - DWORD now = GetTickCount(); - - EnterCriticalSection( &router_section ); - for( int i=open_sockets-1; i>=0; i-- ) { - socket_t *cmpl = all_sockets[i]; - if( !cmpl->permanent && now >= cmpl->socket_ttl ) { - D(bug("expiring socket(%d,%d)\r\n", cmpl->src_port, cmpl->dest_port)); - if(cmpl->s == INVALID_SOCKET) { - delete all_sockets[i]; - all_sockets[i] = all_sockets[--open_sockets]; - } else { - // read completion will deallocate - _closesocket( cmpl->s ); - } - } - } - LeaveCriticalSection( &router_section ); -} - -void close_all_sockets() -{ - D(bug("closing all(%d) sockets\r\n", open_sockets)); - - EnterCriticalSection( &router_section ); - for( int i=0; isrc_port, cmpl->dest_port)); - if(cmpl->s == INVALID_SOCKET) { - delete all_sockets[i]; - all_sockets[i] = all_sockets[--open_sockets]; - } else { - // read completion will deallocate - _closesocket( cmpl->s ); - } - } - LeaveCriticalSection( &router_section ); -} diff --git a/BasiliskII/src/Windows/router/ipsocket.h b/BasiliskII/src/Windows/router/ipsocket.h deleted file mode 100755 index 97005f12..00000000 --- a/BasiliskII/src/Windows/router/ipsocket.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * ipsocket.h - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _IPSOCKET_H_ -#define _IPSOCKET_H_ - -class socket_t { -public: - socket_t( int _proto ); - ~socket_t(); - bool b_recfrom(); - void set_ttl( uint8 ttl ); - -protected: - int WSARecvFrom(); - -public: - SOCKET s; // Always a valid socket - BOOL permanent; // T: a user-defined listening socket, - int proto; // udp/icmp - WSABUF buffers[1]; - WSABUF out_buffers[1]; - DWORD buffer_count; - DWORD bytes_received; - DWORD flags; - struct sockaddr_in from; - int from_len; - WSAOVERLAPPED overlapped; - uint32 ip_src; - uint32 ip_dest; - uint16 src_port; - uint16 dest_port; - DWORD socket_ttl; -}; - - -int get_socket_index( uint16 src_port, uint16 dest_port, int proto ); -int get_socket_index( uint16 src_port, int proto ); -int get_socket_index( socket_t *cmpl ); -void delete_socket( socket_t *cmpl ); -socket_t *find_socket( uint16 src_port, uint16 dest_port, int proto ); -void add_socket( socket_t *cmpl ); -void close_old_sockets(); -void close_all_sockets(); - - -#endif // _IPSOCKET_H_ diff --git a/BasiliskII/src/Windows/router/mib/interfaces.cpp b/BasiliskII/src/Windows/router/mib/interfaces.cpp deleted file mode 100755 index d89d407d..00000000 --- a/BasiliskII/src/Windows/router/mib/interfaces.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * interfaces.cpp - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "main.h" -#include "interfaces.h" -#include "../dump.h" -#include "mibaccess.h" - -#if DEBUG -#pragma optimize("",off) -#endif - -#include "debug.h" - -static UINT ip_array[100]; -static UINT ip_array_sz = 0; - -void init_interfaces() -{ - MibII _mibs(false); - - ip_array_sz = sizeof(ip_array) / sizeof(ip_array[0]); - - if(_mibs.Init()) { - _mibs.GetIPAddress( ip_array, ip_array_sz ); - } - - if(ip_array_sz == 0) { - ip_array_sz = 1; - ip_array[0] = 0; // localhost - } - - D(bug("init_interfaces() found %d interfaces.\r\n", ip_array_sz)); -} - -void final_interfaces() -{ - // Currently nothing to do. -} - -int get_ip_count() -{ - return ip_array_sz; -} - -uint32 get_ip_by_index( int index ) -{ - return index >= 0 && index < (int)ip_array_sz ? ip_array[index] : 0; -} diff --git a/BasiliskII/src/Windows/router/mib/interfaces.h b/BasiliskII/src/Windows/router/mib/interfaces.h deleted file mode 100755 index aeb15223..00000000 --- a/BasiliskII/src/Windows/router/mib/interfaces.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * intercafes.h - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _INTERFACES_H_ -#define _INTERFACES_H_ - -// A wrapper to the MibII class. Enumerates all ip interfaces -// currently in this computer. The interface list is not static. - -void init_interfaces(); -void final_interfaces(); - -int get_ip_count(); -uint32 get_ip_by_index( int index ); - -#endif // _INTERFACES_H_ diff --git a/BasiliskII/src/Windows/router/mib/mibaccess.cpp b/BasiliskII/src/Windows/router/mib/mibaccess.cpp deleted file mode 100755 index f877db9d..00000000 --- a/BasiliskII/src/Windows/router/mib/mibaccess.cpp +++ /dev/null @@ -1,308 +0,0 @@ -/* - * MibAccess.cpp - * - * The original code by Stas Khirman modified by Lauri Pesonen, December, 2000: - * - * SnmpUtilVarBindFree(), SnmpUtilOidNCmp() and SnmpUtilOidCpy() now loaded from - * "snmpapi.dll" dynamically instead of linking statically. - * - * MibII ctor now takes a parameter whether to load Winsock or not. - * WSAStartup maintains an internal reference counter so it would have been ok - * to let it load always. - * - * Fixed a bug where the return value of LoadLibrary() was compared against - * HINSTANCE_ERROR instead of NULL. - * - * Removed some type conversion warnings by casting. - * - * Added a check in MibExtLoad ctor that the function entry points were found. - * - * Added a check in GetIPMask() and GetIPAddress() that the library was loaded - * before accessing the functions. - * - * Changed the return type of GetIPAddress() and GetIPMask() from BOOL to void - * as they always returned TRUE. - * - */ - -/************************************************************************/ -/* Copyright (C) Stas Khirman 1998. All rights reserved. */ -/* Written by Stas Khirman (staskh@rocketmail.com). */ -/* and */ -/* Raz Galili (razgalili@hotmail.com) */ -/* */ -/* Free software: no warranty; use anywhere is ok; spread the */ -/* sources; note any modifications; share variations and */ -/* derivatives (including sending to staskh@rocketmail.com). */ -/* */ -/************************************************************************/ - -/* - * MibAccess.cpp - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "sysdeps.h" -#include "main.h" -#include "mibaccess.h" -#include "../dynsockets.h" -#include "../dump.h" - -#if DEBUG -#pragma optimize("",off) -#endif - -#include "debug.h" - -MibExtLoad::MibExtLoad( LPCTSTR MibDllName, LPCTSTR SnmpDllName ) -{ - m_Init = NULL; - - m_InitEx = NULL; - m_Query = NULL; - m_Trap = NULL; - - m_hInst_snmputil = NULL; - - m_SnmpUtilVarBindFree = NULL; - m_SnmpUtilOidNCmp = NULL; - m_SnmpUtilOidCpy = NULL; - - m_hInst = LoadLibrary( MibDllName ); - if(!m_hInst) { - D(bug(TEXT("MIB: library %s could not be loaded.\r\n"), MibDllName)); - return; - } - D(bug(TEXT("MIB: library %s loaded ok.\r\n"), MibDllName)); - - m_Init = (pSnmpExtensionInit)GetProcAddress(m_hInst ,"SnmpExtensionInit"); - m_InitEx= (pSnmpExtensionInitEx)GetProcAddress(m_hInst ,"SnmpExtensionInitEx"); - m_Query = (pSnmpExtensionQuery)GetProcAddress(m_hInst ,"SnmpExtensionQuery"); - m_Trap = (pSnmpExtensionTrap)GetProcAddress(m_hInst ,"SnmpExtensionTrap"); - - if( !m_Init || !m_InitEx || !m_Query || !m_Trap ) - { - D(bug(TEXT("MIB: required entry points not found in library %s.\r\n"), MibDllName)); - FreeLibrary( m_hInst ); - m_hInst = NULL; - } - - m_hInst_snmputil = LoadLibrary( SnmpDllName ); - if(!m_hInst_snmputil){ - D(bug(TEXT("MIB: library %s could not be loaded.\r\n"), SnmpDllName)); - FreeLibrary( m_hInst ); - m_hInst = NULL; - return; - } - D(bug(TEXT("MIB: library %s loaded ok.\r\n"), SnmpDllName)); - - m_SnmpUtilVarBindFree = (VOID (SNMP_FUNC_TYPE *)(SnmpVarBind *))GetProcAddress( m_hInst_snmputil, "SnmpUtilVarBindFree" ); - m_SnmpUtilOidNCmp = (SNMPAPI (SNMP_FUNC_TYPE *)(AsnObjectIdentifier *, AsnObjectIdentifier *, UINT))GetProcAddress( m_hInst_snmputil, "SnmpUtilOidNCmp" ); - m_SnmpUtilOidCpy = (SNMPAPI (SNMP_FUNC_TYPE *)(AsnObjectIdentifier *, AsnObjectIdentifier *))GetProcAddress( m_hInst_snmputil, "SnmpUtilOidCpy" ); - - if( !m_SnmpUtilVarBindFree || !m_SnmpUtilOidNCmp || !m_SnmpUtilOidCpy ) - { - D(bug(TEXT("MIB: required entry points not found in library %s.\r\n"), SnmpDllName)); - FreeLibrary( m_hInst ); - FreeLibrary( m_hInst_snmputil ); - m_hInst = NULL; - m_hInst_snmputil = NULL; - } - - #undef SNMP_FreeVarBind - #undef SNMP_oidncmp - #undef SNMP_oidcpy - - #define SNMP_FreeVarBind m_SnmpUtilVarBindFree - #define SNMP_oidncmp m_SnmpUtilOidNCmp - #define SNMP_oidcpy m_SnmpUtilOidCpy -} - -MibExtLoad::~MibExtLoad() -{ - if( m_hInst ) { - FreeLibrary( m_hInst ); - m_hInst = NULL; - } - if( m_hInst_snmputil ) { - FreeLibrary( m_hInst_snmputil ); - m_hInst_snmputil = NULL; - } -} - -BOOL MibExtLoad::Init(DWORD dwTimeZeroReference,HANDLE *hPollForTrapEvent,AsnObjectIdentifier *supportedView) -{ - if(m_hInst && m_Init) - return m_Init(dwTimeZeroReference,hPollForTrapEvent,supportedView); - return FALSE; -} -BOOL MibExtLoad::InitEx(AsnObjectIdentifier *supportedView) -{ - if(m_hInst && m_InitEx) - return m_InitEx(supportedView); - - return FALSE; -} - -BOOL MibExtLoad::Query(BYTE requestType,OUT RFC1157VarBindList *variableBindings, - AsnInteger *errorStatus,AsnInteger *errorIndex) -{ - if(m_hInst && m_Query) - return m_Query(requestType,variableBindings,errorStatus,errorIndex); - - return FALSE; -} - -BOOL MibExtLoad::Trap(AsnObjectIdentifier *enterprise, AsnInteger *genericTrap, - AsnInteger *specificTrap, AsnTimeticks *timeStamp, - RFC1157VarBindList *variableBindings) -{ - if(m_hInst && m_Trap) - return m_Trap(enterprise, genericTrap,specificTrap, timeStamp, variableBindings); - - return FALSE; -} - -MibII::MibII(bool load_winsock) : MibExtLoad(TEXT("inetmib1.dll"), TEXT("snmpapi.dll")) -{ - WSADATA wsa; - m_load_winsock = load_winsock; - if(load_winsock) { - int err = _WSAStartup( 0x0101, &wsa ); - } -} - -MibII::~MibII() -{ - if(m_load_winsock) _WSACleanup(); -} - -BOOL MibII::Init() -{ - HANDLE PollForTrapEvent; - AsnObjectIdentifier SupportedView; - - return MibExtLoad::Init(GetTickCount(),&PollForTrapEvent,&SupportedView); - -} - - -void MibII::GetIPAddress( UINT IpArray[], UINT &IpArraySize ) -{ - if(!m_hInst) { - IpArraySize = 0; - return; - } - - UINT OID_ipAdEntAddr[] = { 1, 3, 6, 1, 2, 1, 4 , 20, 1 ,1 }; - AsnObjectIdentifier MIB_ipAdEntAddr = { sizeof(OID_ipAdEntAddr)/sizeof(UINT), OID_ipAdEntAddr }; - RFC1157VarBindList varBindList; - RFC1157VarBind varBind[1]; - AsnInteger errorStatus; - AsnInteger errorIndex; - AsnObjectIdentifier MIB_NULL = {0,0}; - BOOL Exit; - int ret; - int IpCount=0; - DWORD dtmp; - - varBindList.list = varBind; - varBindList.len = 1; - varBind[0].name = MIB_NULL; - SNMP_oidcpy(&varBind[0].name,&MIB_ipAdEntAddr); - Exit = FALSE; - - IpCount=0; - while(!Exit){ - ret = Query(ASN_RFC1157_GETNEXTREQUEST,&varBindList,&errorStatus,&errorIndex); - - if(!ret) - Exit=TRUE; - else{ - ret = SNMP_oidncmp(&varBind[0].name,&MIB_ipAdEntAddr,MIB_ipAdEntAddr.idLength); - if(ret!=0){ - Exit=TRUE; - } - else{ - dtmp = *((DWORD *)varBind[0].value.asnValue.address.stream); - IpArray[IpCount] = dtmp; - IpCount++; - if(IpCount>=(int)IpArraySize) - Exit = TRUE; - } - } - } - - IpArraySize = IpCount; - - SNMP_FreeVarBind(&varBind[0]); -} - -void MibII::GetIPMask( UINT IpArray[], UINT &IpArraySize ) -{ - if(!m_hInst) { - IpArraySize = 0; - return; - } - - UINT OID_ipAdEntMask[] = { 1, 3, 6, 1, 2, 1, 4 , 20, 1 ,3 }; - AsnObjectIdentifier MIB_ipAdEntMask = { sizeof(OID_ipAdEntMask)/sizeof(UINT), OID_ipAdEntMask }; - RFC1157VarBindList varBindList; - RFC1157VarBind varBind[1]; - AsnInteger errorStatus; - AsnInteger errorIndex; - AsnObjectIdentifier MIB_NULL = {0,0}; - BOOL Exit; - int ret; - int IpCount=0; - DWORD dtmp; - - varBindList.list = varBind; - varBindList.len = 1; - varBind[0].name = MIB_NULL; - SNMP_oidcpy(&varBind[0].name,&MIB_ipAdEntMask); - Exit = FALSE; - - IpCount=0; - while(!Exit){ - ret = Query(ASN_RFC1157_GETNEXTREQUEST,&varBindList,&errorStatus,&errorIndex); - - if(!ret) - Exit=TRUE; - else{ - ret = SNMP_oidncmp(&varBind[0].name,&MIB_ipAdEntMask,MIB_ipAdEntMask.idLength); - if(ret!=0){ - Exit=TRUE; - } - else{ - dtmp = *((DWORD *)varBind[0].value.asnValue.address.stream); - IpArray[IpCount] = dtmp; - IpCount++; - if(IpCount>=(int)IpArraySize) - Exit = TRUE; - } - } - } - - IpArraySize = IpCount; - - SNMP_FreeVarBind(&varBind[0]); -} diff --git a/BasiliskII/src/Windows/router/mib/mibaccess.h b/BasiliskII/src/Windows/router/mib/mibaccess.h deleted file mode 100755 index 385f5b85..00000000 --- a/BasiliskII/src/Windows/router/mib/mibaccess.h +++ /dev/null @@ -1,83 +0,0 @@ -////////////////////////////////////////////////////// -// FILE : MibAccess.h -// -// - -#ifndef _SNMP_ACCESS_H_ -#define _SNMP_ACCESS_H_ - -#include -#ifndef SNMP_FUNC_TYPE -#define SNMP_FUNC_TYPE WINAPI -#endif - -////////////////////////////////////////////////////////////// -// Definition of pointers to the four functions in the Mib Dll -// -typedef BOOL (WINAPI *pSnmpExtensionInit)( - IN DWORD dwTimeZeroReference, - OUT HANDLE *hPollForTrapEvent, - OUT AsnObjectIdentifier *supportedView); - -typedef BOOL (WINAPI *pSnmpExtensionTrap)( - OUT AsnObjectIdentifier *enterprise, - OUT AsnInteger *genericTrap, - OUT AsnInteger *specificTrap, - OUT AsnTimeticks *timeStamp, - OUT RFC1157VarBindList *variableBindings); - -typedef BOOL (WINAPI *pSnmpExtensionQuery)( - IN BYTE requestType, - IN OUT RFC1157VarBindList *variableBindings, - OUT AsnInteger *errorStatus, - OUT AsnInteger *errorIndex); - -typedef BOOL (WINAPI *pSnmpExtensionInitEx)(OUT AsnObjectIdentifier *supportedView); - - -class MibExtLoad -{ -public: - MibExtLoad( LPCTSTR MibDllName, LPCTSTR SnmpDllName ); - ~MibExtLoad(); - BOOL Init(DWORD dwTimeZeroReference,HANDLE *hPollForTrapEvent,AsnObjectIdentifier *supportedView); - BOOL InitEx(AsnObjectIdentifier *supportedView); - BOOL Query(BYTE requestType,OUT RFC1157VarBindList *variableBindings, - AsnInteger *errorStatus,AsnInteger *errorIndex); - - BOOL Trap(AsnObjectIdentifier *enterprise, AsnInteger *genericTrap, - AsnInteger *specificTrap, AsnTimeticks *timeStamp, - RFC1157VarBindList *variableBindings); - -public: - HINSTANCE m_hInst; - HINSTANCE m_hInst_snmputil; - -private: - pSnmpExtensionInit m_Init; - pSnmpExtensionInitEx m_InitEx; - pSnmpExtensionQuery m_Query; - pSnmpExtensionTrap m_Trap; - -public: - VOID (SNMP_FUNC_TYPE *m_SnmpUtilVarBindFree) (SnmpVarBind *); - SNMPAPI (SNMP_FUNC_TYPE *m_SnmpUtilOidNCmp) (AsnObjectIdentifier *, AsnObjectIdentifier *, UINT); - SNMPAPI (SNMP_FUNC_TYPE *m_SnmpUtilOidCpy) (AsnObjectIdentifier *, AsnObjectIdentifier *); -}; - - -class MibII: public MibExtLoad -{ -public: - MibII( bool load_winsock ); - ~MibII(); - BOOL Init(); - - void GetIPAddress(UINT IpArray[],UINT &IpArraySize); - void GetIPMask(UINT IpArray[],UINT &IpArraySize); - -protected: - bool m_load_winsock; -}; - -#endif diff --git a/BasiliskII/src/Windows/router/router.cpp b/BasiliskII/src/Windows/router/router.cpp deleted file mode 100755 index 10fe2fd7..00000000 --- a/BasiliskII/src/Windows/router/router.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* - * router.cpp - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * This could be implemented by writing three (9x,nt,2k) - * NDIS filter drivers. No thanks. - * But this is not easy either. - */ - -#include "sysdeps.h" -#include "main.h" - -#include - -#include "cpu_emulation.h" -#include "prefs.h" -#include "ether_windows.h" -#include "ether.h" -#include "router.h" -#include "router_types.h" -#include "dynsockets.h" -#include "ipsocket.h" -#include "iphelp.h" -#include "arp.h" -#include "icmp.h" -#include "udp.h" -#include "tcp.h" -#include "ftp.h" -#include "mib/interfaces.h" -#include "dump.h" - - -#if DEBUG -#pragma optimize("",off) -#endif - -#include "debug.h" - - -uint16 next_ip_ident_number = 1; -uint32 macos_ip_address = 0; -const uint8 router_mac_addr[6] = { '4', '2', '6', '7', '7', '9' }; -uint32 router_ip_address = 0; -bool raw_sockets_available = false; - - - -// Protected data. -CRITICAL_SECTION router_section; -bool is_router_shutting_down = false; -static HANDLE r_handle = 0; -static unsigned int rh_tid = 0; - - -static void write_ip4( ip_t *ip, int len ) -{ - if(len < sizeof(ip_t)) { - D(bug("Too small ip packet(%d), dropped\r\n", len)); - } else { - uint8 proto = ip->proto; - - // This is a router, decrement the hop count - if( --ip->ttl == 0 ) { - // Most likely this is some Mac traceroute app - D(bug("ip packet ttl expired, proto=%d.\r\n", proto)); - error_winsock_2_icmp( WSAETTLEXCEEDED, ip, len ); - } else { - switch( proto ) { - case ip_proto_icmp: - write_icmp( (icmp_t *)ip, len ); - break; - case ip_proto_tcp: - write_tcp( (tcp_t *)ip, len ); - break; - case ip_proto_udp: - write_udp( (udp_t *)ip, len ); - break; - default: - D(bug("write_ip4() len=%d, proto=%d\r\n", len, proto)); - break; - } - } - } -} - -bool router_write_packet(uint8 *packet, int len) -{ - bool result = false; - - if( len >= 14 ) { - switch( ntohs( ((mac_t *)packet)->type ) ) { - case mac_type_ip4: - write_ip4( (ip_t *)packet, len ); - result = true; - break; - case mac_type_ip6: - D(bug("write_ip6() len=%d; unsupported.\r\n", len)); - result = true; - break; - case mac_type_arp: - result = write_arp( (arp_t *)packet, len ); - break; - } - } - return result; -} - -bool router_read_packet(uint8 *packet, int len) -{ - bool result = false; - - if( len >= 14 ) { - switch( ntohs( ((mac_t *)packet)->type ) ) { - case mac_type_ip4: - case mac_type_ip6: - case mac_type_arp: - result = true; - break; - } - } - return result; -} - -/* - This has nothing to do with TCP TIME_WAITs or CLOSE_WAITs, - the thread is needed to close down expired udp sockets. - Arguably an ugly hack, but needed since there is no way to - listen to all ports w/o writing another ndis filter driver -*/ -static unsigned int WINAPI router_expire_thread(void *arg) -{ - while(!is_router_shutting_down) { - close_old_sockets(); - Sleep(1000); - } - return 0; -} - -bool router_init(void) -{ - InitializeCriticalSection( &router_section ); - - if(dynsockets_init()) { - char me[128]; - if( _gethostname(me, sizeof(me)) == SOCKET_ERROR ) { - D(bug("gethostname() failed, error = %d\r\n", _WSAGetLastError())); - } else { - struct hostent *hent = _gethostbyname(me); - if( hent == NULL ) { - D(bug("gethostbyname() failed, error = %d\r\n", _WSAGetLastError())); - } else { - struct in_addr *ina = (struct in_addr *) *hent->h_addr_list; - router_ip_address = ntohl(ina->s_addr); - D(bug("router protocol address seems to be %s (used only in icmp error messages)\r\n", _inet_ntoa(*ina))); - } - } - is_router_shutting_down = false; - r_handle = (HANDLE)_beginthreadex( 0, 0, router_expire_thread, 0, 0, &rh_tid ); - init_interfaces(); - init_tcp(); - init_udp(); - init_ftp(); - return true; - } - - return false; -} - -void router_final(void) -{ - final_interfaces(); - stop_icmp_listen(); - close_all_sockets(); - if(r_handle) { - is_router_shutting_down = true; - WaitForSingleObject( r_handle, INFINITE ); - final_tcp(); - final_udp(); - dynsockets_final(); - } - DeleteCriticalSection( &router_section ); -} diff --git a/BasiliskII/src/Windows/router/router.h b/BasiliskII/src/Windows/router/router.h deleted file mode 100755 index 5d3e74b5..00000000 --- a/BasiliskII/src/Windows/router/router.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * router.h - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _ROUTER_H_ -#define _ROUTER_H_ - -extern bool is_router_shutting_down; -extern CRITICAL_SECTION router_section; - -// Increased by one for each ip packet sent to the emulated enet interface. -extern uint16 next_ip_ident_number; - -// Used by incoming icmp packets and internal icmp messages. Host byte order. -extern uint32 macos_ip_address; - -// The magic constant -extern const uint8 router_mac_addr[6]; - -// Used by internal icmp messages. Host byte order. -extern uint32 router_ip_address; - -// False under NT/Win2k if the user has no admin rights -extern bool raw_sockets_available; - - - -// Interface exposed to ether_windows module. -bool router_init(void); -void router_final(void); - -// Both of these return true if the ethernet module should drop the packet. -bool router_write_packet(uint8 *packet, int len); -bool router_read_packet(uint8 *packet, int len); - -#endif // _ROUTER_H_ diff --git a/BasiliskII/src/Windows/router/router_types.h b/BasiliskII/src/Windows/router/router_types.h deleted file mode 100755 index 9dcc8e63..00000000 --- a/BasiliskII/src/Windows/router/router_types.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * router_types.h - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _ROUTER_TYPES_H_ -#define _ROUTER_TYPES_H_ - -#pragma pack(push, 1) - - -// --------------------------- MAC --------------------------- -typedef struct { - uint8 dest[6]; - uint8 src[6]; - uint16 type; -} mac_t; - -enum { - mac_type_llc_ipx_limit = 0x05DC, // <= mac_type_llc_ipx_limit -->> 802.3 MAC frame - mac_type_ip4 = 0x0800, - mac_type_arp = 0x0806, - mac_type_rarp = 0x8035, - mac_type_ip6 = 0x86DD, - mac_type_loopback = 0x9000 -}; - -// --------------------------- ARP --------------------------- -typedef struct { - mac_t mac; - uint16 htype; - uint16 ptype; - uint8 halen; - uint8 palen; - uint16 opcode; - uint8 srch[6]; // size for ethernet - uint8 srcp[4]; // size for ip - uint8 dsth[6]; // size for ethernet - uint8 dstp[4]; // size for ip -} arp_t; - -enum { - arp_request = 1, - arp_reply = 2 -}; -enum { - arp_hwtype_enet = 1 -}; - -// --------------------------- IP4 --------------------------- -typedef struct { - mac_t mac; - uint8 header_len:4; - uint8 version:4; - uint8 tos; - uint16 total_len; - uint16 ident; - uint16 flags_n_frag_offset; // foffset 0..11, flags 12..15 - uint8 ttl; - uint8 proto; - uint16 checksum; - uint32 src; - uint32 dest; - // ip options, size = 4 * header_len - 20 -} ip_t; - -// Protocol STD numbers -enum { - ip_proto_icmp = IPPROTO_ICMP, - ip_proto_tcp = IPPROTO_TCP, - ip_proto_udp = IPPROTO_UDP -}; - -// --------------------------- ICMP --------------------------- -typedef struct { - ip_t ip; - uint8 type; - uint8 code; - uint16 checksum; - // data -} icmp_t; - -enum { - icmp_Echo_reply = 0, - icmp_Destination_unreachable = 3, - icmp_Source_quench = 4, - icmp_Redirect = 5, - icmp_Echo = 8, - icmp_Router_advertisement = 9, - icmp_Router_solicitation = 10, - icmp_Time_exceeded = 11, - icmp_Parameter_problem = 12, - icmp_Time_Stamp_request = 13, - icmp_Time_Stamp_reply = 14, - icmp_Information_request_obsolete = 15, - icmp_Information_reply_obsolete = 16, - icmp_Address_mask_request = 17, - icmp_Address_mask_reply = 18, - icmp_Traceroute = 30, - icmp_Datagram_conversion_error = 31, - icmp_Mobile_host_redirect = 32, - icmp_IPv6_Where_Are_You = 33, - icmp_IPv6_I_Am_Here = 34, - icmp_Mobile_registration_request = 35, - icmp_Mobile_registration_reply = 36, - icmp_Domain_name_request = 37, - icmp_Domain_name_reply = 38, - icmp_SKIP = 39, - icmp_Photuris = 40 -}; - -// --------------------------- TCP --------------------------- -typedef struct { - ip_t ip; - uint16 src_port; - uint16 dest_port; - uint32 seq; - uint32 ack; - uint8 header_len; // note: some reserved bits - uint8 flags; // note: some reserved bits - uint16 window; - uint16 checksum; - uint16 urgent_ptr; - // options + padding: size = dataoffset*4-20 - // data -} tcp_t; - -enum { - tcp_flags_URG = 0x20, // The urgent pointer field is significant in this segment. - tcp_flags_ACK = 0x10, // The acknowledgment field is significant in this segment. - tcp_flags_PSH = 0x08, // Push function. - tcp_flags_RST = 0x04, // Resets the connection. - tcp_flags_SYN = 0x02, // Synchronizes the sequence numbers. - tcp_flags_FIN = 0x01 // No more data from sender. -}; - -enum { - tcp_state_closed, - tcp_state_listen, - tcp_state_syn_sent, - tcp_state_syn_rcvd, - tcp_state_established, - tcp_state_close_wait, - tcp_state_last_ack, - tcp_state_finwait_1, - tcp_state_finwait_2, - tcp_state_closing, - tcp_state_time_wait -}; - -// --------------------------- UDP --------------------------- -typedef struct { - ip_t ip; - uint16 src_port; - uint16 dest_port; - uint16 msg_len; - uint16 checksum; - // data -} udp_t; - -typedef struct { - uint16 src_lo, src_hi; - uint16 dest_lo, dest_hi; - uint16 proto; - uint16 msg_len; -} pseudo_ip_t; - -#pragma pack(pop) - -#endif // _ROUTER_TYPES_H_ diff --git a/BasiliskII/src/Windows/router/tcp.cpp b/BasiliskII/src/Windows/router/tcp.cpp deleted file mode 100755 index 4b0800dd..00000000 --- a/BasiliskII/src/Windows/router/tcp.cpp +++ /dev/null @@ -1,1605 +0,0 @@ -/* - * tcp.cpp - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Features implemented: - * state machine, flow control, sequence numbers, RST/SYN/FIN/ACK/PSH - * - * Features not implemented: - * oob data, urgent pointer, window sliding, some options - * "Half-Nagle" implementation is a bit weird (mac-router interface; winsock has it on by default) - * - * - * All possible tcp state machine transitions: - * - * CLOSED -> LISTEN passive open - * CLOSED -> SYN_SENT active open SYN-> - * - * LISTEN -> SYN_SENT send data SYN-> - * LISTEN -> SYN_RCVD ->SYN SYN+ACK-> - * - * SYN_SENT -> SYN_RCVD ->SYN SYN+ACK-> - * SYN_SENT -> ESTABLISHED ->SYN+ACK ACK-> - * SYN_SENT -> CLOSED close/timeout - * - * SYN_RCVD -> CLOSED timeout RST-> - * SYN_RCVD -> LISTEN ->RST - * SYN_RCVD -> ESTABLISHED ->ACK - * SYN_RCVD -> FINWAIT_1 close FIN-> - * - * ESTABLISHED -> FINWAIT_1 close FIN-> - * ESTABLISHED -> CLOSE_WAIT ->FIN ACK-> - * - * CLOSE_WAIT -> LAST_ACK close FIN-> - * - * LAST_ACK -> CLOSED ->ACK - * - * FINWAIT_1 -> CLOSING ->FIN ACK-> - * FINWAIT_1 -> FINWAIT_2 ->ACK - * FINWAIT_1 -> TIME_WAIT ->FIN+ACK ACK-> - * - * FINWAIT_2 -> TIME_WAIT ->FIN ACK-> - * - * CLOSING -> TIME_WAIT ->ACK - * - * TIME_WAIT -> CLOSED timeout (2*msl) - * - */ - -#include "sysdeps.h" -#include "main.h" - -#include - -#include "cpu_emulation.h" -#include "ws2tcpip.h" -#include "ether_windows.h" -#include "ether.h" -#include "prefs.h" -#include "router.h" -#include "router_types.h" -#include "dynsockets.h" -#include "iphelp.h" -#include "tcp.h" -#include "dump.h" -#include "mib/interfaces.h" -#include "ftp.h" - -#if DEBUG -#pragma optimize("",off) -#endif - -#include "debug.h" - -// If you need more, use multiple threads. -#define MAX_SOCKETS MAXIMUM_WAIT_OBJECTS - -// If true, always sends the PSH tcp flag with data. -// Otherwise only when a full buffer was received. -#define PUSH_ALWAYS 0 - -// In milliseconds. A TCP implementation should implement -// this dynamically, adapting the timeout value to match to the -// averaged packet round-trip time. -#define RESEND_TIMEOUT 750 - -// Just time out incoming connections after 5 secs if Mac has no time to reply -// No backlogs. -#define SYN_FLOOD_PROTECTION_TIMEOUT 5000 - -const int MAX_SEGMENT_SIZE = 1460; - -// Shorthands -#define ISSET(f,x) ( ((f) & (x)) != 0 ) -#define ISCLEAR(f,x) ( ((f) & (x)) == 0 ) - -// Local aliases -#define URG tcp_flags_URG -#define ACK tcp_flags_ACK -#define PSH tcp_flags_PSH -#define RST tcp_flags_RST -#define SYN tcp_flags_SYN -#define FIN tcp_flags_FIN - -// Local aliases -#define CLOSED tcp_state_closed -#define LISTEN tcp_state_listen -#define SYN_SENT tcp_state_syn_sent -#define SYN_RCVD tcp_state_syn_rcvd -#define ESTABLISHED tcp_state_established -#define CLOSE_WAIT tcp_state_close_wait -#define LAST_ACK tcp_state_last_ack -#define FINWAIT_1 tcp_state_finwait_1 -#define FINWAIT_2 tcp_state_finwait_2 -#define CLOSING tcp_state_closing -#define TIME_WAIT tcp_state_time_wait - -// For debugging only -static const char *_tcp_state_name[] = { - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RCVD", - "ESTABLISHED", - "CLOSE_WAIT", - "LAST_ACK", - "FINWAIT_1", - "FINWAIT_2", - "CLOSING", - "TIME_WAIT" -}; -#define STATENAME(i) _tcp_state_name[i] - -static CRITICAL_SECTION tcp_section; - -typedef struct { - SOCKET s; - int state; - - uint32 ip_src; // "source" is the mac, dest is the remote host, - uint32 ip_dest; // no matter who opened the connection. - uint16 src_port; // all in host byte order. - uint16 dest_port; - - struct sockaddr_in from; // remote host address, network byte order. - int from_len; - - // note: no true windows sliding, only one buffer. - WSABUF buffers_read[1]; // data from remote host to Mac - DWORD buffer_count_read; - DWORD bytes_received; - DWORD flags_read; - WSAOVERLAPPED overlapped_read; - - WSABUF buffers_write[1]; // data from Mac to remote host - DWORD buffer_count_write; - DWORD bytes_written; - DWORD flags_write; - WSAOVERLAPPED overlapped_write; - - bool remote_closed; // remote will not send any more data - bool accept_more_data_from_mac; // are we ready to accept more data from mac - - uint32 seq_in; // will ack this mac sequence number - uint32 seq_out; // next sequence number to mac (unless a resend is needed) - uint32 mac_ack; // mac has acked this byte count. can be used to determined when to send some more data - - uint32 bytes_to_send; // total send block size - uint32 bytes_remaining_to_send; // unsent byte count - - uint16 mac_window; // mac tcp receive window, slides according to the window principle - uint16 our_window; // not really used - uint16 mac_mss; // maximum segment size that mac reported at SYN handshaking - - // resend info - uint32 last_seq_out; // remember last packet seq number if a resend is needed - uint32 resend_timeout; // currently set t0 0.75 secs but not updated - uint32 stream_to_mac_stalled_until; // tick count indicating resend time - - DWORD time_wait; // do a graceful close after MSL*2 - DWORD msl; - - int child; - - WSAEVENT ev; // used to signal remote-initiated close and host-initiated connect. - - bool in_use; -} tcp_socket_t; - -static tcp_socket_t sockets[MAX_SOCKETS]; - -typedef struct { - SOCKET s; - uint16 port; - uint32 ip; - uint32 iface; - bool once; - int parent; - WSAEVENT ev; -} tcp_listening_socket_t; - -static tcp_listening_socket_t l_sockets[MAX_SOCKETS]; - -static void CALLBACK tcp_read_completion( - DWORD error, - DWORD bytes_read, - LPWSAOVERLAPPED lpOverlapped, - DWORD flags -); - -static void CALLBACK tcp_write_completion( - DWORD error, - DWORD bytes_read, - LPWSAOVERLAPPED lpOverlapped, - DWORD flags -); - -// socket utilities assume that the critical section has already been entered. -static void free_socket( const int t ) -{ - _WSAResetEvent( sockets[t].ev ); - if(sockets[t].s != INVALID_SOCKET) { - _closesocket( sockets[t].s ); - sockets[t].s = INVALID_SOCKET; - } - sockets[t].state = CLOSED; - sockets[t].stream_to_mac_stalled_until = 0; - sockets[t].in_use = false; - sockets[t].time_wait = 0; - - // if there was an attached listening socket (ftp), close it. - int lst = sockets[t].child; - if( lst >= 0 ) { - if(l_sockets[lst].s != INVALID_SOCKET) { - D(bug(" closing listening socket %d\r\n", lst)); - _closesocket( l_sockets[lst].s ); - l_sockets[lst].s = INVALID_SOCKET; - } - l_sockets[lst].port = 0; - l_sockets[lst].parent = -1; - } - sockets[t].child = -1; -} - -static int alloc_socket() -{ - static int last_allocated_socket = -1; - - int i = last_allocated_socket; - for( int j=0; j= MAX_SOCKETS ) i = 0; - if( !sockets[i].in_use ) { - D(bug("<%d> Socket allocated\r\n", i)); - - last_allocated_socket = i; - sockets[i].in_use = true; - - sockets[i].s = INVALID_SOCKET; - sockets[i].state = CLOSED; - sockets[i].remote_closed = false; - - sockets[i].accept_more_data_from_mac = false; - - sockets[i].ip_src = sockets[i].ip_dest = 0; - // sockets[i].src_port = sockets[i].dest_port = 0; - - memset( &sockets[i].overlapped_read, 0, sizeof(sockets[i].overlapped_read) ); - sockets[i].overlapped_read.hEvent = (HANDLE)i; - memset( &sockets[i].overlapped_write, 0, sizeof(sockets[i].overlapped_write) ); - sockets[i].overlapped_write.hEvent = (HANDLE)i; - - sockets[i].bytes_received = 0; - sockets[i].bytes_written = 0; - - sockets[i].flags_read = 0; - sockets[i].flags_write = 0; - - // sockets[i].from_len = sizeof(struct sockaddr_in); - // memset( &sockets[i].from, 0, sizeof(sockets[i].from) ); - // sockets[i].from.sin_family = AF_INET; - - sockets[i].buffer_count_read = 1; - sockets[i].buffers_read[0].len = MAX_SEGMENT_SIZE; - if(!sockets[i].buffers_read[0].buf) { - sockets[i].buffers_read[0].buf = new char [sockets[i].buffers_read[0].len]; - } - - sockets[i].buffer_count_write = 1; - sockets[i].buffers_write[0].len = MAX_SEGMENT_SIZE; - if(!sockets[i].buffers_write[0].buf) { - sockets[i].buffers_write[0].buf = new char [sockets[i].buffers_write[0].len]; - } - - sockets[i].mac_window = MAX_SEGMENT_SIZE; // updated for all mac datagrams - sockets[i].our_window = MAX_SEGMENT_SIZE; // should use about 8-16 kB, really - sockets[i].mac_mss = 0; // not known yet - - sockets[i].time_wait = 0; - sockets[i].msl = 5000L; // The round-trip time can be hard to estimate. - - sockets[i].seq_in = 0; - sockets[i].seq_out = 0x00000001; - sockets[i].mac_ack = 0; - sockets[i].stream_to_mac_stalled_until = 0; - - sockets[i].resend_timeout = RESEND_TIMEOUT; - - sockets[i].child = -1; - - break; - } - } - if(i == MAX_SOCKETS) { - D(bug("Out of free sockets\r\n")); - i = -1; - } - return i; -} - -static int alloc_new_socket( const uint16 src_port, const uint16 dest_port, const uint32 ip_dest ) -{ - int t = alloc_socket(); - - if(t >= 0) { - sockets[t].s = _socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); - if(sockets[t].s == INVALID_SOCKET) { - free_socket( t ); - t = -1; - } else { - sockets[t].src_port = src_port; - sockets[t].dest_port = dest_port; - - sockets[t].from_len = sizeof(sockets[t].from); - memset( &sockets[t].from, 0, sockets[t].from_len ); - sockets[t].from.sin_family = AF_INET; - sockets[t].from.sin_port = htons(dest_port); - sockets[t].from.sin_addr.s_addr = htonl(ip_dest); - - struct sockaddr_in to; - memset( &to, 0, sizeof(to) ); - to.sin_family = AF_INET; - - if( _bind ( sockets[t].s, (const struct sockaddr *)&to, sizeof(to) ) == 0 ) { - D(bug("<%d> socket bound\r\n", t)); - } else { - if( _WSAGetLastError() == WSAEINPROGRESS ) { - D(bug("<%d> bind: a blocking call is in progress.\r\n", t)); - } else { - D(bug("<%d> bind failed with error code %d\r\n", t, _WSAGetLastError())); - } - free_socket( t ); - t = -1; - } - } - } - return t; -} - -static int get_socket_index( const uint16 src_port, const uint16 dest_port ) -{ - for( int i=0; i= 0 ) { - if( sockets[i].s == INVALID_SOCKET ) { - D(bug("find_socket reusing slot %d...\r\n", i)); - sockets[i].in_use = false; - } else { - D(bug("find_socket forcing close %d...\r\n", i)); - free_socket( i ); - } - i = -1; - } - } - - D(bug("<%d> find_socket(%d,%d): %s\r\n", i, src_port, dest_port, i>=0 ? "found" : "not found")); - - return i; -} - -static int alloc_listen_socket( const uint16 port, const uint32 ip, const uint32 iface, const bool once ) -{ - static int last_allocated_socket = -1; - - int i = last_allocated_socket; - - for( int j=0; j= MAX_SOCKETS ) i = 0; - if( l_sockets[i].port == 0 ) { - D(bug("[%d] Slot allocated for listening port %d\r\n", i, port)); - l_sockets[i].port = port; - l_sockets[i].ip = ip; - l_sockets[i].iface = iface; - l_sockets[i].once = once; - l_sockets[i].parent = -1; - last_allocated_socket = i; - _WSAResetEvent( l_sockets[i].ev ); - return i; - } - } - return -1; -} - -static void tcp_start_listen( const int i ) -{ - if( l_sockets[i].port ) { - uint32 iface = l_sockets[i].iface; - - D(bug("[%d] binding to interface 0x%08X\r\n", i, iface)); - - l_sockets[i].s = _socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); - if(l_sockets[i].s != INVALID_SOCKET) { - struct sockaddr_in to; - memset( &to, 0, sizeof(to) ); - to.sin_family = AF_INET; - to.sin_port = htons( l_sockets[i].port ); - to.sin_addr.s_addr = htonl( iface ); - - if( _bind ( l_sockets[i].s, (const struct sockaddr *)&to, sizeof(to) ) == 0 ) - { - D(bug("[%d] socket bound to port %d on interface 0x%08X\r\n", i, l_sockets[i].port, iface)); - if( _listen( l_sockets[i].s, SOMAXCONN ) == SOCKET_ERROR ) { - D(bug("[%d] listen() failed with error code %d\r\n", i, _WSAGetLastError())); - } else { - D(bug("[%d] listening to port %d\r\n", i, l_sockets[i].port)); - _WSAResetEvent( l_sockets[i].ev ); - if( SOCKET_ERROR == _WSAEventSelect( l_sockets[i].s, l_sockets[i].ev, FD_ACCEPT ) ) { - D(bug("[%d] WSAEventSelect() failed with error code %d\r\n", i, _WSAGetLastError())); - } - } - } else { - D(bug("[%d] bind to port %d failed with error code %d\r\n", i, l_sockets[i].port, _WSAGetLastError())); - } - } else { - D(bug("[%d] could not create a socket for port %d, error = %d\r\n", i, l_sockets[i].port, _WSAGetLastError())); - } - } -} - -static void set_ttl( const int t, const uint8 ttl ) -{ - int _ttl = ttl; // defensive programming, I know VCx - - if(_setsockopt( sockets[t].s, IPPROTO_IP, IP_TTL, (const char *)&_ttl, sizeof(int) ) == SOCKET_ERROR ) { - D(bug("<%d> could not set ttl to %d, error=%d\r\n", t, ttl, _WSAGetLastError())); - } else { - D(bug("<%d> ttl set to %d.\r\n", t, ttl)); - } -} - -static void tcp_reply( const int flags, const int t ) -{ - int tcp_size = sizeof(tcp_t); - - tcp_t *tcp = (tcp_t *)malloc( tcp_size ); - if(tcp) { - memcpy( tcp->ip.mac.dest, ether_addr, 6 ); - memcpy( tcp->ip.mac.src, router_mac_addr, 6 ); - tcp->ip.mac.type = htons(mac_type_ip4); - - tcp->ip.version = 4; - tcp->ip.header_len = 5; - tcp->ip.tos = 0; - tcp->ip.total_len = htons(tcp_size - sizeof(mac_t)); - tcp->ip.ident = htons(next_ip_ident_number++); - tcp->ip.flags_n_frag_offset = 0; - tcp->ip.ttl = 128; - tcp->ip.proto = ip_proto_tcp; - tcp->ip.src = htonl(sockets[t].ip_dest); - tcp->ip.dest = htonl(sockets[t].ip_src); - make_ip4_checksum( (ip_t *)tcp ); - - D(bug("<%d> Reply: Seq=%d, Ack=%d\r\n", t, sockets[t].seq_out, sockets[t].seq_in)); - - tcp->src_port = htons(sockets[t].dest_port); - tcp->dest_port = htons(sockets[t].src_port); - tcp->seq = htonl(sockets[t].seq_out); - tcp->ack = htonl(sockets[t].seq_in); - tcp->header_len = (uint8)( 20 << 2 ); - tcp->flags = flags; - tcp->window = htons( sockets[t].our_window ); - tcp->urgent_ptr = 0; - make_tcp_checksum( tcp, tcp_size ); - - // dump_bytes( (uint8 *)tcp, tcp_size ); - - enqueue_packet( (uint8 *)tcp, tcp_size ); - free(tcp); - } -} - -static bool has_mac_read_space( const int t ) -{ - uint32 pending_bytes = sockets[t].seq_out - sockets[t].mac_ack; - uint32 mac_can_accept_bytes = sockets[t].mac_window - pending_bytes; - - D(bug("<%d> mac_can_accept_bytes = %d\r\n", t, mac_can_accept_bytes)); - - // Modified Nagle, effectively disabling window sliding (which I don't support anyway): - return pending_bytes == 0; - - // Use more of window bandwidth - // Enabling this would require that the buffers seq numbers are stored somewhere - // return mac_can_accept_bytes >= sockets[t].buffers_read[0].len; -} - -static bool b_recfrom( const int t ) -{ - bool result; - - if( !has_mac_read_space(t) ) { - D(bug("<%d> read stalled, mac cannot accept any more data\r\n", t)); - - sockets[t].stream_to_mac_stalled_until = GetTickCount() + sockets[t].resend_timeout; - return true; - } - - int ret = _WSARecv( - sockets[t].s, - sockets[t].buffers_read, - sockets[t].buffer_count_read, - &sockets[t].bytes_received, - &sockets[t].flags_read, - &sockets[t].overlapped_read, - tcp_read_completion - ); - - if(ret == SOCKET_ERROR) { - int socket_error = _WSAGetLastError(); - if(socket_error == WSA_IO_PENDING) { - D(bug("<%d> WSARecv() i/o pending\r\n", t)); - result = true; - } else { - D(bug("<%d> WSARecv() returned error %d\r\n", t, socket_error)); - result = false; - } - } else /*if(ret == 0) */ { - D(bug("<%d> WSARecv() ok\r\n", t)); - // Completion routine call is already scheduled. - result = true; - } - return result; -} - -static bool b_send( const int t ) -{ - int ret = _WSASend( - sockets[t].s, - sockets[t].buffers_write, - sockets[t].buffer_count_write, - &sockets[t].bytes_written, - sockets[t].flags_write, - &sockets[t].overlapped_write, - tcp_write_completion - ); - - bool result; - if(ret == SOCKET_ERROR) { - int socket_error = _WSAGetLastError(); - if(socket_error == WSA_IO_PENDING) { - D(bug("<%d> WSASend() i/o pending\r\n", t)); - result = true; - } else { - D(bug("<%d> WSASend() returned %d\r\n", t, socket_error)); - result = false; - } - } else /*if(ret == 0) */ { - D(bug("<%d> WSASend() ok\r\n", t)); - // Completion routine call is already scheduled. - result = true; - } - return result; -} - -static void send_buffer( const int t, const bool resending ) -{ - if(resending) { - if(sockets[t].last_seq_out == 0) { - D(bug("<%d> resend failure\r\n", t )); - return; - } - sockets[t].seq_out = sockets[t].last_seq_out; - } else { - sockets[t].last_seq_out = sockets[t].seq_out; - } - - D(bug("<%d> %s data to Mac: Seq=%d, Ack=%d\r\n", t, (resending ? "resending" : "sending"), sockets[t].seq_out, sockets[t].seq_in)); - - uint32 bytes_read = sockets[t].bytes_received; - - if( sockets[t].mac_mss && bytes_read > sockets[t].mac_mss ) { - D(bug("<%d> impossible: %d bytes to send, Mac mss is only %d\r\n", t, sockets[t].mac_mss && bytes_read, sockets[t].mac_mss)); - } - - int tcp_size = sizeof(tcp_t) + bytes_read; - - tcp_t *tcp = (tcp_t *)malloc( tcp_size ); - if(tcp) { - // Build MAC - // memcpy( tcp->ip.mac.dest, sockets[t].mac_src, 6 ); - memcpy( tcp->ip.mac.dest, ether_addr, 6 ); - memcpy( tcp->ip.mac.src, router_mac_addr, 6 ); - tcp->ip.mac.type = htons(mac_type_ip4); - - // Build IP - tcp->ip.version = 4; - tcp->ip.header_len = 5; - tcp->ip.tos = 0; - tcp->ip.total_len = htons(sizeof(tcp_t) - sizeof(mac_t) + bytes_read); // no options - tcp->ip.ident = htons(next_ip_ident_number++); - tcp->ip.flags_n_frag_offset = 0; - tcp->ip.ttl = 128; // one hop actually! - tcp->ip.proto = ip_proto_tcp; - tcp->ip.src = htonl(sockets[t].ip_dest); - tcp->ip.dest = htonl(sockets[t].ip_src); - make_ip4_checksum( (ip_t *)tcp ); - - // Copy payload (used by tcp checksum) - memcpy( (char *)tcp + sizeof(tcp_t), sockets[t].buffers_read[0].buf, bytes_read ); - - // Build tcp - tcp->src_port = htons(sockets[t].dest_port); - tcp->dest_port = htons(sockets[t].src_port); - - tcp->seq = htonl(sockets[t].seq_out); - tcp->ack = htonl(sockets[t].seq_in); - - tcp->header_len = (uint8)( 20 << 2 ); -#if PUSH_ALWAYS - tcp->flags = ACK|PSH; -#else - tcp->flags = (bytes_read == MAX_SEGMENT_SIZE) ? ACK : (ACK|PSH); -#endif - tcp->window = htons( sockets[t].our_window ); - tcp->urgent_ptr = 0; - make_tcp_checksum( tcp, tcp_size ); - - sockets[t].seq_out += bytes_read; - - // dump_bytes( (uint8 *)tcp, tcp_size ); - - enqueue_packet( (uint8 *)tcp, tcp_size ); - free(tcp); - } -} - -static void CALLBACK tcp_read_completion( - DWORD error, - DWORD bytes_read, - LPWSAOVERLAPPED lpOverlapped, - DWORD flags -) -{ - EnterCriticalSection( &tcp_section ); - - const int t = (int)lpOverlapped->hEvent; - - sockets[t].bytes_received = bytes_read; - - D(bug("<%d> tcp_read_completion(error=%d, bytes_read=%d)\r\n", t, error, bytes_read)); - - D(bug("<%d> tcp_read_completion() start, old state = %s\r\n", t, STATENAME(sockets[t].state))); - - if(!sockets[t].in_use) { - D(bug("<%d> ignoring canceled read\r\n", t)); - } else { - if( error != 0 ) { - D(bug("<%d> resetting after read error\r\n", t)); - tcp_reply( RST, t ); - free_socket(t); - } else { - if(bytes_read == 0) { - _closesocket( sockets[t].s ); - sockets[t].s = INVALID_SOCKET; - } else if( bytes_read > 0) { - send_buffer( t, false ); - } - - switch( sockets[t].state ) { - case SYN_RCVD: - if( bytes_read == 0 ) { - D(bug("<%d> Closing: SYN_RCVD -> FINWAIT_1\r\n", t)); - tcp_reply( ACK|FIN, t ); - sockets[t].seq_out++; - sockets[t].state = FINWAIT_1; - } - break; - case ESTABLISHED: - if( bytes_read == 0 ) { - D(bug("<%d> Closing: ESTABLISHED -> FINWAIT_1\r\n", t)); - tcp_reply( ACK|FIN, t ); - sockets[t].seq_out++; - sockets[t].state = FINWAIT_1; - } - break; - case LISTEN: - tcp_reply( SYN, t ); - sockets[t].seq_out++; - sockets[t].state = SYN_SENT; - sockets[t].time_wait = GetTickCount() + SYN_FLOOD_PROTECTION_TIMEOUT; - D(bug("<%d> LISTEN -> SYN_SENT\r\n", t)); - break; - case CLOSE_WAIT: - if( bytes_read == 0) { - tcp_reply( ACK|FIN, t ); - sockets[t].seq_out++; - sockets[t].state = LAST_ACK; - D(bug("<%d> Closing: CLOSE_WAIT -> LAST_ACK\r\n", t)); - if(sockets[t].remote_closed) { - // Just in case that mac gets out of sync. - _closesocket(sockets[t].s); - sockets[t].s = INVALID_SOCKET; - } - } - break; - default: - break; - } - - if(!is_router_shutting_down && sockets[t].s != INVALID_SOCKET) { - if(sockets[t].state != LISTEN) { - b_recfrom(t); - } - } - } - } - - LeaveCriticalSection( &tcp_section ); -} - -static void CALLBACK tcp_write_completion( - DWORD error, - DWORD bytes_written, - LPWSAOVERLAPPED lpOverlapped, - DWORD flags -) -{ - EnterCriticalSection( &tcp_section ); - - const int t = (int)lpOverlapped->hEvent; - - sockets[t].bytes_written = bytes_written; - sockets[t].bytes_remaining_to_send -= bytes_written; - - D(bug("<%d> tcp_write_completion(error=%d, bytes_written=%d)\r\n", t, error, bytes_written)); - - if(!sockets[t].in_use) { - D(bug("<%d> ignoring canceled write\r\n", t)); - } else { - if(is_router_shutting_down || sockets[t].s == INVALID_SOCKET) { - D(bug("<%d> is not alive for sending.\r\n", t)); - } else { - if( sockets[t].bytes_remaining_to_send <= 0 ) { - D(bug("<%d> all data sent, accepting some more.\r\n", t)); - sockets[t].seq_in += sockets[t].bytes_to_send; - sockets[t].bytes_to_send = sockets[t].bytes_remaining_to_send = 0; // superfluous - tcp_reply( ACK, t ); - sockets[t].accept_more_data_from_mac = true; - } else { - D(bug("<%d> %d bytes (of %d total) remaining, sending.\r\n", t, sockets[t].bytes_remaining_to_send, sockets[t].bytes_to_send)); - sockets[t].buffers_write[0].len = sockets[t].bytes_remaining_to_send; - char *p = sockets[t].buffers_write[0].buf; - memmove( p, &p[bytes_written], sockets[t].bytes_remaining_to_send ); - if(!b_send(t)) { - } else { - } - } - } - } - - LeaveCriticalSection( &tcp_section ); -} - -static void tcp_connect_callback( const int t ) -{ - D(bug("<%d> tcp_connect_callback() start, old state = %s\r\n", t, STATENAME(sockets[t].state))); - - switch( sockets[t].state ) { - case LISTEN: - tcp_reply( SYN|ACK, t ); - sockets[t].seq_out++; - sockets[t].state = SYN_RCVD; - D(bug("<%d> Connect: LISTEN -> SYN_RCVD\r\n", t)); - break; - default: - break; - } - D(bug("<%d> tcp_connect_callback() end, new state = %s\r\n", t, STATENAME(sockets[t].state))); -} - -static void tcp_accept_callback( const int lst ) -{ - D(bug("[%d] tcp_accept_callback()\r\n", lst)); - - struct sockaddr_in to; - memset( &to, 0, sizeof(to) ); - to.sin_family = AF_INET; - int tolen = sizeof(to); - - SOCKET s = _accept( l_sockets[lst].s, (struct sockaddr *)&to, &tolen ); - if( s == INVALID_SOCKET ) { - D(bug("[%d] connection not accepted, error code %d\r\n", lst, _WSAGetLastError())); - } else { - _WSAEventSelect( s, 0, 0 ); - - uint16 src_port = l_sockets[lst].port; - uint16 dest_port = ntohs(to.sin_port); - uint32 ip_dest = ntohl(to.sin_addr.s_addr); - - D(bug("[%d] connection accepted, local port:%d, remote %s:%d\r\n", lst, src_port, _inet_ntoa(to.sin_addr), dest_port)); - - if( l_sockets[lst].ip != 0 && l_sockets[lst].ip != ip_dest ) { - _closesocket( s ); - D(bug("[%d] authorization failure. connection closed.\r\n", lst )); - } else { - int t = alloc_new_socket( src_port, dest_port, ip_dest ); - if( t < 0 ) { - D(bug("<%d> out of slot space, connection dropped\r\n", t )); - free_socket(t); - } else { - sockets[t].s = s; - sockets[t].state = LISTEN; - sockets[t].src_port = src_port; - sockets[t].dest_port = dest_port; - sockets[t].ip_src = macos_ip_address; - sockets[t].ip_dest = ip_dest; - - sockets[t].seq_out = 0x00000001; - sockets[t].seq_in = 0; // not known yet - sockets[t].mac_ack = sockets[t].seq_out; // zero out pending bytes - - tcp_reply( SYN, t ); - sockets[t].seq_out++; - sockets[t].state = SYN_SENT; - sockets[t].time_wait = GetTickCount() + SYN_FLOOD_PROTECTION_TIMEOUT; - D(bug("<%d> Connect: LISTEN -> SYN_SENT\r\n", t)); - - _WSAResetEvent( sockets[t].ev ); - if( SOCKET_ERROR == _WSAEventSelect( sockets[t].s, sockets[t].ev, FD_CLOSE ) ) { - D(bug("<%d> WSAEventSelect() failed with error code %d\r\n", t, _WSAGetLastError())); - } - - // No data from the remote host is needed until the connection is established. - // So don't initiate read yet. - } - } - } -} - -/* - MSS is the only option I care about, and since I'm on ethernet - I already pretty much know everything needed. - - AFAIK window scaling is not in effect unless both parties specify it, - and I'm not doing it. -*/ -static void process_options( const int t, const uint8 *opt, int len, uint32 &mss ) -{ - mss = 0; - - while( len > 0 ) { - switch( *opt ) { - case 0: // End of Option List - D(bug("<%d> End of Option List\r\n", t)); - len = 0; - break; - case 1: // No-Operation - D(bug("<%d> No-Operation\r\n", t)); - len--; - opt++; - break; - case 2: // Maximum Segment Size - { - mss = ntohs( *((uint16 *)&opt[2]) ); - D(bug("<%d> Maximum Segment Size = %d\r\n", t, mss)); - len -= 4; - opt += 4; - } - break; - case 3: // Window Scale - { - int wscale = opt[2]; - D(bug("<%d> Window Scale = %d\r\n", t, (int)wscale)); - len -= 3; - opt += 3; - } - break; - case 4: // Sack-Permitted - D(bug("<%d> Sack-Permitted option is set\r\n", t)); - len -= 2; - opt += 2; - break; - case 5: // Sack - { - int sack_len = opt[1]; - int hf = (sack_len-2) / 4; - D(bug("<%d> Sack, %d half-blocks\r\n", t, hf)); - len -= sack_len; - opt += sack_len; - } - break; - case 8: // Time Stamps - { - int valve = ntohl( *((uint32 *)&opt[2]) ); - int ereply = ntohl( *((uint32 *)&opt[6]) ); - D(bug("<%d> Time Stamps, TS valve = 0x%X, TS echo reply = 0x%X\r\n", t, valve, ereply)); - len -= 10; - opt += 10; - } - break; - default: - D(bug("<%d> Unknown tcp header option 0x%02x, breaking out\r\n", t, (int)*opt)); - len = 0; - break; - } - } -} - -void write_tcp( tcp_t *tcp, int len ) -{ - if(len < sizeof(tcp_t)) { - D(bug("<%d> Too small tcp packet(%d) on unknown slot, dropped\r\n", -1, len)); - return; - } - uint16 src_port = ntohs(tcp->src_port); - uint16 dest_port = ntohs(tcp->dest_port); - - BOOL ok = true; - BOOL handle_data = false; - BOOL initiate_read = false; - - EnterCriticalSection( &tcp_section ); - - int t = find_socket( src_port, dest_port ); - - if(t < 0) { - t = alloc_new_socket( src_port, dest_port, ntohl(tcp->ip.dest) ); - ok = t >= 0; - } - - if(ok) { - D(bug("<%d> write_tcp %d bytes from port %d to port %d\r\n", t, len, src_port, dest_port)); - } else { - D(bug("<%d> FAILED write_tcp %d bytes from port %d to port %d\r\n", t, len, src_port, dest_port)); - } - - if( ok && ISSET(tcp->flags,RST) ) { - D(bug("<%d> RST set, resetting socket\r\n", t)); - if( sockets[t].s != INVALID_SOCKET ) { - D(bug("<%d> doing an extra shutdown (ie4)\r\n", t)); - _shutdown( sockets[t].s, SD_BOTH ); - } - free_socket( t ); - ok = false; - } - - if(ok) { - D(bug("<%d> State machine start = %s\r\n", t, STATENAME(sockets[t].state))); - - // always update receive window - sockets[t].mac_window = ntohs(tcp->window); - - int header_len = tcp->header_len >> 2; - int option_bytes = header_len - 20; - char *data = (char *)tcp + sizeof(tcp_t) + option_bytes; - int dlen = len - sizeof(tcp_t) - option_bytes; - - if( !ISSET(tcp->flags,ACK) ) { - D(bug("<%d> ACK not set\r\n", t)); - } - if( ISSET(tcp->flags,SYN) ) { - D(bug("<%d> SYN set\r\n", t)); - - // Note that some options are valid even if there is no SYN. - // I don't care about those however. - - uint32 new_mss; - process_options( t, (uint8 *)data - option_bytes, option_bytes, new_mss ); - if(new_mss) { - sockets[t].mac_mss = (int)new_mss; - if( new_mss < sockets[t].buffers_read[0].len ) { - sockets[t].buffers_read[0].len = new_mss; - } - D(bug("<%d> Max segment size set to %d\r\n", t, new_mss)); - } - } - if( ISSET(tcp->flags,FIN) ) { - D(bug("<%d> FIN set\r\n", t)); - } - - // The sequence number Mac expects to see next time. - sockets[t].mac_ack = ntohl(tcp->ack); - - D(bug("<%d> From Mac: Seq=%d, Ack=%d, window=%d, router Seq=%d\r\n", t, ntohl(tcp->seq), sockets[t].mac_ack, sockets[t].mac_window, sockets[t].seq_out)); - - if( sockets[t].stream_to_mac_stalled_until && - sockets[t].mac_ack == sockets[t].seq_out && - (sockets[t].state == ESTABLISHED || sockets[t].state == CLOSE_WAIT) ) - { - if( has_mac_read_space(t) ) { - initiate_read = true; - sockets[t].stream_to_mac_stalled_until = 0; - D(bug("<%d> read resumed, mac can accept more data\r\n", t)); - } - } - - switch( sockets[t].state ) { - case CLOSED: - sockets[t].src_port = src_port; - sockets[t].dest_port = dest_port; - sockets[t].ip_src = ntohl(tcp->ip.src); - sockets[t].ip_dest = ntohl(tcp->ip.dest); - - if( ISSET(tcp->flags,SYN) ) { - - sockets[t].seq_out = 0x00000001; - sockets[t].seq_in = ntohl(tcp->seq) + 1; - - _WSAResetEvent( sockets[t].ev ); - if( SOCKET_ERROR == _WSAEventSelect( sockets[t].s, sockets[t].ev, FD_CONNECT | FD_CLOSE ) ) { - D(bug("<%d> WSAEventSelect() failed with error code %d\r\n", t, _WSAGetLastError())); - } - - D(bug("<%d> connecting local port %d to remote %s:%d\r\n", t, src_port, _inet_ntoa(sockets[t].from.sin_addr), dest_port)); - - sockets[t].state = LISTEN; - if( _WSAConnect( - sockets[t].s, - (const struct sockaddr *)&sockets[t].from, - sockets[t].from_len, - NULL, NULL, - NULL, NULL - ) == SOCKET_ERROR ) - { - int connect_error = _WSAGetLastError(); - if( connect_error == WSAEWOULDBLOCK ) { - D(bug("<%d> WSAConnect() i/o pending.\r\n", t)); - } else { - D(bug("<%d> WSAConnect() failed with error %d.\r\n", t, connect_error)); - } - } else { - D(bug("<%d> WSAConnect() ok.\r\n", t)); - } - } else { - if( ISSET(tcp->flags,FIN) ) { - D(bug("<%d> No SYN but FIN on a closed socket.\r\n", t)); - free_socket(t); - } else { - D(bug("<%d> No SYN on a closed socket. resetting.\r\n", t)); - free_socket(t); - } - } - break; - case LISTEN: - // handled in connect callback - break; - case SYN_SENT: - if( ISSET(tcp->flags,SYN) && ISSET(tcp->flags,ACK) ) { - sockets[t].seq_in = ntohl(tcp->seq) + 1; - tcp_reply( ACK, t ); - sockets[t].state = ESTABLISHED; - initiate_read = true; - sockets[t].accept_more_data_from_mac = true; - sockets[t].time_wait = 0; - } else if( ISSET(tcp->flags,SYN) ) { - sockets[t].seq_in = ntohl(tcp->seq) + 1; - tcp_reply( ACK|SYN, t ); - sockets[t].seq_out++; - sockets[t].state = SYN_RCVD; - sockets[t].time_wait = 0; - } else if( ISSET(tcp->flags,ACK) ) { - // What was the bright idea here. - D(bug("<%d> State is SYN_SENT, but got only ACK from Mac??\r\n", t)); - sockets[t].state = FINWAIT_2; - sockets[t].time_wait = 0; - } - break; - case SYN_RCVD: - if( ISSET(tcp->flags,ACK) ) { - sockets[t].state = ESTABLISHED; - handle_data = true; - initiate_read = true; - sockets[t].accept_more_data_from_mac = true; - } - break; - case ESTABLISHED: - if( ISSET(tcp->flags,FIN) ) { - sockets[t].seq_in++; - tcp_reply( ACK, t ); - _shutdown( sockets[t].s, SD_SEND ); - sockets[t].state = CLOSE_WAIT; - } - handle_data = true; - break; - case CLOSE_WAIT: - // handled in tcp_read_completion - break; - case LAST_ACK: - if( ISSET(tcp->flags,ACK) ) { - D(bug("<%d> LAST_ACK received, socket closed\r\n", t)); - free_socket( t ); - } - break; - case FINWAIT_1: - if( ISSET(tcp->flags,FIN) && ISSET(tcp->flags,ACK) ) { - sockets[t].seq_in++; - tcp_reply( ACK, t ); - if(sockets[t].remote_closed) { - _closesocket(sockets[t].s); - sockets[t].s = INVALID_SOCKET; - } else { - _shutdown( sockets[t].s, SD_SEND ); - } - sockets[t].state = TIME_WAIT; - sockets[t].time_wait = GetTickCount() + 2 * sockets[t].msl; - } else if( ISSET(tcp->flags,FIN) ) { - sockets[t].seq_in++; - tcp_reply( ACK, t ); - if(sockets[t].remote_closed) { - _closesocket(sockets[t].s); - sockets[t].s = INVALID_SOCKET; - } else { - _shutdown( sockets[t].s, SD_SEND ); - } - sockets[t].state = CLOSING; - } else if( ISSET(tcp->flags,ACK) ) { - sockets[t].state = FINWAIT_2; - } - break; - case FINWAIT_2: - if( ISSET(tcp->flags,FIN) ) { - sockets[t].seq_in++; - tcp_reply( ACK, t ); - if(sockets[t].remote_closed) { - _closesocket(sockets[t].s); - sockets[t].s = INVALID_SOCKET; - } else { - _shutdown( sockets[t].s, SD_SEND ); - } - sockets[t].state = TIME_WAIT; - sockets[t].time_wait = GetTickCount() + 2 * sockets[t].msl; - } - break; - case CLOSING: - if( ISSET(tcp->flags,ACK) ) { - sockets[t].state = TIME_WAIT; - sockets[t].time_wait = GetTickCount() + 2 * sockets[t].msl; - } - break; - case TIME_WAIT: - // Catching stray packets: wait MSL * 2 seconds, -> CLOSED - // Timer already set since we might not get here at all. - // I'm using exceptionally low MSL value (5 secs). - D(bug("<%d> time wait, datagram discarded\r\n", t)); - break; - } - - // The "t" descriptor may already be freed. However, it's safe - // to peek the state value inside the critical section. - D(bug("<%d> State machine end = %s\r\n", t, STATENAME(sockets[t].state))); - - D(bug("<%d> handle_data=%d, initiate_read=%d\r\n", t, handle_data, initiate_read)); - - if( handle_data && dlen && sockets[t].accept_more_data_from_mac ) { - if( sockets[t].seq_in != ntohl(tcp->seq) ) { - D(bug("<%d> dropping duplicate datagram seq=%d, expected=%d\r\n", t, ntohl(tcp->seq), sockets[t].seq_in)); - } else { - set_ttl( t, tcp->ip.ttl ); - - struct sockaddr_in to; - memset( &to, 0, sizeof(to) ); - to.sin_family = AF_INET; - to.sin_port = tcp->dest_port; - to.sin_addr.s_addr = tcp->ip.dest; - - D(bug("<%d> sending %d bytes to remote host\r\n", t, dlen)); - - sockets[t].accept_more_data_from_mac = false; - - if( dlen > MAX_SEGMENT_SIZE ) { - D(bug("<%d> IMPOSSIBLE: b_send() dropped %d bytes! \r\n", t, dlen-MAX_SEGMENT_SIZE)); - dlen = MAX_SEGMENT_SIZE; - } - - memcpy( sockets[t].buffers_write[0].buf, data, dlen ); - - sockets[t].buffers_write[0].len = dlen; - sockets[t].bytes_remaining_to_send = dlen; - sockets[t].bytes_to_send = dlen; - - bool send_now = false; - if( ISSET(tcp->flags,PSH) ) { - send_now = true; - } else { - // todo -- delayed send - send_now = true; - } - - if(send_now) { - - // Patch ftp server or client address if needed. - - int lst = 1; - bool is_pasv; - uint16 ftp_data_port = 0; - - if(ftp_is_ftp_port(sockets[t].src_port)) { - // Local ftp server may be entering to passive mode. - is_pasv = true; - ftp_parse_port_command( - sockets[t].buffers_write[0].buf, - dlen, - ftp_data_port, - is_pasv - ); - } else if(ftp_is_ftp_port(sockets[t].dest_port)) { - // Local ftp client may be using port command. - is_pasv = false; - ftp_parse_port_command( - sockets[t].buffers_write[0].buf, - dlen, - ftp_data_port, - is_pasv - ); - } - - if(ftp_data_port) { - D(bug("<%d> ftp %s command detected, port %d\r\n", t, (is_pasv ? "SERVER PASV REPLY" : "CLIENT PORT"), ftp_data_port )); - - // Note: for security reasons, only allow incoming connection from sockets[t].ip_dest - lst = alloc_listen_socket( ftp_data_port, sockets[t].ip_dest, 0/*iface*/, true ); - - if(lst < 0) { - D(bug("<%d> no more free slots\r\n", t)); - } else { - // First start listening (need to know the local name later) - tcp_start_listen( lst ); - - // When t is closed, lst must be closed too. - sockets[t].child = lst; - l_sockets[lst].parent = t; - - // Find out the local name - struct sockaddr_in name; - int namelen = sizeof(name); - memset( &name, 0, sizeof(name) ); - if( _getsockname( sockets[t].s, (struct sockaddr *)&name, &namelen ) == SOCKET_ERROR ) { - D(bug("_getsockname() failed, error=%d\r\n", _WSAGetLastError() )); - } - - ftp_modify_port_command( - sockets[t].buffers_write[0].buf, - dlen, - MAX_SEGMENT_SIZE, - ntohl(name.sin_addr.s_addr), - ftp_data_port, - is_pasv - ); - - sockets[t].buffers_write[0].len = dlen; - sockets[t].bytes_remaining_to_send = dlen; - // Do not change "bytes_to_send" field as it is used for ack calculation - } - } // end of ftp patch - - if(!b_send(t)) { - // on error, close the ftp data listening socket if one was created - if(lst >= 0) { - D(bug("[%d] closing listening port %d after write error\r\n", t, l_sockets[lst].port)); - _closesocket( l_sockets[lst].s ); - l_sockets[lst].s = INVALID_SOCKET; - l_sockets[lst].port = 0; - l_sockets[lst].ip = 0; - l_sockets[lst].parent = -1; - sockets[t].child = -1; - } - } - } - } - } - - if(initiate_read) { - if(!b_recfrom(t)) { - // post icmp error message - } - } - } - - LeaveCriticalSection( &tcp_section ); -} - -/* - - Dispatch remote close and connect events. - - Expire time-waits. - - Handle resend timeouts. -*/ -static unsigned int WINAPI tcp_connect_close_thread(void *arg) -{ - WSAEVENT wait_handles[MAX_SOCKETS]; - - for( int i=0; i= WAIT_OBJECT_0 && ret < WAIT_OBJECT_0 + MAX_SOCKETS ) { - const int t = ret - WAIT_OBJECT_0; - - D(bug("<%d> Event %d\r\n", t, ret)); - - if(sockets[t].in_use) { - WSANETWORKEVENTS what; - - if( _WSAEnumNetworkEvents( sockets[t].s, sockets[t].ev, &what ) != SOCKET_ERROR ) { - if( what.lNetworkEvents & FD_CONNECT ) { - if( what.iErrorCode[FD_CONNECT_BIT] == 0 ) { - D(bug("<%d> Connect ok\r\n", t)); - tcp_connect_callback(t); - } else { - D(bug("<%d> Connect error=%d\r\n", t, what.iErrorCode[FD_CONNECT_BIT])); - // Post icmp error - } - } else if( what.lNetworkEvents & FD_CLOSE ) { - if( what.iErrorCode[FD_CLOSE_BIT] == 0 ) { - D(bug("<%d> graceful close, state = %s\r\n", t, STATENAME(sockets[t].state))); - } else { - D(bug("<%d> abortive close, state = %s, code=%d\r\n", t, STATENAME(sockets[t].state), what.iErrorCode[FD_CLOSE_BIT])); - } - sockets[t].remote_closed = true; - } - } else { - int err = _WSAGetLastError(); - if( err == WSAENOTSOCK ) { - D(bug("<%d> WSAEnumNetworkEvents: socket is already closed\r\n", t)); - } else { - D(bug("<%d> WSAEnumNetworkEvents failed with error code %d, freeing slot\r\n", t, err)); - free_socket( t ); - } - } - } - _WSAResetEvent( sockets[t].ev ); - } else { - static int interval = 5; - if( !--interval ) { - for( int i=0; i= tmw ) { - if( sockets[i].state == SYN_SENT ) { - /* - A very basic SYN flood protection. Note that watching - SYN_SENT instead of SYN_RCVD, because the state codes are - from the point of view of the Mac-Router interface, not Router-Remote. - */ - D(bug("<%d> SYN_SENT time-out expired\r\n", i)); - } else { - D(bug("<%d> TIME_WAIT expired\r\n", i)); - } - free_socket( i ); - } - } else if( stl ) { - if( sockets[i].state == ESTABLISHED ) { - if( GetTickCount() >= stl ) { - D(bug("<%d> RESEND timeout expired\r\n", i)); - sockets[i].stream_to_mac_stalled_until = GetTickCount() + sockets[i].resend_timeout; - send_buffer( i, true ); - } - } else { - sockets[i].stream_to_mac_stalled_until = 0; - } - } - } - } - interval = 5; - } - } - LeaveCriticalSection( &tcp_section ); - } - return 0; -} - -static unsigned int WINAPI tcp_listen_thread(void *arg) -{ - WSAEVENT wait_handles[MAX_SOCKETS]; - - for( int i=0; i= WAIT_OBJECT_0 && ret < WAIT_OBJECT_0 + MAX_SOCKETS ) { - const int lst = ret - WAIT_OBJECT_0; - - D(bug("[%d] connection attempt to port %d\r\n", lst, l_sockets[lst].port)); - - WSANETWORKEVENTS what; - - if( _WSAEnumNetworkEvents( l_sockets[lst].s, l_sockets[lst].ev, &what ) != SOCKET_ERROR ) { - if( what.lNetworkEvents & FD_ACCEPT ) { - if( what.iErrorCode[FD_ACCEPT_BIT] == 0 ) { - D(bug("[%d] Connect ok\r\n", lst)); - tcp_accept_callback(lst); - } else { - D(bug("[%d] Connect error=%d\r\n", lst, what.iErrorCode[FD_ACCEPT_BIT])); - // Post icmp error - } - } - } - - // close on errors too - if(l_sockets[lst].once) { - D(bug("[%d] once mode: closing listening socket on port %d\r\n", lst, l_sockets[lst].port)); - if( _closesocket( l_sockets[lst].s ) == SOCKET_ERROR ) { - int err = _WSAGetLastError(); - D(bug("[%d] close error %d\r\n", lst, err)); - } - - l_sockets[lst].s = INVALID_SOCKET; - l_sockets[lst].port = 0; - l_sockets[lst].ip = 0; - - int t = l_sockets[lst].parent; - if( t >= 0 ) { - sockets[t].child = -1; - } - l_sockets[lst].parent = -1; - } - - _WSAResetEvent( l_sockets[lst].ev ); - } - LeaveCriticalSection( &tcp_section ); - } - return 0; -} - -/* - tcp_port= [,] - tcp_port=21,192.168.0.1 -*/ - -static void init_tcp_listen_ports() -{ - int32 index = 0; - const char *port_str; - while ((port_str = PrefsFindString("tcp_port", index++)) != NULL) { - uint32 iface = 0; - const char *if_str = strchr(port_str,','); - if(if_str) { - if_str++; - uint32 if_net = _inet_addr( if_str ); - if(if_net == INADDR_NONE) if_net = INADDR_ANY; - iface = ntohl( if_net ); - } - uint16 port = (uint16)strtoul( port_str, 0, 0 ); - if( port ) { - uint32 ip = 0; - bool once = false; - alloc_listen_socket( port, ip, iface, once ); - } - } -} - -static HANDLE tcp_handle = 0; -static HANDLE tcp_l_handle = 0; - -void init_tcp() -{ - InitializeCriticalSection( &tcp_section ); - - for( int i=0; ihEvent; - - // It's not easy to know whether empty upd datagrams should be passed along. doh. - if(error == 0 && bytes_read > 0) { - - if(bytes_read > 1460) { - D(bug("discarding oversized udp packet, size = \r\n", bytes_read)); - } else { - struct sockaddr_in name; - int namelen = sizeof(name); - memset( &name, 0, sizeof(name) ); - if( _getsockname( cmpl->s, (struct sockaddr *)&name, &namelen ) == SOCKET_ERROR ) { - D(bug("_getsockname() failed, error=%d\r\n", _WSAGetLastError() )); - } else { - D(bug("_getsockname(): port=%d\r\n", ntohs(name.sin_port) )); - } - - int udp_size = sizeof(udp_t) + bytes_read; - udp_t *udp = (udp_t *)malloc( udp_size ); - if(udp) { - mac_t *mac = (mac_t *)udp; - ip_t *ip = (ip_t *)udp; - - // Build MAC - // memcpy( udp->ip.mac.dest, cmpl->mac_src, 6 ); - memcpy( mac->dest, ether_addr, 6 ); - memcpy( mac->src, router_mac_addr, 6 ); - mac->type = htons(mac_type_ip4); - - // Build IP - ip->version = 4; - ip->header_len = 5; - ip->tos = 0; - ip->total_len = htons(sizeof(udp_t) - sizeof(mac_t) + bytes_read); // no options - ip->ident = htons(next_ip_ident_number++); // htons() might be a macro... but does not really matter here. - ip->flags_n_frag_offset = 0; - ip->ttl = 128; // one hop actually! - ip->proto = ip_proto_udp; - ip->src = htonl(cmpl->ip_dest); - ip->dest = htonl(cmpl->ip_src); - make_ip4_checksum( (ip_t *)udp ); - - // Copy payload (used by UDP checksum) - memcpy( (char *)udp + sizeof(udp_t), cmpl->buffers[0].buf, bytes_read ); - - // Build UDP - udp->src_port = htons(cmpl->dest_port); - udp->dest_port = htons(cmpl->src_port); - udp->msg_len = htons(sizeof(udp_t) - sizeof(ip_t) + bytes_read); // no options - make_udp_checksum( udp ); - - dump_bytes( (uint8 *)udp, udp_size ); - - enqueue_packet( (uint8 *)udp, udp_size ); - free(udp); - } - } - } - - if(!is_router_shutting_down && cmpl->s != INVALID_SOCKET && cmpl->b_recfrom()) { - cmpl->socket_ttl = GetTickCount() + 60000L; - } else { - delete_socket( cmpl ); - } -} - -void write_udp( udp_t *udp, int len ) -{ - if( len < sizeof(udp_t) ) { - D(bug("Too small udp packet(%d), dropped\r\n", len)); - return; - } - - uint16 src_port = ntohs(udp->src_port); - uint16 dest_port = ntohs(udp->dest_port); - - BOOL ok = true; - - socket_t *cmpl = find_socket( src_port, dest_port, IPPROTO_UDP ); - - BOOL old_socket_found = cmpl != 0; - - if(!cmpl) { - cmpl = new socket_t(IPPROTO_UDP); - if(cmpl) { - cmpl->s = _socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); - if(cmpl->s == INVALID_SOCKET) { - delete cmpl; - cmpl = 0; - ok = false; - } else { - cmpl->src_port = src_port; - cmpl->dest_port = dest_port; - add_socket( cmpl ); - } - } else { - ok = false; - } - } - - if(ok) { - cmpl->src_port = src_port; - cmpl->dest_port = dest_port; - cmpl->ip_src = ntohl(udp->ip.src); - cmpl->ip_dest = ntohl(udp->ip.dest); - - struct sockaddr_in to; - memset( &to, 0, sizeof(to) ); - to.sin_family = AF_INET; - to.sin_port = udp->dest_port; - to.sin_addr.s_addr = udp->ip.dest; - - char *data = (char *)udp + sizeof(udp_t); - int dlen = len - sizeof(udp_t); - - // ttl changed, update checksum - make_udp_checksum( udp ); - - cmpl->set_ttl( udp->ip.ttl ); - - bool please_close = true; - /* - Note that broadcast messages fill fail, no setsockopt(SO_BROADCAST). - That's exactly what I want. - */ - if(SOCKET_ERROR != _sendto( cmpl->s, data, dlen, 0, (struct sockaddr *)&to, sizeof(to) )) { - if(old_socket_found) { - // This socket is not overlapped. - please_close = false; - } else { - if(cmpl->b_recfrom()) please_close = false; - } - cmpl->socket_ttl = GetTickCount() + 60000L; - } else { - int socket_error = _WSAGetLastError(); - D(bug("_sendto() completed with error %d\r\n", socket_error)); - // TODO: check this out: error_winsock_2_icmp() uses router_ip_address - // as source ip; but it's probably allright - error_winsock_2_icmp( socket_error, (ip_t *)udp, len ); - } - if(please_close) { - delete_socket(cmpl); - } - } -} - -void init_udp() -{ -} - -void final_udp() -{ -} diff --git a/BasiliskII/src/Windows/router/udp.h b/BasiliskII/src/Windows/router/udp.h deleted file mode 100755 index b9a5f8a5..00000000 --- a/BasiliskII/src/Windows/router/udp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * udp.h - ip router - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _UDP_H_ -#define _UDP_H_ - -void write_udp( udp_t *udp, int len ); - -void CALLBACK udp_read_completion( - DWORD error, - DWORD bytes_read, - LPWSAOVERLAPPED lpOverlapped, - DWORD flags -); - -void init_udp(); -void final_udp(); - -#endif // _UDP_H_ diff --git a/BasiliskII/src/Windows/serial_windows.cpp b/BasiliskII/src/Windows/serial_windows.cpp deleted file mode 100755 index 5a062b32..00000000 --- a/BasiliskII/src/Windows/serial_windows.cpp +++ /dev/null @@ -1,1198 +0,0 @@ -/* - * serial_windows.cpp - Serial device driver for Win32 - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// TODO: serial i/o threads should have high priority. -#include "sysdeps.h" - -#include -#include - -#include "main.h" -#include "util_windows.h" -#include "macos_util.h" -#include "prefs.h" -#include "serial.h" -#include "serial_defs.h" -#include "cpu_emulation.h" - -// This must be always on. -#define DEBUG 1 -#undef OutputDebugString -#define OutputDebugString serial_log_write -static void serial_log_write( char *s ); -#define SERIAL_LOG_FILE_NAME TEXT("serial.log") -#include "debug.h" -#undef D -#define D(x) if(debug_serial != DB_SERIAL_NONE) (x); - - -enum { - DB_SERIAL_NONE=0, - DB_SERIAL_NORMAL, - DB_SERIAL_LOUD -}; - -static int16 debug_serial = DB_SERIAL_NONE; - -static HANDLE serial_log_file = INVALID_HANDLE_VALUE; - -static void serial_log_open( LPCTSTR path ) -{ - if(debug_serial == DB_SERIAL_NONE) return; - - DeleteFile( path ); - serial_log_file = CreateFile( - path, - GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ, - NULL, - CREATE_ALWAYS, - FILE_FLAG_WRITE_THROUGH, - NULL - ); - if( serial_log_file == INVALID_HANDLE_VALUE ) { - ErrorAlert( "Could not create the serial log file." ); - } -} - -static void serial_log_close( void ) -{ - if(debug_serial == DB_SERIAL_NONE) return; - - if( serial_log_file != INVALID_HANDLE_VALUE ) { - CloseHandle( serial_log_file ); - serial_log_file = INVALID_HANDLE_VALUE; - } -} - -static void serial_log_write( char *s ) -{ - DWORD bytes_written; - - // should have been checked already. - if(debug_serial == DB_SERIAL_NONE) return; - - if( serial_log_file != INVALID_HANDLE_VALUE ) { - - DWORD count = strlen(s); - if (0 == WriteFile(serial_log_file, s, count, &bytes_written, NULL) || - (int)bytes_written != count) - { - serial_log_close(); - ErrorAlert( "serial log file write error (out of disk space?). Log closed." ); - } else { - FlushFileBuffers( serial_log_file ); - } - } -} - - -// Driver private variables -class XSERDPort : public SERDPort { -public: - XSERDPort(LPCTSTR dev, LPCTSTR suffix) - { - D(bug(TEXT("XSERDPort constructor %s\r\n"), dev)); - - read_pending = write_pending = false; - - if(dev) - _tcscpy( device_name, dev ); - else - *device_name = 0; - _tcsupr(device_name); - is_parallel = (_tcsncmp(device_name, TEXT("LPT"), 3) == 0); - is_file = (_tcsncmp(device_name, TEXT("FILE"), 4) == 0); - if(is_file) { - char entry_name[20]; - _snprintf( entry_name, lengthof(entry_name), "portfile%s", str(suffix).get() ); - const char *path = PrefsFindString(entry_name); - if(path) { - _tcscpy( output_file_name, tstr(path).get() ); - } else { - _tcscpy( output_file_name, TEXT("C:\\B2TEMP.OUT") ); - } - } - - is_serial = !is_parallel && !is_file; - - fd = INVALID_HANDLE_VALUE; - input_thread_active = output_thread_active = NULL; - } - - virtual ~XSERDPort() - { - D(bug("XSERDPort destructor \r\n")); - if (input_thread_active) { - D(bug("WARNING: brute TerminateThread(input)\r\n")); - TerminateThread(input_thread_active,0); - CloseHandle(input_signal); - input_thread_active = NULL; - } - if (output_thread_active) { - D(bug("WARNING: brute TerminateThread(output)\r\n")); - TerminateThread(output_thread_active,0); - CloseHandle(output_signal); - output_thread_active = NULL; - } - } - - virtual int16 open(uint16 config); - virtual int16 prime_in(uint32 pb, uint32 dce); - virtual int16 prime_out(uint32 pb, uint32 dce); - virtual int16 control(uint32 pb, uint32 dce, uint16 code); - virtual int16 status(uint32 pb, uint32 dce, uint16 code); - virtual int16 close(void); - -private: - bool configure(uint16 config); - void set_handshake(uint32 s, bool with_dtr); - static unsigned int WINAPI input_func(void *arg); - static unsigned int WINAPI output_func(void *arg); - static int acknowledge_error(HANDLE h, bool is_read); - bool set_timeouts(int bauds, int parity_bits, int stop_bits); - - TCHAR device_name[256]; - HANDLE fd; - - bool io_killed; // Flag: KillIO called, I/O threads must not call deferred tasks - bool quitting; // Flag: Quit threads - - HANDLE input_thread_active; // Handle: Input thread installed (was a bool) - unsigned int input_thread_id; - HANDLE input_signal; // Signal for input thread: execute command - uint32 input_pb, input_dce; // Command parameters for input thread - - HANDLE output_thread_active; // Handle: Output thread installed (was a bool) - unsigned int output_thread_id; - HANDLE output_signal; // Signal for output thread: execute command - uint32 output_pb, output_dce; // Command parameters for output thread - - DCB mode; // Terminal configuration - - bool is_serial; - bool is_parallel; // true if LPTx - - bool is_file; // true if FILE - TCHAR output_file_name[256]; -}; - -/* - * Initialization - */ - -void SerialInit(void) -{ - const char *port; - - debug_serial = PrefsFindInt32("debugserial"); - - serial_log_open( SERIAL_LOG_FILE_NAME ); - - // Read serial preferences and create structs for both ports - - port = PrefsFindString("seriala"); - if(port) { - D(bug("SerialInit seriala=%s\r\n",port)); - } - the_serd_port[0] = new XSERDPort(tstr(port).get(), TEXT("0")); - - port = PrefsFindString("serialb"); - if(port) { - D(bug("SerialInit serialb=%s\r\n",port)); - } - the_serd_port[1] = new XSERDPort(tstr(port).get(), TEXT("1")); -} - - -/* - * Deinitialization - */ - -void SerialExit(void) -{ - D(bug("SerialExit\r\n")); - if(the_serd_port[0]) delete (XSERDPort *)the_serd_port[0]; - if(the_serd_port[1]) delete (XSERDPort *)the_serd_port[1]; - D(bug("SerialExit done\r\n")); - - serial_log_close(); -} - - -/* - * Open serial port - */ - -int16 XSERDPort::open(uint16 config) -{ - // Don't open NULL name devices - if (!device_name || !*device_name) - return openErr; - - D(bug(TEXT("XSERDPort::open device=%s,config=0x%X\r\n"),device_name,(int)config)); - - // Init variables - io_killed = false; - quitting = false; - - // Open port - if(is_file) { - DeleteFile( output_file_name ); - fd = CreateFile( output_file_name, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ, - NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL - ); - } else { - fd = CreateFile( device_name, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0 ); - } - if(fd == INVALID_HANDLE_VALUE) { - goto open_error; - D(bug(TEXT("XSERDPort::open failed to open port %s\r\n"),device_name)); - } - - if(is_serial) { - // Configure port for raw mode - memset( &mode, 0, sizeof(DCB) ); - mode.DCBlength = sizeof(mode); - if(!GetCommState( fd, &mode )) - goto open_error; - - mode.fBinary = TRUE; - if(!configure(config)) { - D(bug("XSERDPort::configure failed\r\n")); - goto open_error; - } - } - - // Start input/output threads - input_signal = CreateSemaphore( 0, 0, 1, NULL); - if(!input_signal) - goto open_error; - - output_signal = CreateSemaphore( 0, 0, 1, NULL); - if(!output_signal) - goto open_error; - - D(bug("Semaphores created\r\n")); - - input_thread_active = (HANDLE)_beginthreadex( 0, 0, input_func, (LPVOID)this, 0, &input_thread_id ); - output_thread_active = (HANDLE)_beginthreadex( 0, 0, output_func, (LPVOID)this, 0, &output_thread_id ); - - if (!input_thread_active || !output_thread_active) - goto open_error; - - D(bug("Threads created, Open returns success\r\n")); - return noErr; - -open_error: - D(bug("Open cleanup after failure\r\n")); - if (input_thread_active) { - TerminateThread(input_thread_active,0); - CloseHandle(input_signal); - input_thread_active = false; - } - if (output_thread_active) { - TerminateThread(output_thread_active,0); - CloseHandle(output_signal); - output_thread_active = false; - } - if(fd != INVALID_HANDLE_VALUE) { - CloseHandle(fd); - fd = 0; - } - return openErr; -} - -/* - * Read data from port - */ - -int16 XSERDPort::prime_in(uint32 pb, uint32 dce) -{ - D(bug("XSERDPort::prime_in\r\n")); - // Send input command to input_thread - read_done = false; - read_pending = true; - input_pb = pb; - input_dce = dce; - ReleaseSemaphore(input_signal,1,NULL); - return 1; // Command in progress -} - - -/* - * Write data to port - */ - -int16 XSERDPort::prime_out(uint32 pb, uint32 dce) -{ - D(bug("XSERDPort::prime_out\r\n")); - // Send output command to output_thread - write_done = false; - write_pending = true; - output_pb = pb; - output_dce = dce; - ReleaseSemaphore(output_signal,1,NULL); - return 1; // Command in progress -} - - -static DWORD get_comm_output_buf_size( HANDLE h ) -{ - DWORD size = 0; - COMMPROP cp; - - if(GetCommProperties(h,&cp)) { - size = cp.dwCurrentTxQueue; - } - return size; -} - -/* - * Control calls - */ - -int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code) -{ - D(bug("XSERDPort::control code=%d\r\n",(int)code)); - switch (code) { - - case kSERDClockMIDI: - /* http://til.info.apple.com/techinfo.nsf/artnum/n2425 - A MIDI interface operates at 31.25 Kbaud (+/- 1%) [== 31400] - asynchronously, using a data format of one start bit, eight - data bits, and one stop bit. This makes a total of 10 bits - for each 320 microsecond period per serial byte. - */ - D(bug("kSERDClockMIDI setting 38400,n,8,1\n")); - return noErr; - - /* - mode.BaudRate = 38400; - mode.ByteSize = 8; - mode.StopBits = ONESTOPBIT; - mode.Parity = NOPARITY; - if(!SetCommState( fd, &mode )) { - D(bug("kSERDClockMIDI SetCommState() failed\n")); - return controlErr; - } else { - if(!set_timeouts(38400,0,2)) { - D(bug("kSERDClockMIDI set_timeouts() failed\n")); - return controlErr; - } - D(bug("kSERDClockMIDI OK\n")); - return noErr; - } - */ - - case 1: // KillIO - io_killed = true; - - if(is_serial) { - // Make sure we won't hang waiting. There is something wrong - // in how read_pending & write_pending are handled. - DWORD endtime = GetTickCount() + 1000; - while ( (read_pending || write_pending) && (GetTickCount() < endtime) ) { - Sleep(20); - } - if(read_pending || write_pending) { - D(bug("Warning (KillIO): read_pending=%d, write_pending=%d\n", read_pending, write_pending)); - read_pending = write_pending = false; - } - // | PURGE_TXABORT | PURGE_RXABORT not needed, no overlapped i/o - PurgeComm(fd,PURGE_TXCLEAR|PURGE_RXCLEAR); - FlushFileBuffers(fd); - } - io_killed = false; - D(bug("KillIO done\n")); - return noErr; - - case kSERDConfiguration: - if (configure((uint16)ReadMacInt16(pb + csParam))) - return noErr; - else - return paramErr; - - case kSERDInputBuffer: - if(is_serial) { - - // SetupComm() wants both values, so we need to know the output size. - DWORD osize = get_comm_output_buf_size(fd); - - DWORD isize = ReadMacInt16(pb + csParam + 4) & 0xffffffc0; - - // 1k minimum - // Was this something Amiga specific -- do I need to do this? - if (isize < 1024) - isize = 1024; - - if(isize > 0 && osize > 0) { - if(SetupComm( fd, isize, osize )) { - D(bug(" buffer size is now %08lx\n", isize)); - return noErr; - } else { - D(bug(" SetupComm(%d,%d) failed, error = %08lx\n", isize, osize, GetLastError())); - } - } - } - // Always return ok. - return noErr; - - case kSERDSerHShake: - set_handshake(pb + csParam, false); - return noErr; - - case kSERDSetBreak: - if(is_serial) { - if(!SetCommBreak(fd)) return controlErr; - } - return noErr; - - case kSERDClearBreak: - if(is_serial) { - if(!ClearCommBreak(fd)) return controlErr; - } - return noErr; - - case kSERDBaudRate: { - if (is_serial) { - uint16 rate = (uint16)ReadMacInt16(pb + csParam); - int baud_rate; - if (rate <= 50) { - rate = 50; baud_rate = CBR_110; - } else if (rate <= 75) { - rate = 75; baud_rate = CBR_110; - } else if (rate <= 110) { - rate = 110; baud_rate = CBR_110; - } else if (rate <= 134) { - rate = 134; baud_rate = CBR_110; - } else if (rate <= 150) { - rate = 150; baud_rate = CBR_110; - } else if (rate <= 200) { - rate = 200; baud_rate = CBR_300; - } else if (rate <= 300) { - rate = 300; baud_rate = CBR_300; - } else if (rate <= 600) { - rate = 600; baud_rate = CBR_600; - } else if (rate <= 1200) { - rate = 1200; baud_rate = CBR_1200; - } else if (rate <= 1800) { - rate = 1800; baud_rate = CBR_2400; - } else if (rate <= 2400) { - rate = 2400; baud_rate = CBR_2400; - } else if (rate <= 4800) { - rate = 4800; baud_rate = CBR_4800; - } else if (rate <= 9600) { - rate = 9600; baud_rate = CBR_9600; - } else if (rate <= 19200) { - rate = 19200; baud_rate = CBR_19200; - } else if (rate <= 38400) { - rate = 38400; baud_rate = CBR_38400; - } else if (rate <= 57600) { - rate = 57600; baud_rate = CBR_57600; - } else { - rate = 57600; baud_rate = CBR_57600; - } - WriteMacInt16(pb + csParam, rate); - mode.BaudRate = baud_rate; - if(!SetCommState( fd, &mode )) return controlErr; - // TODO: save parity/stop values and use here (not critical) - if(!set_timeouts(rate,0,1)) return controlErr; - } - return noErr; - } - - case kSERDHandshake: - case kSERDHandshakeRS232: - set_handshake(pb + csParam, true); - return noErr; - - case kSERDMiscOptions: - if (ReadMacInt8(pb + csParam) & kOptionPreserveDTR) - mode.fDtrControl = DTR_CONTROL_ENABLE; // correct? - else - mode.fDtrControl = DTR_CONTROL_DISABLE; // correct? - if(is_serial) { - if(!SetCommState( fd, &mode )) return controlErr; - } - return noErr; - - case kSERDAssertDTR: { - if (is_serial) { - if(!EscapeCommFunction(fd,SETDTR)) return controlErr; - } - return noErr; - } - - case kSERDNegateDTR: { - if (is_serial) { - if(!EscapeCommFunction(fd,CLRDTR)) return controlErr; - } - return noErr; - } - - case kSERDSetPEChar: - case kSERDSetPEAltChar: - { - uint16 errChar = (uint16)ReadMacInt16(pb + csParam); - mode.fErrorChar = TRUE; - mode.ErrorChar = (char)errChar; - return noErr; - } - - case kSERDResetChannel: - if (is_serial) { - // | PURGE_TXABORT | PURGE_RXABORT not needed, no overlapped i/o - PurgeComm(fd,PURGE_TXCLEAR|PURGE_RXCLEAR); - FlushFileBuffers(fd); - } - return noErr; - - case kSERDAssertRTS: { - if (is_serial) { - if(!EscapeCommFunction(fd,SETRTS)) return controlErr; - } - return noErr; - } - - case kSERDNegateRTS: { - if (is_serial) { - if(!EscapeCommFunction(fd,CLRRTS)) return controlErr; - } - return noErr; - } - - case kSERD115KBaud: - if (is_serial) { - mode.BaudRate = CBR_115200; - if(!SetCommState( fd, &mode )) return controlErr; - } - return noErr; - - case kSERD230KBaud: - case kSERDSetHighSpeed: - if (is_serial) { - mode.BaudRate = CBR_256000; - if(!SetCommState( fd, &mode )) return controlErr; - } - return noErr; - - default: - D(bug("WARNING: SerialControl(): unimplemented control code %d\r\n", code)); - return controlErr; - } -} - -/* - * Status calls - */ - -int16 XSERDPort::status(uint32 pb, uint32 dce, uint16 code) -{ - // D(bug("XSERDPort::status code=%d\r\n",(int)code)); - - DWORD error_state; - COMSTAT comstat; - - switch (code) { - case kSERDInputCount: { - uint32 num = 0; - if (is_serial) { - if(!ClearCommError(fd,&error_state,&comstat)) return statusErr; - num = comstat.cbInQue; - } - WriteMacInt32(pb + csParam, num); - return noErr; - } - - case kSERDStatus: { - uint32 p = pb + csParam; - WriteMacInt8(p + staCumErrs, cum_errors); - cum_errors = 0; - DWORD status; - - if(is_serial) { - if(!GetCommModemStatus(fd,&status)) return statusErr; - } else { - status = MS_CTS_ON | MS_DSR_ON | MS_RLSD_ON; - D(bug("kSERDStatus: faking status for LPT port or FILE\r\n")); - } - - WriteMacInt8(p + staXOffSent, 0); - WriteMacInt8(p + staXOffHold, 0); - WriteMacInt8(p + staRdPend, read_pending); - WriteMacInt8(p + staWrPend, write_pending); - - WriteMacInt8(p + staCtsHold, status & MS_CTS_ON ? 0 : 1); - WriteMacInt8(p + staDsrHold, status & MS_DSR_ON ? 0 : 1); - - WriteMacInt8(p + staModemStatus, - (status & MS_DSR_ON ? dsrEvent : 0) - | (status & MS_RING_ON ? riEvent : 0) - | (status & MS_RLSD_ON ? dcdEvent : 0) // is this carrier detect? - | (status & MS_CTS_ON ? ctsEvent : 0)); - return noErr; - } - - default: - D(bug("WARNING: SerialStatus(): unimplemented status code %d\r\n", code)); - return statusErr; - } -} - - -/* - * Close serial port - */ - -int16 XSERDPort::close() -{ - D(bug("XSERDPort::close\r\n")); - - // Kill threads - if (input_thread_active) { - quitting = true; - ReleaseSemaphore(input_signal,1,NULL); - input_thread_active = false; - CloseHandle(input_signal); - } - if (output_thread_active) { - quitting = true; - ReleaseSemaphore(output_signal,1,NULL); - output_thread_active = false; - // bugfix: was: CloseHandle(&output_signal); - CloseHandle(output_signal); - } - - // Close port - if(fd != INVALID_HANDLE_VALUE) { - CloseHandle(fd); - fd = 0; - } - return noErr; -} - -bool XSERDPort::set_timeouts( - int bauds, int parity_bits, int stop_bits ) -{ - COMMTIMEOUTS timeouts; - uint32 bytes_per_sec; - uint32 msecs_per_ch; - bool result = false; - - // Should already been checked - if (!is_serial) - return true; - - bytes_per_sec = bauds / (mode.ByteSize + parity_bits + stop_bits); - - // 75% bytes_per_sec - // bytes_per_sec = (bytes_per_sec+bytes_per_sec+bytes_per_sec) >> 2; - - // 50% bytes_per_sec - bytes_per_sec = bytes_per_sec >> 1; - - msecs_per_ch = 1000 / bytes_per_sec; - if(msecs_per_ch == 0) msecs_per_ch = 1; - - if(GetCommTimeouts(fd,&timeouts)) { - D(bug("old timeout values: %ld %ld %ld %ld %ld\r\n", - timeouts.ReadIntervalTimeout, - timeouts.ReadTotalTimeoutMultiplier, - timeouts.ReadTotalTimeoutConstant, - timeouts.WriteTotalTimeoutMultiplier, - timeouts.WriteTotalTimeoutConstant - )); - - timeouts.WriteTotalTimeoutMultiplier = msecs_per_ch; - timeouts.WriteTotalTimeoutConstant = 10; - - /* - timeouts.ReadIntervalTimeout = msecs_per_ch; - timeouts.ReadTotalTimeoutMultiplier = msecs_per_ch; - timeouts.ReadTotalTimeoutConstant = 10; - */ - - timeouts.ReadIntervalTimeout = MAXDWORD; - timeouts.ReadTotalTimeoutMultiplier = 0; - timeouts.ReadTotalTimeoutConstant = 0; - - if(!SetCommTimeouts(fd,&timeouts)) { - D(bug("SetCommTimeouts() failed in configure()\r\n")); - } else { - D(bug("new timeout values: %ld %ld %ld %ld %ld\r\n", - timeouts.ReadIntervalTimeout, - timeouts.ReadTotalTimeoutMultiplier, - timeouts.ReadTotalTimeoutConstant, - timeouts.WriteTotalTimeoutMultiplier, - timeouts.WriteTotalTimeoutConstant - )); - result = true; - } - } else { - D(bug("GetCommTimeouts() failed in set_timeouts()\r\n")); - } - return(result); -} - -/* - * Configure serial port with MacOS config word - */ - -bool XSERDPort::configure(uint16 config) -{ - D(bug("XSERDPort::configure, config=%d\r\n",(int)config)); - - if (!is_serial) - return true; - - // needed to calculate optimal timeouts - uint32 bauds = 57600; - uint32 stop_bits = 1; - uint32 parity_bits = 0; - - // Not all of these can be set here anyway. - /* - mode.fOutxCtsFlow = TRUE; - mode.fOutxDsrFlow = FALSE; - mode.fDtrControl = DTR_CONTROL_ENABLE; // DTR_CONTROL_HANDSHAKE? - mode.fDsrSensitivity = FALSE; // ??? - mode.fOutX = FALSE; - mode.fInX = FALSE; - mode.fTXContinueOnXoff = FALSE; - mode.fErrorChar = FALSE; - mode.ErrorChar = 0; - mode.fNull = FALSE; - mode.fRtsControl = 2; // ??? - mode.fAbortOnError = FALSE; - mode.XonLim = 0x800; - mode.XoffLim = 0x200; - mode.XonChar = 0x11; - mode.XoffChar = 0x13; - mode.EofChar = 0; - mode.EvtChar = '\0'; - */ - - // Set baud rate - switch (config & 0x03ff) { - // no baud1800, CBR_14400, CBR_56000, CBR_115200, CBR_128000, CBR_256000 - case baud150: mode.BaudRate = CBR_110; bauds = 110; break; - case baud300: mode.BaudRate = CBR_300; bauds = 300; break; - case baud600: mode.BaudRate = CBR_600; bauds = 600; break; - case baud1200: mode.BaudRate = CBR_1200; bauds = 1200; break; - case baud1800: return false; - case baud2400: mode.BaudRate = CBR_2400; bauds = 2400; break; - case baud4800: mode.BaudRate = CBR_4800; bauds = 4800; break; - case baud9600: mode.BaudRate = CBR_9600; bauds = 9600; break; - case baud19200: mode.BaudRate = CBR_19200; bauds = 19200; break; - case baud38400: mode.BaudRate = CBR_38400; bauds = 38400; break; - case baud57600: mode.BaudRate = CBR_57600; bauds = 57600; break; - default: - return false; - } - - // Set number of stop bits - switch (config & 0xc000) { - case stop10: - mode.StopBits = ONESTOPBIT; - stop_bits = 1; - break; - case stop15: - mode.StopBits = ONE5STOPBITS; - stop_bits = 2; - break; - case stop20: - mode.StopBits = TWOSTOPBITS; - stop_bits = 2; - break; - default: - return false; - } - - // Set parity mode - switch (config & 0x3000) { - case noParity: - mode.Parity = NOPARITY; - mode.fParity = FALSE; - parity_bits = 0; - break; - case oddParity: - mode.Parity = ODDPARITY; - mode.fParity = TRUE; - parity_bits = 1; - break; - case evenParity: - mode.Parity = EVENPARITY; - mode.fParity = TRUE; - parity_bits = 1; - break; - // No MARKPARITY, SPACEPARITY - default: - return false; - } - - // Set number of data bits - switch (config & 0x0c00) { - // No data4 - case data5: - mode.ByteSize = 5; break; - case data6: - mode.ByteSize = 6; break; - case data7: - mode.ByteSize = 7; break; - case data8: - mode.ByteSize = 8; break; - default: - return false; - } - - D(bug("Interpreted configuration: %d,%d,%d,%d\r\n", - bauds, - mode.ByteSize, - stop_bits, - parity_bits - )); - - if(!SetCommState( fd, &mode )) { - D(bug("SetCommState failed in configure()\r\n")); - return false; - } - - if(!set_timeouts(bauds,parity_bits,stop_bits)) - return false; - - return true; -} - - -/* - * Set serial handshaking - */ - -void XSERDPort::set_handshake(uint32 s, bool with_dtr) -{ - D(bug(" set_handshake %02x %02x %02x %02x %02x %02x %02x %02x\r\n", - ReadMacInt8(s + 0), ReadMacInt8(s + 1), ReadMacInt8(s + 2), ReadMacInt8(s + 3), - ReadMacInt8(s + 4), ReadMacInt8(s + 5), ReadMacInt8(s + 6), ReadMacInt8(s + 7))); - - if (!is_serial) - return; - - if (with_dtr) { - mode.fDtrControl = DTR_CONTROL_ENABLE; - if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR)) - mode.fOutxCtsFlow = TRUE; - else - mode.fOutxCtsFlow = FALSE; - } else { - mode.fDtrControl = DTR_CONTROL_DISABLE; - if (ReadMacInt8(s + shkFCTS)) - mode.fOutxCtsFlow = TRUE; - else - mode.fOutxCtsFlow = FALSE; - } - - // MIDI: set_handshake 00 00 f4 f5 21 00 00 00 - // shkFXOn = 0 - // shkFCTS = 0 - // shkXOn = f4 - // shkXOff = f5 - // shkErrs = 21 - // shkEvts = 0 - // shkFInX = 0 - // shkFDTR = 0 - if (ReadMacInt8(s + shkXOn) && ReadMacInt8(s + shkXOn)) { - mode.fOutX = 1; - mode.fInX = 1; - mode.XonChar = ReadMacInt8(s + shkXOn); - mode.XoffChar = ReadMacInt8(s + shkXOff); - } else { - mode.fOutX = 0; - mode.fInX = 0; - } - if (ReadMacInt8(s + shkErrs)) { - mode.ErrorChar = ReadMacInt8(s + shkErrs); - mode.fErrorChar = 1; - } else { - mode.fErrorChar = 0; - } - - (void)SetCommState( fd, &mode ); - - // D(bug(" %sware flow control\r\n", mode.c_cflag & CRTSCTS ? "hard" : "soft")); - // tcsetattr(fd, TCSANOW, &mode); -} - -/* - if mode.fAbortOnError is TRUE, ClearCommError() *MUST* be called - after any read or write errors. Otherwise no i/o will occur again - - These error codes should be translated but the Mac Device Manager - error code mnemonics are too cryptic to me. -*/ - -int XSERDPort::acknowledge_error(HANDLE h, bool is_read) -{ - DWORD error_state; - COMSTAT comstat; - int err; - - // default error code if cannot map correctly - err = is_read ? readErr : writErr; - - if(ClearCommError(h,&error_state,&comstat)) { - D(bug("A %s error 0x%X occured.\r\n", is_read ? "read" : "write", error_state)); - D(bug("There was %d bytes in input buffer and %d bytes in output buffer.\r\n",(int)comstat.cbInQue,(int)comstat.cbOutQue)); - if(error_state & CE_MODE) { - D(bug("The requested mode is not supported.\r\n")); - } else { - if(error_state & CE_BREAK) { - D(bug("The hardware detected a break condition.\r\n")); - } - if(error_state & CE_FRAME) { - D(bug("The hardware detected a framing error.\r\n")); - } - if(error_state & CE_IOE) { - D(bug("An I/O error occurred during communications with the device.\r\n")); - } - if(error_state & CE_RXOVER) { - D(bug("An input buffer overflow has occurred.\r\n")); - } - if(error_state & CE_RXPARITY) { - D(bug("The hardware detected a parity error.\r\n")); - err = badDCksum; - } - if(error_state & CE_TXFULL) { - D(bug("The application tried to transmit a character, but the output buffer was full.\r\n")); - } - - // Win95 specific errors - if(error_state & CE_OVERRUN) { - D(bug("A character-buffer overrun has occurred. The next character is lost.\r\n")); - if(!is_read) err = wrUnderrun; - } - - // Win95 parallel devices really. - if(error_state & CE_DNS) { - D(bug("A parallel device is not selected (Windows 95).\r\n")); - } - if(error_state & CE_OOP) { - D(bug("A parallel device signaled that it is out of paper (Windows 95 only).\r\n")); - err = unitEmptyErr; - } - if(error_state & CE_PTO) { - D(bug("A time-out occurred on a parallel device (Windows 95).\r\n")); - } - - } - } else { - D(bug("Failed to resume after %s operation.\r\n",is_read ? "read" : "write")); - } - return(err); -} - -#if DEBUG -static void dump_dirst_bytes( BYTE *buf, int32 actual ) -{ - if(debug_serial != DB_SERIAL_LOUD) return; - - BYTE b[256]; - int32 i, bytes = min(actual,sizeof(b)-3); - - for (i=0; idevice_name)); - - for (;;) { - - // Wait for commands - WaitForSingleObject(s->input_signal,INFINITE); - if (s->quitting) - break; - - // Execute command - void *buf = Mac2HostAddr(ReadMacInt32(s->input_pb + ioBuffer)); - uint32 length = ReadMacInt32(s->input_pb + ioReqCount); - D(bug("input_func waiting for %ld bytes of data...\r\n", length)); - - if(length & 0xFFFF0000) { - length &= 0x0000FFFF; - D(bug("byte count fixed to be %ld...\r\n", length)); - } - - int32 actual; - if(s->is_file) { - actual = -1; - error_code = readErr; - } else if(!ReadFile(s->fd, buf, length, (LPDWORD)&actual, 0)) { - actual = -1; - if(s->is_serial) - error_code = acknowledge_error(s->fd,true); - else - error_code = readErr; - } - D(bug(" %ld bytes received\r\n", actual)); - if(actual > 0) { - dump_dirst_bytes( (BYTE*)buf, actual ); - } - - // KillIO called? Then simply return - if (s->io_killed) { - - WriteMacInt16(s->input_pb + ioResult, abortErr); - WriteMacInt32(s->input_pb + ioActCount, 0); - s->read_pending = s->read_done = false; - - } else { - - // Set error code - if (actual >= 0) { - WriteMacInt32(s->input_pb + ioActCount, actual); - WriteMacInt32(s->input_dt + serdtResult, noErr); - } else { - WriteMacInt32(s->input_pb + ioActCount, 0); - WriteMacInt32(s->input_dt + serdtResult, error_code); - } - - // Trigger serial interrupt - D(bug(" triggering serial interrupt\r\n")); - WriteMacInt32(s->input_dt + serdtDCE, s->input_dce); - s->read_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } - } - - D(bug("XSERDPort::input_func terminating gracefully\r\n")); - - _endthreadex( 0 ); - - return(0); -} - - -/* - * Data output thread - */ - -unsigned int XSERDPort::output_func(void *arg) -{ - XSERDPort *s = (XSERDPort *)arg; - int error_code; - -#if 0 - SetThreadPriority( GetCurrentThread(), threads[THREAD_SERIAL_OUT].priority_running ); - SetThreadAffinityMask( GetCurrentThread(), threads[THREAD_SERIAL_OUT].affinity_mask ); - set_desktop(); -#endif - - D(bug(TEXT("XSERDPort::output_func started for device %s\r\n"),s->device_name)); - - for (;;) { - - // Wait for commands - WaitForSingleObject(s->output_signal,INFINITE); - if (s->quitting) - break; - - // Execute command - void *buf = Mac2HostAddr(ReadMacInt32(s->output_pb + ioBuffer)); - uint32 length = ReadMacInt32(s->output_pb + ioReqCount); - D(bug("output_func transmitting %ld bytes of data...\r\n", length)); - - if(length & 0xFFFF0000) { - length &= 0x0000FFFF; - D(bug("byte count fixed to be %ld...\r\n", length)); - } - - int32 actual; - if(!WriteFile(s->fd, buf, length, (LPDWORD)&actual, 0)) { - actual = -1; - if(s->is_serial) - error_code = acknowledge_error(s->fd,false); - else - error_code = writErr; - } - D(bug(" %ld bytes transmitted\r\n", actual)); - if(actual > 0) { - dump_dirst_bytes( (BYTE*)buf, actual ); - } - - // KillIO called? Then simply return - if (s->io_killed) { - - WriteMacInt16(s->output_pb + ioResult, abortErr); - WriteMacInt32(s->output_pb + ioActCount, 0); - s->write_pending = s->write_done = false; - - } else { - - // Set error code - if (actual >= 0) { - WriteMacInt32(s->output_pb + ioActCount, actual); - WriteMacInt32(s->output_dt + serdtResult, noErr); - } else { - WriteMacInt32(s->output_pb + ioActCount, 0); - WriteMacInt32(s->output_dt + serdtResult, error_code); - } - - // Trigger serial interrupt - D(bug(" triggering serial interrupt\r\n")); - WriteMacInt32(s->output_dt + serdtDCE, s->output_dce); - s->write_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } - } - - D(bug("XSERDPort::output_func terminating gracefully\r\n")); - - _endthreadex( 0 ); - - return(0); -} diff --git a/BasiliskII/src/Windows/sys_windows.cpp b/BasiliskII/src/Windows/sys_windows.cpp deleted file mode 100755 index 21e2df0e..00000000 --- a/BasiliskII/src/Windows/sys_windows.cpp +++ /dev/null @@ -1,994 +0,0 @@ -/* - * sys_windows.cpp - System dependent routines, Windows implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include - -#include -typedef std::basic_string tstring; - -#include -using std::min; - -#include "main.h" -#include "util_windows.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "sys.h" - -#include "cd_defs.h" -#include "cdenable/ntcd.h" -#include "cdenable/cache.h" -#include "cdenable/eject_nt.h" - -#define DEBUG 0 -#include "debug.h" - - -// File handles are pointers to these structures -struct file_handle { - TCHAR *name; // Copy of device/file name - HANDLE fh; - bool is_file; // Flag: plain file or physical device? - bool is_floppy; // Flag: floppy device - bool is_cdrom; // Flag: CD-ROM device - bool read_only; // Copy of Sys_open() flag - loff_t start_byte; // Size of file header (if any) - loff_t file_size; // Size of file data (only valid if is_file is true) - cachetype cache; - bool is_media_present; -}; - -// Open file handles -struct open_file_handle { - file_handle *fh; - open_file_handle *next; -}; -static open_file_handle *open_file_handles = NULL; - -// File handle of first floppy drive (for SysMountFirstFloppy()) -static file_handle *first_floppy = NULL; - -// CD-ROM variables -static const int CD_READ_AHEAD_SECTORS = 16; -static char *sector_buffer = NULL; - -// Prototypes -static bool is_cdrom_readable(file_handle *fh); - - -/* - * Initialization - */ - -void SysInit(void) -{ - // Initialize CD-ROM driver - sector_buffer = (char *)VirtualAlloc(NULL, 8192, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - CdenableSysInstallStart(); -} - - -/* - * Deinitialization - */ - -void SysExit(void) -{ - if (sector_buffer) { - VirtualFree(sector_buffer, 0, MEM_RELEASE ); - sector_buffer = NULL; - } -} - - -/* - * Manage open file handles - */ - -static void sys_add_file_handle(file_handle *fh) -{ - open_file_handle *p = new open_file_handle; - p->fh = fh; - p->next = open_file_handles; - open_file_handles = p; -} - -static void sys_remove_file_handle(file_handle *fh) -{ - open_file_handle *p = open_file_handles; - open_file_handle *q = NULL; - - while (p) { - if (p->fh == fh) { - if (q) - q->next = p->next; - else - open_file_handles = p->next; - delete p; - break; - } - q = p; - p = p->next; - } -} - - -/* - * Mount removable media now - */ - -void mount_removable_media(int media) -{ - for (open_file_handle *p = open_file_handles; p != NULL; p = p->next) { - file_handle * const fh = p->fh; - - if (fh->is_cdrom && (media & MEDIA_CD)) { - cache_clear(&fh->cache); - fh->start_byte = 0; - - if (fh->fh && fh->fh != INVALID_HANDLE_VALUE) - CloseHandle(fh->fh); - - // Re-open device - TCHAR device_name[MAX_PATH]; - _sntprintf(device_name, lengthof(device_name), TEXT("\\\\.\\%c:"), fh->name[0]); - fh->fh = CreateFile( - device_name, - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (fh->fh != INVALID_HANDLE_VALUE) { - fh->is_media_present = is_cdrom_readable(fh); - if (fh->is_media_present) - MountVolume(fh); - } else { - fh->is_media_present = false; - } - } - } -} - - -/* - * Account for media that has just arrived - */ - -void SysMediaArrived(void) -{ - mount_removable_media(MEDIA_REMOVABLE); -} - - -/* - * Account for media that has just been removed - */ - -void SysMediaRemoved(void) -{ -} - - -/* - * Mount first floppy disk - */ - -void SysMountFirstFloppy(void) -{ - if (first_floppy) - MountVolume(first_floppy); -} - - -/* - * This gets called when no "floppy" prefs items are found - * It scans for available floppy drives and adds appropriate prefs items - */ - -void SysAddFloppyPrefs(void) -{ -} - - -/* - * This gets called when no "disk" prefs items are found - * It scans for available HFS volumes and adds appropriate prefs items - */ - -void SysAddDiskPrefs(void) -{ -} - - -/* - * This gets called when no "cdrom" prefs items are found - * It scans for available CD-ROM drives and adds appropriate prefs items - */ - -void SysAddCDROMPrefs(void) -{ - // Don't scan for drives if nocdrom option given - if (PrefsFindBool("nocdrom")) - return; - - char rootdir[] = "C:\\"; - for (; rootdir[0] <= 'Z'; rootdir[0]++) { - if (GetDriveTypeA(rootdir) == DRIVE_CDROM) - PrefsAddString("cdrom", rootdir); - } -} - - -/* - * Add default serial prefs (must be added, even if no ports present) - */ - -void SysAddSerialPrefs(void) -{ - PrefsAddString("seriala", "COM1"); - PrefsAddString("serialb", "COM2"); -} - - -/* - * Read CD-ROM - * Must give cd some time to settle - * Can't give too much however, would be annoying, this is difficult.. - */ - -static inline int cd_read_with_retry(file_handle *fh, ULONG LBA, int count, char *buf ) -{ - if (!fh || !fh->fh) - return 0; - - return CdenableSysReadCdBytes(fh->fh, LBA, count, buf); -} - -static int cd_read(file_handle *fh, cachetype *cptr, ULONG LBA, int count, char *buf) -{ - ULONG l1, l2, cc; - int i, c_count, got_bytes = 0, nblocks, s_inx, ss, first_block; - int ok_bytes = 0; - char *ptr, *ttptr = 0, *tmpbuf; - - if (count <= 0) - return 0; - - if (!fh || !fh->fh) - return 0; - - ss = 2048; - l1 = (LBA / ss) * ss; - l2 = ((LBA + count - 1 + ss) / ss) * ss; - cc = l2 - l1; - nblocks = cc / ss; - first_block = LBA / ss; - - ptr = buf; - s_inx = LBA - l1; - c_count = ss - s_inx; - if (c_count > count) - c_count = count; - - for (i = 0; i < nblocks; i++) { - if (!cache_get(cptr, first_block + i, sector_buffer)) - break; - - memcpy(ptr, sector_buffer + s_inx, c_count); - ok_bytes += c_count; - ptr += c_count; - s_inx = 0; - c_count = ss; - if (c_count > count - ok_bytes) - c_count = count - ok_bytes; - } - - if (i != nblocks && count != ok_bytes) { - int bytes_left = count - ok_bytes; - int blocks_left = nblocks - i; - int alignedleft; - - // NEW read ahead code: - int ahead = CD_READ_AHEAD_SECTORS; - if (blocks_left < ahead) { - nblocks += (ahead - blocks_left); - blocks_left = ahead; - } - - alignedleft = blocks_left*ss; - - tmpbuf = (char *)VirtualAlloc( - NULL, alignedleft, - MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - if (tmpbuf) { - got_bytes = cd_read_with_retry(fh, (first_block + i) * ss, alignedleft, tmpbuf); - if (got_bytes != alignedleft) { - // should never happen - // Yes it does ... - if (got_bytes < 0) - got_bytes = 0; - if (c_count > got_bytes) - c_count = got_bytes; - if (c_count > 0) { - ttptr = tmpbuf; - memcpy(ptr, ttptr + s_inx, c_count); - ok_bytes += c_count; - } - VirtualFree(tmpbuf, 0, MEM_RELEASE ); - return ok_bytes; - } - ttptr = tmpbuf; - for ( ; i < nblocks; i++) { - if (c_count > 0) { - memcpy(ptr, ttptr + s_inx, c_count); - ok_bytes += c_count; - ptr += c_count; - } - s_inx = 0; - c_count = ss; - if (c_count > count - ok_bytes) - c_count = count - ok_bytes; - cache_put(cptr, first_block + i, ttptr, ss); - ttptr += ss; - } - VirtualFree(tmpbuf, 0, MEM_RELEASE ); - } - } - - return ok_bytes; -} - - -/* - * Check if file handle FH represents a readable CD-ROM - */ - -static bool is_cdrom_readable(file_handle *fh) -{ - if (!fh || !fh->fh) - return false; - - cache_clear(&fh->cache); - - DWORD dummy; - bool result = (0 != DeviceIoControl( - fh->fh, - IOCTL_STORAGE_CHECK_VERIFY, - NULL, 0, - NULL, 0, - &dummy, - NULL)); - if (!result) { - const size_t n_bytes = 2048; - char *buffer = (char *)VirtualAlloc(NULL, n_bytes, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - if (buffer) { - result = (cd_read_with_retry(fh, 0, n_bytes, buffer) == n_bytes); - VirtualFree(buffer, 0, MEM_RELEASE); - } - } - - return result; -} - - -/* - * Check if NAME represents a read-only file - */ - -static bool is_read_only_path(const TCHAR *name) -{ - DWORD attrib = GetFileAttributes(name); - return (attrib != INVALID_FILE_ATTRIBUTES && ((attrib & FILE_ATTRIBUTE_READONLY) != 0)); -} - - -/* - * Open file/device, create new file handle (returns NULL on error) - */ - -void *Sys_open(const char *path_name, bool read_only) -{ - file_handle * fh = NULL; - - // Parse path name and options - TCHAR name[MAX_PATH]; - tcslcpy(name, path_name, lengthof(name)); - - // Normalize floppy / cd path - int name_len = _tcslen(name); - if (name_len == 1 && _istalpha(name[0])) - _tcscat(name, TEXT(":\\")); - if (name_len > 0 && name[name_len - 1] == TEXT(':')) - _tcscat(name, TEXT("\\")); - name_len = _tcslen(name); - - D(bug(TEXT("Sys_open(%s, %s)\n"), name, read_only ? TEXT("read-only") : TEXT("read/write"))); - if (name_len > 0 && name[name_len - 1] == TEXT('\\')) { - int type = GetDriveType(name); - - if (type == DRIVE_CDROM) { - read_only = true; - TCHAR device_name[MAX_PATH]; - _sntprintf(device_name, lengthof(device_name), TEXT("\\\\.\\%c:"), name[0]); - - // Open device - HANDLE h = CreateFile( - device_name, - GENERIC_READ, - 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (h != INVALID_HANDLE_VALUE) { - fh = new file_handle; - fh->name = _tcsdup(name); - fh->fh = h; - fh->is_file = false; - fh->read_only = read_only; - fh->start_byte = 0; - fh->is_floppy = false; - fh->is_cdrom = true; - memset(&fh->cache, 0, sizeof(cachetype)); - cache_init(&fh->cache); - cache_clear(&fh->cache); - if (!PrefsFindBool("nocdrom")) - fh->is_media_present = is_cdrom_readable(fh); - } - } - } - - else { // Hard file - - // Check if write access is allowed, set read-only flag if not - if (!read_only && is_read_only_path(name)) - read_only = true; - - // Open file - HANDLE h = CreateFile( - name, - read_only ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (h == INVALID_HANDLE_VALUE && !read_only) { - // Read-write failed, try read-only - read_only = true; - h = CreateFile( - name, - GENERIC_READ, - 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - } - - if (h != INVALID_HANDLE_VALUE) { - fh = new file_handle; - fh->name = _tcsdup(name); - fh->fh = h; - fh->is_file = true; - fh->read_only = read_only; - fh->start_byte = 0; - fh->is_floppy = false; - fh->is_cdrom = false; - - // Detect disk image file layout - loff_t size = GetFileSize(h, NULL); - DWORD bytes_read; - uint8 data[256]; - ReadFile(h, data, sizeof(data), &bytes_read, NULL); - FileDiskLayout(size, data, fh->start_byte, fh->file_size); - } - } - - if (fh) { - if (fh->is_floppy && first_floppy == NULL) - first_floppy = fh; - sys_add_file_handle(fh); - } - - return fh; -} - - -/* - * Close file/device, delete file handle - */ - -void Sys_close(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - sys_remove_file_handle(fh); - - if (fh->is_cdrom) { - cache_final(&fh->cache); - SysAllowRemoval((void *)fh); - } - if (fh->fh != NULL) { - CloseHandle(fh->fh); - fh->fh = NULL; - } - if (fh->name) - free(fh->name); - - delete fh; -} - - -/* - * Read "length" bytes from file/device, starting at "offset", to "buffer", - * returns number of bytes read (or 0) - */ - -size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return 0; - - DWORD bytes_read = 0; - - if (fh->is_file) { - // Seek to position - LONG lo = (LONG)offset; - LONG hi = (LONG)(offset >> 32); - DWORD r = SetFilePointer(fh->fh, lo, &hi, FILE_BEGIN); - if (r == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) - return 0; - - // Read data - if (ReadFile(fh->fh, buffer, length, &bytes_read, NULL) == 0) - bytes_read = 0; - } - else if (fh->is_cdrom) { - int bytes_left, try_bytes, got_bytes; - char *b = (char *)buffer; - bytes_left = length; - while (bytes_left) { - try_bytes = min(bytes_left, 32768); - if (fh->is_cdrom) { - got_bytes = cd_read(fh, &fh->cache, (DWORD)offset, try_bytes, b); - if (got_bytes != try_bytes && !PrefsFindBool("nocdrom")) - fh->is_media_present = is_cdrom_readable(fh); - } - b += got_bytes; - offset += got_bytes; - bytes_read += got_bytes; - bytes_left -= got_bytes; - if (got_bytes != try_bytes) - bytes_left = 0; - } - } - // TODO: other media - - return bytes_read; -} - - -/* - * Write "length" bytes from "buffer" to file/device, starting at "offset", - * returns number of bytes written (or 0) - */ - -size_t Sys_write(void *arg, void *buffer, loff_t offset, size_t length) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return 0; - - DWORD bytes_written = 0; - - if (fh->is_file) { - // Seek to position - LONG lo = (LONG)offset; - LONG hi = (LONG)(offset >> 32); - DWORD r = SetFilePointer(fh->fh, lo, &hi, FILE_BEGIN); - if (r == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) - return 0; - - // Write data - if (WriteFile(fh->fh, buffer, length, &bytes_written, NULL) == 0) - bytes_written = 0; - } - // TODO: other media - - return bytes_written; -} - - -/* - * Return size of file/device (minus header) - */ - -loff_t SysGetFileSize(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (fh->is_file) - return fh->file_size; - else if (fh->is_cdrom) - return 0x28A00000; // FIXME: get real CD-ROM size - else { - // TODO: other media - return 0; - } -} - - -/* - * Eject volume (if applicable) - */ - -void SysEject(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (fh->is_cdrom && fh->fh) { - fh->is_media_present = false; - // Commented out because there was some problems, but can't remember - // exactly ... need to find out - // EjectVolume(toupper(*fh->name),false); - - // Preventing is cumulative, try to make sure it's indeed released now - for (int i = 0; i < 10; i++) - PreventRemovalOfVolume(fh->fh, false); - - if (!PrefsFindBool("nocdrom")) { - DWORD dummy; - DeviceIoControl( - fh->fh, - IOCTL_STORAGE_EJECT_MEDIA, - NULL, 0, - NULL, 0, - &dummy, - NULL - ); - } - cache_clear(&fh->cache); - fh->start_byte = 0; - } - // TODO: handle floppies -} - - -/* - * Format volume (if applicable) - */ - -bool SysFormat(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - //!! - return true; -} - - -/* - * Check if file/device is read-only (this includes the read-only flag on Sys_open()) - */ - -bool SysIsReadOnly(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - return fh->read_only; -} - - -/* - * Check if the given file handle refers to a fixed or a removable disk - */ - -bool SysIsFixedDisk(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (fh->is_file) - return true; - else if (fh->is_floppy || fh->is_cdrom) - return false; - else - return true; -} - - -/* - * Check if a disk is inserted in the drive (always true for files) - */ - -bool SysIsDiskInserted(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return true; - else if (fh->is_cdrom && !PrefsFindBool("nocdrom")) { - if (PrefsFindBool("pollmedia")) - fh->is_media_present = is_cdrom_readable(fh); - return fh->is_media_present; - } - else { - // TODO: other media - } - - return false; -} - - -/* - * Prevent medium removal (if applicable) - */ - -void SysPreventRemoval(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (fh->is_cdrom && fh->fh) - PreventRemovalOfVolume(fh->fh, true); -} - - -/* - * Allow medium removal (if applicable) - */ - -void SysAllowRemoval(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (fh->is_cdrom && fh->fh) - PreventRemovalOfVolume(fh->fh, false); -} - - -/* - * Read CD-ROM TOC (binary MSF format, 804 bytes max.) - */ - -bool SysCDReadTOC(void *arg, uint8 *toc) -{ - file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) - return false; - - DWORD dummy; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_READ_TOC, - NULL, 0, - toc, min((int)sizeof(CDROM_TOC), 804), - &dummy, - NULL) != FALSE; -} - - -/* - * Read CD-ROM position data (Sub-Q Channel, 16 bytes, see SCSI standard) - */ - -bool SysCDGetPosition(void *arg, uint8 *pos) -{ - file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) - return false; - - SUB_Q_CHANNEL_DATA q_data; - - CDROM_SUB_Q_DATA_FORMAT q_format; - q_format.Format = IOCTL_CDROM_CURRENT_POSITION; - q_format.Track = 0; // used only by ISRC reads - - DWORD dwBytesReturned = 0; - bool ok = DeviceIoControl(fh->fh, - IOCTL_CDROM_READ_Q_CHANNEL, - &q_format, sizeof(CDROM_SUB_Q_DATA_FORMAT), - &q_data, sizeof(SUB_Q_CHANNEL_DATA), - &dwBytesReturned, - NULL) != FALSE; - if (ok) - memcpy(pos, &q_data.CurrentPosition, sizeof(SUB_Q_CURRENT_POSITION)); - - return ok; -} - - -/* - * Play CD audio - */ - -bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end_m, uint8 end_s, uint8 end_f) -{ - file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) - return false; - - CDROM_PLAY_AUDIO_MSF msf; - msf.StartingM = start_m; - msf.StartingS = start_s; - msf.StartingF = start_f; - msf.EndingM = end_m; - msf.EndingS = end_s; - msf.EndingF = end_f; - - DWORD dwBytesReturned = 0; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_PLAY_AUDIO_MSF, - &msf, sizeof(CDROM_PLAY_AUDIO_MSF), - NULL, 0, - &dwBytesReturned, - NULL) != FALSE; -} - - -/* - * Pause CD audio - */ - -bool SysCDPause(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) - return false; - - DWORD dwBytesReturned = 0; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_PAUSE_AUDIO, - NULL, 0, - NULL, 0, - &dwBytesReturned, - NULL) != FALSE; -} - - -/* - * Resume paused CD audio - */ - -bool SysCDResume(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) - return false; - - DWORD dwBytesReturned = 0; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_RESUME_AUDIO, - NULL, 0, - NULL, 0, - &dwBytesReturned, NULL) != FALSE; -} - - -/* - * Stop CD audio - */ - -bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f) -{ - file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) - return false; - - DWORD dwBytesReturned = 0; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_STOP_AUDIO, - NULL, 0, - NULL, 0, - &dwBytesReturned, - NULL) != FALSE; -} - - -/* - * Perform CD audio fast-forward/fast-reverse operation starting from specified address - */ - -bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse) -{ - file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) - return false; - - CDROM_SEEK_AUDIO_MSF msf; - msf.M = start_m; - msf.S = start_s; - msf.F = start_f; - - DWORD dwBytesReturned = 0; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_SEEK_AUDIO_MSF, - &msf, sizeof(CDROM_SEEK_AUDIO_MSF), - NULL, 0, - &dwBytesReturned, - NULL) != FALSE; -} - - -/* - * Set CD audio volume (0..255 each channel) - */ - -void SysCDSetVolume(void *arg, uint8 left, uint8 right) -{ - file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) - return; - - VOLUME_CONTROL vc; - vc.PortVolume[0] = left; - vc.PortVolume[1] = right; - vc.PortVolume[2] = left; - vc.PortVolume[3] = right; - - DWORD dwBytesReturned = 0; - DeviceIoControl(fh->fh, - IOCTL_CDROM_SET_VOLUME, - &vc, sizeof(VOLUME_CONTROL), - NULL, 0, - &dwBytesReturned, - NULL); -} - - -/* - * Get CD audio volume (0..255 each channel) - */ - -void SysCDGetVolume(void *arg, uint8 &left, uint8 &right) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - left = right = 0; - if (!fh->fh || !fh->is_cdrom) - return; - - VOLUME_CONTROL vc; - memset(&vc, 0, sizeof(vc)); - - DWORD dwBytesReturned = 0; - if (DeviceIoControl(fh->fh, - IOCTL_CDROM_GET_VOLUME, - NULL, 0, - &vc, sizeof(VOLUME_CONTROL), - &dwBytesReturned, - NULL)) - { - left = vc.PortVolume[0]; - right = vc.PortVolume[1]; - } -} diff --git a/BasiliskII/src/Windows/sysdeps.h b/BasiliskII/src/Windows/sysdeps.h deleted file mode 100755 index c1d7898f..00000000 --- a/BasiliskII/src/Windows/sysdeps.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * sysdeps.h - System dependent definitions for Windows - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SYSDEPS_H -#define SYSDEPS_H - -#if !defined _MSC_VER && !defined __STDC__ -#error "Your compiler is not ANSI. Get a real one." -#endif - -#include "config.h" -#include "user_strings_windows.h" - -#ifndef STDC_HEADERS -#error "You don't have ANSI C header files." -#endif - -#ifndef WIN32 -#define WIN32 -#endif - -#include -#include -#include -#include -#include -#include -#define WIN32_LEAN_AND_MEAN -#include -#include -#include - - -/* Mac and host address space are distinct */ -#ifndef REAL_ADDRESSING -#define REAL_ADDRESSING 0 -#endif -#if REAL_ADDRESSING -#error "Real Addressing mode can't work without proper kernel support" -#endif - -/* Using 68k emulator */ -#define EMULATED_68K 1 - -/* The m68k emulator uses a prefetch buffer ? */ -#define USE_PREFETCH_BUFFER 0 - -/* Mac ROM is write protected when banked memory is used */ -#if REAL_ADDRESSING || DIRECT_ADDRESSING -# define ROM_IS_WRITE_PROTECTED 0 -# define USE_SCRATCHMEM_SUBTERFUGE 1 -#else -# define ROM_IS_WRITE_PROTECTED 1 -#endif - -/* Direct Addressing requires Video on SEGV signals in plain X11 mode */ -#if DIRECT_ADDRESSING && (!ENABLE_VOSF && !USE_SDL_VIDEO) -# undef ENABLE_VOSF -# define ENABLE_VOSF 1 -#endif - -/* ExtFS is supported */ -#define SUPPORTS_EXTFS 1 - -/* POSIX data types missing from Microsoft's CRT */ -#ifdef _MSC_VER -typedef ptrdiff_t ssize_t; -#endif - -/* Data types */ -typedef unsigned char uint8; -typedef signed char int8; -#if SIZEOF_SHORT == 2 -typedef unsigned short uint16; -typedef short int16; -#elif SIZEOF_INT == 2 -typedef unsigned int uint16; -typedef int int16; -#else -#error "No 2 byte type, you lose." -#endif -#if SIZEOF_INT == 4 -typedef unsigned int uint32; -typedef int int32; -#elif SIZEOF_LONG == 4 -typedef unsigned long uint32; -typedef long int32; -#else -#error "No 4 byte type, you lose." -#endif -#if SIZEOF_LONG == 8 -typedef unsigned long uint64; -typedef long int64; -#define VAL64(a) (a ## l) -#define UVAL64(a) (a ## ul) -#elif SIZEOF_LONG_LONG == 8 -typedef unsigned long long uint64; -typedef long long int64; -#define VAL64(a) (a ## LL) -#define UVAL64(a) (a ## uLL) -#else -#error "No 8 byte type, you lose." -#endif -#if SIZEOF_VOID_P == 4 -typedef uint32 uintptr; -typedef int32 intptr; -#elif SIZEOF_VOID_P == 8 -typedef uint64 uintptr; -typedef int64 intptr; -#else -#error "Unsupported size of pointer" -#endif - -#ifdef _WIN32 -typedef int64 loff_t; -#endif -#ifndef HAVE_CADDR_T -typedef char * caddr_t; -#endif - -#ifdef _MSC_VER -#ifdef _M_IX86 -#define __i386__ -#elif defined _M_AMD64 -#define __x86_64__ -#endif -#endif - -/* Time data type for Time Manager emulation */ -typedef int64 tm_time_t; - -/* Define codes for all the float formats that we know of. - * Though we only handle IEEE format. */ -#define UNKNOWN_FLOAT_FORMAT 0 -#define IEEE_FLOAT_FORMAT 1 -#define VAX_FLOAT_FORMAT 2 -#define IBM_FLOAT_FORMAT 3 -#define C4X_FLOAT_FORMAT 4 - -/* UAE CPU data types */ -#define uae_s8 int8 -#define uae_u8 uint8 -#define uae_s16 int16 -#define uae_u16 uint16 -#define uae_s32 int32 -#define uae_u32 uint32 -#define uae_s64 int64 -#define uae_u64 uint64 -typedef uae_u32 uaecptr; - -/* Timing functions */ -extern void timer_init(void); -extern uint64 GetTicks_usec(void); -extern void Delay_usec(uint32 usec); - -/* Spinlocks */ -#ifdef __GNUC__ -#define HAVE_TEST_AND_SET 1 -static inline int testandset(volatile int *p) -{ - long int ret; - /* Note: the "xchg" instruction does not need a "lock" prefix */ - __asm__ __volatile__("xchgl %k0, %1" - : "=r" (ret), "=m" (*p) - : "0" (1), "m" (*p) - : "memory"); - return ret; -} -#endif /* __GNUC__ */ - -typedef volatile int spinlock_t; - -static const spinlock_t SPIN_LOCK_UNLOCKED = 0; - -#if HAVE_TEST_AND_SET -#define HAVE_SPINLOCKS 1 -static inline void spin_lock(spinlock_t *lock) -{ - while (testandset(lock)); -} - -static inline void spin_unlock(spinlock_t *lock) -{ - *lock = 0; -} - -static inline int spin_trylock(spinlock_t *lock) -{ - return !testandset(lock); -} -#else -static inline void spin_lock(spinlock_t *lock) -{ -} - -static inline void spin_unlock(spinlock_t *lock) -{ -} - -static inline int spin_trylock(spinlock_t *lock) -{ - return 1; -} -#endif - -#define X86_PPRO_OPT -#define HAVE_OPTIMIZED_BYTESWAP_32 -#define HAVE_OPTIMIZED_BYTESWAP_16 - -#ifdef _MSC_VER -static inline uae_u32 do_get_mem_long(uae_u32 *a) {return _byteswap_ulong(*a);} -static inline uae_u32 do_get_mem_word(uae_u16 *a) {return _byteswap_ushort(*a);} -static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {*a = _byteswap_ulong(v);} -static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {*a = _byteswap_ushort(v);} -static inline uae_u32 do_byteswap_32_g(uae_u32 v) {return _byteswap_ulong(v);} -static inline uae_u32 do_byteswap_16_g(uae_u32 v) {return _byteswap_ushort(v);} -#else -/* Intel x86 */ -static inline uae_u32 do_get_mem_long(uae_u32 *a) {uint32 retval; __asm__ ("bswap %0" : "=r" (retval) : "0" (*a) : "cc"); return retval;} -#ifdef X86_PPRO_OPT -static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint32 retval; __asm__ ("movzwl %w1,%k0\n\tshll $16,%k0\n\tbswapl %k0\n" : "=&r" (retval) : "m" (*a) : "cc"); return retval;} -#else -static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint32 retval; __asm__ ("xorl %k0,%k0\n\tmovw %w1,%w0\n\trolw $8,%w0" : "=&r" (retval) : "m" (*a) : "cc"); return retval;} -#endif -static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {__asm__ ("bswap %0" : "=r" (v) : "0" (v) : "cc"); *a = v;} -#ifdef X86_PPRO_OPT -static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {__asm__ ("bswapl %0" : "=&r" (v) : "0" (v << 16) : "cc"); *a = v;} -#else -static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {__asm__ ("rolw $8,%0" : "=r" (v) : "0" (v) : "cc"); *a = v;} -#endif -/* bswap doesn't affect condition codes */ -static inline uae_u32 do_byteswap_32_g(uae_u32 v) {__asm__ ("bswap %0" : "=r" (v) : "0" (v)); return v;} -#ifdef X86_PPRO_OPT -static inline uae_u32 do_byteswap_16_g(uae_u32 v) {__asm__ ("bswapl %0" : "=&r" (v) : "0" (v << 16) : "cc"); return v;} -#else -static inline uae_u32 do_byteswap_16_g(uae_u32 v) {__asm__ ("rolw $8,%0" : "=r" (v) : "0" (v) : "cc"); return v;} -#endif -#endif - -#define HAVE_GET_WORD_UNSWAPPED -#define do_get_mem_word_unswapped(a) ((uae_u32)*((uae_u16 *)(a))) - -#ifndef HAVE_OPTIMIZED_BYTESWAP_32 -static inline uae_u32 do_byteswap_32_g(uae_u32 v) - { return (((v >> 24) & 0xff) | ((v >> 8) & 0xff00) | ((v & 0xff) << 24) | ((v & 0xff00) << 8)); } -#endif - -#ifndef HAVE_OPTIMIZED_BYTESWAP_16 -static inline uae_u32 do_byteswap_16_g(uae_u32 v) - { return (((v >> 8) & 0xff) | ((v & 0xff) << 8)); } -#endif - -#define do_byteswap_16_c(x) \ - ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) - -#define do_byteswap_32_c(x) \ - ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ - (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) - -#if defined(__GNUC__) -#define do_byteswap_16(x) \ - (__extension__ \ - ({ register uint16 __v, __x = (x); \ - if (__builtin_constant_p(__x)) \ - __v = do_byteswap_16_c(__x); \ - else \ - __v = do_byteswap_16_g(__x); \ - __v; })) - -#define do_byteswap_32(x) \ - (__extension__ \ - ({ register uint32 __v, __x = (x); \ - if (__builtin_constant_p(__x)) \ - __v = do_byteswap_32_c(__x); \ - else \ - __v = do_byteswap_32_g(__x); \ - __v; })) -#else -#define do_byteswap_16(x) do_byteswap_16_g(x) -#define do_byteswap_32(x) do_byteswap_32_g(x) -#endif - -/* Byte-swapping routines */ -#if defined(__i386__) || defined(__x86_64__) -#define ntohl(x) do_byteswap_32(x) -#define ntohs(x) do_byteswap_16(x) -#define htonl(x) do_byteswap_32(x) -#define htons(x) do_byteswap_16(x) -#endif - -#define do_get_mem_byte(a) ((uae_u32)*((uae_u8 *)(a))) -#define do_put_mem_byte(a, v) (*(uae_u8 *)(a) = (v)) - -#define call_mem_get_func(func, addr) ((*func)(addr)) -#define call_mem_put_func(func, addr, v) ((*func)(addr, v)) -#define __inline__ inline -#define CPU_EMU_SIZE 0 -#undef NO_INLINE_MEMORY_ACCESS -#undef MD_HAVE_MEM_1_FUNCS -#define ENUMDECL typedef enum -#define ENUMNAME(name) name -#define write_log printf - -#if defined(X86_ASSEMBLY) || defined(X86_64_ASSEMBLY) -#define ASM_SYM(a) __asm__(a) -#else -#define ASM_SYM(a) -#endif - -#ifndef REGPARAM -# define REGPARAM -#endif -#define REGPARAM2 - -#ifdef _MSC_VER -#define ATTRIBUTE_PACKED -#endif - -#endif diff --git a/BasiliskII/src/Windows/timer_windows.cpp b/BasiliskII/src/Windows/timer_windows.cpp deleted file mode 100755 index d0aed8ac..00000000 --- a/BasiliskII/src/Windows/timer_windows.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* - * timer_windows.cpp - Time Manager emulation, Windows specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include "main.h" -#include "macos_util.h" -#include "timer.h" - -#define DEBUG 0 -#include "debug.h" - - -// Helper time functions -#define MSECS2TICKS(MSECS) (((uint64)(MSECS) * frequency) / 1000) -#define USECS2TICKS(USECS) (((uint64)(USECS) * frequency) / 1000000) -#define TICKS2USECS(TICKS) (((uint64)(TICKS) * 1000000) / frequency) - -// From main_windows.cpp -extern HANDLE emul_thread; - -// Global variables -static uint32 frequency; // CPU frequency in Hz (< 4 GHz) -static tm_time_t mac_boot_ticks; -static tm_time_t mac_1904_ticks; -static tm_time_t mac_now_diff; - - -/* - * Initialize native Windows timers - */ - -void timer_init(void) -{ - D(bug("SysTimerInit\n")); - - LARGE_INTEGER tt; - if (!QueryPerformanceFrequency(&tt)) { - ErrorAlert("No high resolution timers available\n"); - QuitEmulator(); - } - frequency = tt.LowPart; - D(bug(" frequency %d\n", frequency)); - - // mac_boot_ticks is 1.18 us since Basilisk II was started - QueryPerformanceCounter(&tt); - mac_boot_ticks = tt.QuadPart; - - // mac_1904_ticks is 1.18 us since Mac time started 1904 - mac_1904_ticks = time(NULL) * frequency; - mac_now_diff = mac_1904_ticks - mac_boot_ticks; -} - - - /* - * Return microseconds since boot (64 bit) - */ - -void Microseconds(uint32 &hi, uint32 &lo) -{ - D(bug("Microseconds\n")); - LARGE_INTEGER tt; - QueryPerformanceCounter(&tt); - tt.QuadPart = TICKS2USECS(tt.QuadPart - mac_boot_ticks); - hi = tt.HighPart; - lo = tt.LowPart; -} - - -/* - * Return local date/time in Mac format (seconds since 1.1.1904) - */ - -uint32 TimerDateTime(void) -{ - return TimeToMacTime(time(NULL)); -} - - -/* - * Get current time - */ - -void timer_current_time(tm_time_t &t) -{ - LARGE_INTEGER tt; - QueryPerformanceCounter(&tt); - t = tt.QuadPart + mac_now_diff; -} - - -/* - * Add times - */ - -void timer_add_time(tm_time_t &res, tm_time_t a, tm_time_t b) -{ - res = a + b; -} - - -/* - * Subtract times - */ - -void timer_sub_time(tm_time_t &res, tm_time_t a, tm_time_t b) -{ - res = a - b; -} - - -/* - * Compare times (<0: a < b, =0: a = b, >0: a > b) - */ - -int timer_cmp_time(tm_time_t a, tm_time_t b) -{ - tm_time_t r = a - b; - return r < 0 ? -1 : (r > 0 ? 1 : 0); -} - - -/* - * Convert Mac time value (>0: microseconds, <0: microseconds) to tm_time_t - */ - -void timer_mac2host_time(tm_time_t &res, int32 mactime) -{ - if (mactime > 0) { - // Time in milliseconds - res = MSECS2TICKS(mactime); - } else { - // Time in negative microseconds - res = USECS2TICKS(-mactime); - } -} - - -/* - * Convert positive tm_time_t to Mac time value (>0: microseconds, <0: microseconds) - * A negative input value for hosttime results in a zero return value - * As long as the microseconds value fits in 32 bit, it must not be converted to milliseconds! - */ - -int32 timer_host2mac_time(tm_time_t hosttime) -{ - if (hosttime < 0) - return 0; - else { - uint64 t = TICKS2USECS(hosttime); - if (t > 0x7fffffff) - return int32(t / 1000); // Time in milliseconds - else - return -int32(t); // Time in negative microseconds - } -} - - -/* - * Get current value of microsecond timer - */ - -uint64 GetTicks_usec(void) -{ - LARGE_INTEGER tt; - QueryPerformanceCounter(&tt); - return TICKS2USECS(tt.QuadPart - mac_boot_ticks); -} - - -/* - * Delay by specified number of microseconds (<1 second) - */ - -void Delay_usec(uint32 usec) -{ - // FIXME: fortunately, Delay_usec() is generally used with - // millisecond resolution anyway - Sleep(usec / 1000); -} - - -/* - * Suspend emulator thread, virtual CPU in idle mode - */ - -struct idle_sentinel { - idle_sentinel(); - ~idle_sentinel(); -}; -static idle_sentinel idle_sentinel; - -static int idle_sem_ok = -1; -static HANDLE idle_sem = NULL; - -static HANDLE idle_lock = NULL; -#define LOCK_IDLE WaitForSingleObject(idle_lock, INFINITE) -#define UNLOCK_IDLE ReleaseMutex(idle_lock) - -idle_sentinel::idle_sentinel() -{ - idle_sem_ok = 1; - if ((idle_sem = CreateSemaphore(0, 0, 1, NULL)) == NULL) - idle_sem_ok = 0; - if ((idle_lock = CreateMutex(NULL, FALSE, NULL)) == NULL) - idle_sem_ok = 0; -} - -idle_sentinel::~idle_sentinel() -{ - if (idle_lock) { - ReleaseMutex(idle_lock); - CloseHandle(idle_lock); - } - if (idle_sem) { - ReleaseSemaphore(idle_sem, 1, NULL); - CloseHandle(idle_sem); - } -} - -void idle_wait(void) -{ - LOCK_IDLE; - if (idle_sem_ok > 0) { - idle_sem_ok++; - UNLOCK_IDLE; - WaitForSingleObject(idle_sem, INFINITE); - return; - } - UNLOCK_IDLE; - - // Fallback: sleep 10 ms (this should not happen though) - Delay_usec(10000); -} - - -/* - * Resume execution of emulator thread, events just arrived - */ - -void idle_resume(void) -{ - LOCK_IDLE; - if (idle_sem_ok > 1) { - idle_sem_ok--; - UNLOCK_IDLE; - ReleaseSemaphore(idle_sem, 1, NULL); - return; - } - UNLOCK_IDLE; -} diff --git a/BasiliskII/src/Windows/user_strings_windows.cpp b/BasiliskII/src/Windows/user_strings_windows.cpp deleted file mode 100755 index c2241250..00000000 --- a/BasiliskII/src/Windows/user_strings_windows.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * user_strings_windows.cpp - Windows-specific localizable strings - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "user_strings.h" - - -// Platform-specific string definitions -user_string_def platform_strings[] = { - // Common strings that have a platform-specific variant - {STR_VOLUME_IS_MOUNTED_WARN, "The volume '%s' is mounted under Unix. Basilisk II will try to unmount it."}, - {STR_EXTFS_VOLUME_NAME, "My Computer"}, - - // Purely platform-specific strings - {STR_NO_XVISUAL_ERR, "Cannot obtain appropriate X visual."}, - {STR_VOSF_INIT_ERR, "Cannot initialize Video on SEGV signals."}, - {STR_SIG_INSTALL_ERR, "Cannot install %s handler (%s)."}, - {STR_TICK_THREAD_ERR, "Cannot create 60Hz thread (%s)."}, - {STR_SLIRP_NO_DNS_FOUND_WARN, "Cannot get DNS address. Ethernet will not be available."}, - {STR_NO_AUDIO_WARN, "No audio device found, audio output will be disabled."}, - {STR_KEYCODE_FILE_WARN, "Cannot open keycode translation file %s (%s)."}, - {STR_KEYCODE_VENDOR_WARN, "Cannot find vendor '%s' in keycode translation file %s."}, - {STR_WINDOW_TITLE_GRABBED, "Basilisk II (mouse grabbed, press Ctrl-F5 to release)"}, - {STR_NO_WIN32_NT_4, "Basilisk II does not run on Windows NT versions less than 4.0"}, - - {STR_PREFS_MENU_FILE_GTK, "/_File"}, - {STR_PREFS_ITEM_START_GTK, "/File/_Start Basilisk II"}, - {STR_PREFS_ITEM_ZAP_PRAM_GTK, "/File/_Zap PRAM File"}, - {STR_PREFS_ITEM_SEPL_GTK, "/File/sepl"}, - {STR_PREFS_ITEM_QUIT_GTK, "/File/_Quit Basilisk II"}, - {STR_HELP_MENU_GTK, "/_Help"}, - {STR_HELP_ITEM_ABOUT_GTK, "/Help/_About Basilisk II"}, - - {STR_ABOUT_BUTTON, "About"}, - {STR_FILE_CTRL, "File"}, - {STR_BROWSE_TITLE, "Browse file"}, - {STR_BROWSE_CTRL, "Browse..."}, - {STR_SERIAL_PANE_TITLE, "Serial"}, - {STR_NETWORK_PANE_TITLE, "Network"}, - {STR_INPUT_PANE_TITLE, "Keyboard/Mouse"}, - {STR_KEYCODES_CTRL, "Use Raw Keycodes"}, - {STR_KEYCODE_FILE_CTRL, "Keycode Translation File"}, - {STR_MOUSEWHEELMODE_CTRL, "Mouse Wheel Function"}, - {STR_MOUSEWHEELMODE_PAGE_LAB, "Page Up/Down"}, - {STR_MOUSEWHEELMODE_CURSOR_LAB, "Cursor Up/Down"}, - {STR_MOUSEWHEELLINES_CTRL, "Lines To Scroll"}, - {STR_POLLMEDIA_CTRL, "Try to automatically detect new removable media (enable polling)"}, - {STR_EXTFS_ENABLE_CTRL, "Enable \"My Computer\" icon on your Mac desktop (external file system)"}, - {STR_EXTFS_DRIVES_CTRL, "Mount drives"}, - {STR_ETHER_FTP_PORT_LIST_CTRL, "FTP ports"}, - {STR_ETHER_TCP_PORT_LIST_CTRL, "Server ports"}, - - {STR_IGNORESEGV_CTRL, "Ignore Illegal Memory Accesses"}, - - {-1, NULL} // End marker -}; - - -/* - * Search for main volume name - */ - -static const char *get_volume_name(void) -{ - HKEY hHelpKey; - DWORD key_type, cbData; - - static char volume[256]; - memset(volume, 0, sizeof(volume)); - - // Try Windows 2000 key first - if (ERROR_SUCCESS == RegOpenKey( - HKEY_CURRENT_USER, - TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}"), - &hHelpKey)) - { - cbData = sizeof(volume); - RegQueryValueEx( hHelpKey, 0, NULL, &key_type, (unsigned char *)volume, &cbData ); - RegCloseKey(hHelpKey); - } - - if (volume[0] == 0 && - ERROR_SUCCESS == RegOpenKey( - HKEY_CURRENT_USER, - TEXT("Software\\Classes\\CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}"), - &hHelpKey)) - { - cbData = sizeof(volume); - RegQueryValueEx( hHelpKey, 0, NULL, &key_type, (unsigned char *)volume, &cbData ); - RegCloseKey(hHelpKey); - } - - if (volume[0] == 0 && - ERROR_SUCCESS == RegOpenKey( - HKEY_CLASSES_ROOT, - TEXT("CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}"), - &hHelpKey)) - { - cbData = sizeof(volume); - RegQueryValueEx( hHelpKey, 0, NULL, &key_type, (unsigned char *)volume, &cbData ); - RegCloseKey(hHelpKey); - } - - // Fix the error that some "tweak" apps do. - if (_stricmp(volume, "%USERNAME% on %COMPUTER%") == 0) - volume[0] = '\0'; - - // No volume name found, default to "My Computer" - if (volume[0] == 0) - strcpy(volume, "My Computer"); - - return volume; -} - - -/* - * Fetch pointer to string, given the string number - */ - -const char *GetString(int num) -{ - // First, search for platform-specific variable string - switch (num) { - case STR_EXTFS_VOLUME_NAME: - return get_volume_name(); - } - - // Next, search for platform-specific constant string - int i = 0; - while (platform_strings[i].num >= 0) { - if (platform_strings[i].num == num) - return platform_strings[i].str; - i++; - } - - // Not found, search for common string - i = 0; - while (common_strings[i].num >= 0) { - if (common_strings[i].num == num) - return common_strings[i].str; - i++; - } - return NULL; -} - -/* - * Convert text to wide string, given the string number - */ -std::unique_ptr GetStringW(int num) -{ - auto str = GetString(num); - if (str == nullptr) - return nullptr; - - auto length = MultiByteToWideChar(CP_ACP, 0, str, -1, nullptr, 0); - if (length == 0) - return nullptr; - - auto p = std::unique_ptr(new wchar_t[length]); - MultiByteToWideChar(CP_ACP, 0, str, -1, p.get(), length); - return p; -} diff --git a/BasiliskII/src/Windows/user_strings_windows.h b/BasiliskII/src/Windows/user_strings_windows.h deleted file mode 100755 index ccf5ff54..00000000 --- a/BasiliskII/src/Windows/user_strings_windows.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * user_strings_windows.h - Windows-specific localizable strings - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef USER_STRINGS_WINDOWS_H -#define USER_STRINGS_WINDOWS_H - -#ifdef __cplusplus -#if __cplusplus >= 201103L || _MSC_VER >= 1600 -#include - - // Convert text to wide string, given the string number -extern std::unique_ptr GetStringW(int num); -#endif -#endif - -enum { - STR_NO_XVISUAL_ERR = 10000, - STR_VOSF_INIT_ERR, - STR_SIG_INSTALL_ERR, - STR_TICK_THREAD_ERR, - STR_SLIRP_NO_DNS_FOUND_WARN, - STR_NO_AUDIO_WARN, - STR_KEYCODE_FILE_WARN, - STR_KEYCODE_VENDOR_WARN, - STR_WINDOW_TITLE_GRABBED, - STR_NO_WIN32_NT_4, - - STR_PREFS_MENU_FILE_GTK, - STR_PREFS_ITEM_START_GTK, - STR_PREFS_ITEM_ZAP_PRAM_GTK, - STR_PREFS_ITEM_SEPL_GTK, - STR_PREFS_ITEM_QUIT_GTK, - STR_HELP_MENU_GTK, - STR_HELP_ITEM_ABOUT_GTK, - - STR_ABOUT_BUTTON, - STR_FILE_CTRL, - STR_BROWSE_CTRL, - STR_BROWSE_TITLE, - STR_SERIAL_PANE_TITLE, - STR_NETWORK_PANE_TITLE, - STR_INPUT_PANE_TITLE, - STR_KEYCODES_CTRL, - STR_KEYCODE_FILE_CTRL, - STR_MOUSEWHEELMODE_CTRL, - STR_MOUSEWHEELMODE_PAGE_LAB, - STR_MOUSEWHEELMODE_CURSOR_LAB, - STR_MOUSEWHEELLINES_CTRL, - STR_POLLMEDIA_CTRL, - STR_EXTFS_ENABLE_CTRL, - STR_EXTFS_DRIVES_CTRL, - STR_ETHER_FTP_PORT_LIST_CTRL, - STR_ETHER_TCP_PORT_LIST_CTRL, - - STR_IGNORESEGV_CTRL, -}; - -#endif diff --git a/BasiliskII/src/Windows/util_windows.cpp b/BasiliskII/src/Windows/util_windows.cpp deleted file mode 100755 index ef29a06b..00000000 --- a/BasiliskII/src/Windows/util_windows.cpp +++ /dev/null @@ -1,510 +0,0 @@ -/* - * util_windows.cpp - Miscellaneous utilities for Win32 - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "util_windows.h" -#include "main.h" -#include -#include - -#include -using std::list; - -#include -using std::string; -using std::wstring; -typedef std::basic_string tstring; - -std::unique_ptr str(const wchar_t* s) -{ - auto length = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); - if (length == -1) - return nullptr; - - std::unique_ptr p(new char[length]); - WideCharToMultiByte(CP_ACP, 0, s, -1, p.get(), length, nullptr, nullptr); - return p; -} - -std::unique_ptr wstr(const char* s) -{ - auto length = MultiByteToWideChar(CP_ACP, 0, s, -1, nullptr, 0); - if (length == -1) - return nullptr; - - std::unique_ptr p(new wchar_t[length]); - MultiByteToWideChar(CP_ACP, 0, s, -1, p.get(), length); - return p; -} - -string to_string(const wchar_t* s) -{ - auto wlen = wcslen(s); // length without null terminator - auto len = WideCharToMultiByte(CP_ACP, 0, s, wlen, nullptr, 0, nullptr, nullptr); - if (len == -1) - return string(); - - string str(len, '\0'); - WideCharToMultiByte(CP_ACP, 0, s, wlen, &str.front(), len, nullptr, nullptr); - return str; -} - -wstring to_wstring(const char* s) -{ - auto len = strlen(s); // length without null terminator - auto wlen = MultiByteToWideChar(CP_ACP, 0, s, len, nullptr, 0); - if (len == -1) - return wstring(); - - wstring str(wlen, L'\0'); - MultiByteToWideChar(CP_ACP, 0, s, len, &str.front(), wlen); - return str; -} - -size_t strlcpy(char* dst, const char* src, size_t size) -{ - size_t length = strlen(src); - if (size-- > 0) { - if (length < size) - size = length; - memcpy(dst, src, size); - dst[size] = '\0'; - } - return length; -} - -size_t strlcpy(char* dst, const wchar_t* src, size_t size) -{ - size_t length = WideCharToMultiByte(CP_ACP, 0, src, -1, dst, size, nullptr, nullptr); - if (size > 0) { - if (length == 0) - return strlcpy(dst, str(src).get(), size); - --length; - } - return length; -} - -size_t strlcat(char* dst, const char* src, size_t size) -{ - char* end = static_cast(memchr(dst, '\0', size)); - if (end == nullptr) - return size; - size_t length = end - dst; - return length + strlcpy(end, src, size - length); -} - -size_t strlcat(char* dst, const wchar_t* src, size_t size) -{ - char* end = static_cast(memchr(dst, '\0', size)); - if (end == nullptr) - return size; - size_t length = end - dst; - return length + strlcpy(end, src, size - length); -} - -size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t size) -{ - size_t length = wcslen(src); - if (size-- > 0) { - if (length < size) - size = length; - wmemcpy(dst, src, size); - dst[size] = '\0'; - } - return length; -} - -size_t wcslcpy(wchar_t* dst, const char* src, size_t size) -{ - size_t length = MultiByteToWideChar(CP_ACP, 0, src, -1, dst, size); - if (size > 0) { - if (length == 0) - return wcslcpy(dst, wstr(src).get(), size); - --length; - } - return length; -} - -size_t wcslcat(wchar_t* dst, const wchar_t* src, size_t size) -{ - wchar_t* end = wmemchr(dst, L'\0', size); - if (end == nullptr) - return size; - size_t length = end - dst; - return length + wcslcpy(end, src, size - length); -} - -size_t wcslcat(wchar_t* dst, const char* src, size_t size) -{ - wchar_t* end = wmemchr(dst, L'\0', size); - if (end == nullptr) - return size; - size_t length = end - dst; - return length + wcslcpy(end, src, size - length); -} - -BOOL exists( const TCHAR *path ) -{ - HFILE h; - bool ret = false; - - h = _topen( path, _O_RDONLY | _O_BINARY ); - if(h != -1) { - ret = true; - _close(h); - } - return(ret); -} - -BOOL create_file( const TCHAR *path, DWORD size ) -{ - HANDLE h; - bool ok = false; - - h = CreateFile( path, - GENERIC_READ | GENERIC_WRITE, - 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL - ); - if(h != INVALID_HANDLE_VALUE) { - if(size == 0) { - ok = true; - } else if(SetFilePointer( h, size, NULL, FILE_BEGIN) != 0xFFFFFFFF) { - if(SetEndOfFile(h)) { - ok = true; - if(SetFilePointer( h, 0, NULL, FILE_BEGIN) != 0xFFFFFFFF) { - DWORD written; - DWORD zeroed_size = size; - if (zeroed_size > 1024*1024) - zeroed_size = 1024*1024; - char *b = (char *)malloc(zeroed_size); - if(b) { - memset( b, 0, zeroed_size ); - WriteFile( h, b, zeroed_size, &written, NULL ); - free(b); - } - } - } - } - CloseHandle(h); - } - if(!ok) DeleteFile(path); - return(ok); -} - -int32 get_file_size( const TCHAR *path ) -{ - HANDLE h; - DWORD size = 0; - - h = CreateFile( path, - GENERIC_READ, - 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL - ); - if(h != INVALID_HANDLE_VALUE) { - size = GetFileSize( h, NULL ); - CloseHandle(h); - } - return(size); -} - - -/* - * Thread wrappers - */ - -HANDLE create_thread(LPTHREAD_START_ROUTINE start_routine, void *arg) -{ - DWORD dwThreadId; - return CreateThread(NULL, 0, start_routine, arg, 0, &dwThreadId); -} - -void wait_thread(HANDLE thread) -{ - WaitForSingleObject(thread, INFINITE); - CloseHandle(thread); -} - -void kill_thread(HANDLE thread) -{ - TerminateThread(thread, 0); -} - - -/* - * Check that drivers are installed - */ - -bool check_drivers(void) -{ - TCHAR path[_MAX_PATH]; - GetSystemDirectory(path, lengthof(path)); - _tcscat(path, TEXT("\\drivers\\cdenable.sys")); - - if (exists(path)) { - int32 size = get_file_size(path); - if (size != 6112) { - TCHAR str[256]; - _sntprintf(str, lengthof(str), TEXT("The CD-ROM driver file \"%s\" is too old or corrupted."), path); - ErrorAlert(str); - return false; - } - } - else { - TCHAR str[256]; - _sntprintf(str, lengthof(str), TEXT("The CD-ROM driver file \"%s\" is missing."), path); - WarningAlert(str); - } - - return true; -} - - -/* - * Network control panel helpers - */ - -struct panel_reg { - tstring name; - tstring guid; -}; - -static list network_registry; -typedef list::const_iterator network_registry_iterator; - -#define NETWORK_CONNECTIONS_KEY \ - TEXT("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}") - -static void get_network_registry(void) -{ - LONG status; - HKEY network_connections_key; - DWORD len; - int i = 0; - - if (network_registry.size() > 0) - return; - - status = RegOpenKeyEx( - HKEY_LOCAL_MACHINE, - NETWORK_CONNECTIONS_KEY, - 0, - KEY_READ, - &network_connections_key); - - if (status != ERROR_SUCCESS) - return; - - while (true) { - TCHAR enum_name[256]; - TCHAR connection_string[256]; - HKEY connection_key; - TCHAR name_data[256]; - DWORD name_type; - const TCHAR name_string[] = TEXT("Name"); - - len = lengthof(enum_name); - status = RegEnumKeyEx( - network_connections_key, - i, - enum_name, - &len, - NULL, - NULL, - NULL, - NULL); - if (status != ERROR_SUCCESS) - break; - - _sntprintf (connection_string, lengthof(connection_string), - TEXT("%s\\%s\\Connection"), - NETWORK_CONNECTIONS_KEY, enum_name); - - status = RegOpenKeyEx( - HKEY_LOCAL_MACHINE, - connection_string, - 0, - KEY_READ, - &connection_key); - - if (status == ERROR_SUCCESS) { - len = lengthof(name_data); - status = RegQueryValueEx( - connection_key, - name_string, - NULL, - &name_type, - (BYTE *)name_data, - &len); - - if (status == ERROR_SUCCESS && name_type == REG_SZ) { - panel_reg pr; - pr.name = name_data; - pr.guid = enum_name; - network_registry.push_back(pr); - } - RegCloseKey (connection_key); - } - ++i; - } - - RegCloseKey (network_connections_key); -} - -const TCHAR *ether_name_to_guid(const TCHAR *name) -{ - get_network_registry(); - - for (network_registry_iterator it = network_registry.begin(); it != network_registry.end(); it++) { - if (_tcscmp((*it).name.c_str(), name) == 0) - return (*it).guid.c_str(); - } - - return NULL; -} - -const TCHAR *ether_guid_to_name(const TCHAR *guid) -{ - get_network_registry(); - - for (network_registry_iterator it = network_registry.begin(); it != network_registry.end(); it++) { - if (_tcscmp((*it).guid.c_str(), guid) == 0) - return (*it).name.c_str(); - } - - return NULL; -} - - -/* - * Get TAP-Win32 adapters - */ - -#define ADAPTER_KEY TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}") - -#define TAP_COMPONENT_ID TEXT("tap0801") - -const TCHAR *ether_tap_devices(void) -{ - HKEY adapter_key; - LONG status; - DWORD len; - int i = 0; - - status = RegOpenKeyEx( - HKEY_LOCAL_MACHINE, - ADAPTER_KEY, - 0, - KEY_READ, - &adapter_key); - - if (status != ERROR_SUCCESS) - return NULL; - - list devices; - - while (true) { - TCHAR enum_name[256]; - TCHAR unit_string[256]; - HKEY unit_key; - TCHAR component_id_string[] = TEXT("ComponentId"); - TCHAR component_id[256]; - TCHAR net_cfg_instance_id_string[] = TEXT("NetCfgInstanceId"); - TCHAR net_cfg_instance_id[256]; - DWORD data_type; - - len = lengthof(enum_name); - status = RegEnumKeyEx( - adapter_key, - i, - enum_name, - &len, - NULL, - NULL, - NULL, - NULL); - if (status != ERROR_SUCCESS) - break; - - _sntprintf (unit_string, lengthof(unit_string), TEXT("%s\\%s"), - ADAPTER_KEY, enum_name); - - status = RegOpenKeyEx( - HKEY_LOCAL_MACHINE, - unit_string, - 0, - KEY_READ, - &unit_key); - - if (status == ERROR_SUCCESS) { - len = lengthof(component_id); - status = RegQueryValueEx( - unit_key, - component_id_string, - NULL, - &data_type, - (BYTE *)component_id, - &len); - - if (status == ERROR_SUCCESS && data_type == REG_SZ) { - len = lengthof(net_cfg_instance_id); - status = RegQueryValueEx( - unit_key, - net_cfg_instance_id_string, - NULL, - &data_type, - (BYTE *)net_cfg_instance_id, - &len); - - if (status == ERROR_SUCCESS && data_type == REG_SZ) { - if (!_tcscmp (component_id, TAP_COMPONENT_ID)) - devices.push_back(net_cfg_instance_id); - } - } - RegCloseKey (unit_key); - } - ++i; - } - - RegCloseKey (adapter_key); - - if (devices.empty()) - return NULL; - - // The result is a '\0' separated list of strings - list::const_iterator it; - len = 0; - for (it = devices.begin(); it != devices.end(); it++) - len += (*it).length() + 1; - - TCHAR *names = (TCHAR *)malloc(len * sizeof(TCHAR)); - if (names) { - TCHAR *p = names; - for (it = devices.begin(); it != devices.end(); it++) { - len = (*it).length(); - _tcscpy(p, (*it).c_str()); - p[len] = '\0'; - p += len + 1; - } - } - - return names; -} diff --git a/BasiliskII/src/Windows/util_windows.h b/BasiliskII/src/Windows/util_windows.h deleted file mode 100755 index 26435558..00000000 --- a/BasiliskII/src/Windows/util_windows.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * util_windows.h - Miscellaneous utilities for Win32 - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Windows platform specific code copyright (C) Lauri Pesonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _UTIL_WINDOWS_H -#define _UTIL_WINDOWS_H - -#include -#include - -BOOL exists( const TCHAR *path ); -int32 get_file_size( const TCHAR *path ); -BOOL create_file( const TCHAR *path, DWORD size ); -bool check_drivers(void); - -// Thread wrappers -extern HANDLE create_thread(LPTHREAD_START_ROUTINE start_routine, void *arg = NULL); -extern void wait_thread(HANDLE thread); -extern void kill_thread(HANDLE thread); - -// Mutex wrappers -class mutex_t { - CRITICAL_SECTION cs; - public: - mutex_t() { InitializeCriticalSection(&cs); } - ~mutex_t() { DeleteCriticalSection(&cs); } - void lock() { EnterCriticalSection(&cs); } - void unlock() { LeaveCriticalSection(&cs); } -}; - -// Network control panel helpers -extern const TCHAR *ether_name_to_guid(const TCHAR *name); -extern const TCHAR *ether_guid_to_name(const TCHAR *guid); - -// Get TAP-Win32 devices (caller free()s returned buffer) -extern const TCHAR *ether_tap_devices(void); - -// Wide string versions of commonly used functions -extern void ErrorAlert(const wchar_t *text); -extern void WarningAlert(const wchar_t *text); - -// ----------------- String conversion functions ----------------- - -// Null deleter -- does nothing. Allows returning a non-owning -// unique_ptr. This should go away if observer_ptr makes it into -// the standard. -template struct null_delete { - constexpr null_delete() noexcept = default; - template null_delete(const null_delete&) noexcept { } - void operator ()(T*) const noexcept { } -}; -template struct null_delete { - constexpr null_delete() noexcept = default; - void operator ()(T*) const noexcept { } - template void operator ()(U*) const = delete; -}; - -// Functions returning null-terminated C strings -std::unique_ptr str(const wchar_t* s); -std::unique_ptr wstr(const char* s); - -inline std::unique_ptr> str(const char* s) -{ - return std::unique_ptr>(s); -} -inline std::unique_ptr> wstr(const wchar_t* s) -{ - return std::unique_ptr>(s); -} - -#ifdef _UNICODE -#define tstr wstr -#else -#define tstr str -#endif - -// Functions returning std::strings -std::string to_string(const wchar_t* s); -std::wstring to_wstring(const char* s); -inline std::string to_string(const char* s) { return std::string(s); } -inline std::wstring to_wstring(const wchar_t* s) { return std::wstring(s); } - -#ifdef _UNICODE -#define to_tstring to_wstring -#else -#define to_tstring to_string -#endif - -// BSD strlcpy/strlcat with overloads for converting between wide and narrow strings -size_t strlcpy(char* dst, const char* src, size_t size); -size_t strlcpy(char* dst, const wchar_t* src, size_t size); -size_t strlcat(char* dst, const char* src, size_t size); -size_t strlcat(char* dst, const wchar_t* src, size_t size); -size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t size); -size_t wcslcpy(wchar_t* dst, const char* src, size_t size); -size_t wcslcat(wchar_t* dst, const wchar_t* src, size_t size); -size_t wcslcat(wchar_t* dst, const char* src, size_t size); - -#ifdef _UNICODE -#define tcslcpy wcslcpy -#define tcslcat wcslcat -#else -#define tcslcpy strlcpy -#define tcslcat strlcat -#endif - -#endif // _UTIL_WINDOWS_H diff --git a/BasiliskII/src/Windows/xpram_windows.cpp b/BasiliskII/src/Windows/xpram_windows.cpp deleted file mode 100755 index 46c45040..00000000 --- a/BasiliskII/src/Windows/xpram_windows.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * xpram_windows.cpp - XPRAM handling, Windows specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -typedef std::basic_string tstring; - -#include "xpram.h" - - -// XPRAM file name and path -#if POWERPC_ROM -const TCHAR XPRAM_FILE_NAME[] = TEXT("SheepShaver_nvram.dat"); -#else -const TCHAR XPRAM_FILE_NAME[] = TEXT("BasiliskII_xpram.dat"); -#endif -static tstring xpram_path; - - -/* - * Construct XPRAM path - */ - -static void build_xpram_path(void) -{ - xpram_path.clear(); - int pwd_len = GetCurrentDirectory(0, NULL); - TCHAR *pwd = new TCHAR[pwd_len]; - if (GetCurrentDirectory(pwd_len, pwd) == pwd_len - 1) - xpram_path = tstring(pwd) + TEXT('\\'); - delete[] pwd; - xpram_path += XPRAM_FILE_NAME; -} - - -/* - * Load XPRAM from settings file - */ - -void LoadXPRAM(const char *vmdir) -{ - // Construct XPRAM path - build_xpram_path(); - - // Load XPRAM from settings file - HANDLE fh = CreateFile(xpram_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (fh != INVALID_HANDLE_VALUE) { - DWORD bytesRead; - ReadFile(fh, XPRAM, XPRAM_SIZE, &bytesRead, NULL); - CloseHandle(fh); - } -} - - -/* - * Save XPRAM to settings file - */ - -void SaveXPRAM(void) -{ - HANDLE fh = CreateFile(xpram_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - if (fh != INVALID_HANDLE_VALUE) { - DWORD bytesWritten; - WriteFile(fh, XPRAM, XPRAM_SIZE, &bytesWritten, NULL); - CloseHandle(fh); - } -} - - -/* - * Delete PRAM file - */ - -void ZapPRAM(void) -{ - // Construct PRAM path - build_xpram_path(); - - // Delete file - DeleteFile(xpram_path.c_str()); -} diff --git a/BasiliskII/src/emul_op.cpp b/BasiliskII/src/emul_op.cpp index 0f2b59fc..549d1de0 100644 --- a/BasiliskII/src/emul_op.cpp +++ b/BasiliskII/src/emul_op.cpp @@ -42,9 +42,6 @@ #include "extfs.h" #include "emul_op.h" -#ifdef ENABLE_MON -#include "mon.h" -#endif #define DEBUG 0 #include "debug.h" @@ -69,10 +66,7 @@ void EmulOp(uint16 opcode, M68kRegisters *r) r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7], r->sr); VideoQuitFullScreen(); -#ifdef ENABLE_MON - const char *arg[4] = {"mon", "-m", "-r", NULL}; - mon(3, arg); -#endif + QuitEmulator(); break; } @@ -574,10 +568,7 @@ void EmulOp(uint16 opcode, M68kRegisters *r) r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7], r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7], r->sr); -#ifdef ENABLE_MON - const char *arg[4] = {"mon", "-m", "-r", NULL}; - mon(3, arg); -#endif + QuitEmulator(); break; } diff --git a/BasiliskII/src/ether.cpp b/BasiliskII/src/ether.cpp index d5471029..e3f7e970 100644 --- a/BasiliskII/src/ether.cpp +++ b/BasiliskII/src/ether.cpp @@ -57,11 +57,8 @@ using std::map; #define MONITOR 0 -#ifdef __BEOS__ -#define CLOSESOCKET closesocket -#else + #define CLOSESOCKET close -#endif // Global variables @@ -138,12 +135,8 @@ void EtherInit(void) // Set socket options int on = 1; -#ifdef __BEOS__ - setsockopt(udp_socket, SOL_SOCKET, SO_NONBLOCK, &on, sizeof(on)); -#else setsockopt(udp_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); ioctl(udp_socket, FIONBIO, &on); -#endif // Start thread for packet reception if (!ether_start_udp_thread(udp_socket)) { @@ -453,7 +446,6 @@ void ether_udp_read(uint32 packet, int length, struct sockaddr_in *from) * Ethernet packet allocator */ -#if SIZEOF_VOID_P != 4 || REAL_ADDRESSING == 0 static uint32 ether_packet = 0; // Ethernet packet (cached allocation) static uint32 n_ether_packets = 0; // Number of ethernet packets allocated so far (should be at most 1) @@ -485,4 +477,3 @@ EthernetPacket::~EthernetPacket() bug("WARNING: Nested allocation of ethernet packets!\n"); } } -#endif diff --git a/BasiliskII/src/extfs.cpp b/BasiliskII/src/extfs.cpp index f6ac09f1..fe421782 100644 --- a/BasiliskII/src/extfs.cpp +++ b/BasiliskII/src/extfs.cpp @@ -43,10 +43,8 @@ #include #include -#ifndef WIN32 #include #include -#endif #if defined __APPLE__ && defined __MACH__ #include @@ -61,10 +59,6 @@ #include "extfs.h" #include "extfs_defs.h" -#ifdef WIN32 -# include "posix_emu.h" -#endif - #define DEBUG 0 #include "debug.h" @@ -1049,9 +1043,7 @@ static int16 fs_volume_mount(uint32 pb) // Init VCB WriteMacInt16(vcb + vcbSigWord, 0x4244); -#if defined(__BEOS__) || defined(WIN32) - WriteMacInt32(vcb + vcbCrDate, TimeToMacTime(root_stat.st_crtime)); -#elif defined __APPLE__ && defined __MACH__ +#if defined __APPLE__ && defined __MACH__ WriteMacInt32(vcb + vcbCrDate, get_creation_time(RootPath)); #else WriteMacInt32(vcb + vcbCrDate, 0); @@ -1114,9 +1106,7 @@ static int16 fs_get_vol_info(uint32 pb, bool hfs) // Fill in struct if (ReadMacInt32(pb + ioNamePtr)) pstrcpy((char *)Mac2HostAddr(ReadMacInt32(pb + ioNamePtr)), VOLUME_NAME); -#if defined(__BEOS__) || defined(WIN32) - WriteMacInt32(pb + ioVCrDate, TimeToMacTime(root_stat.st_crtime)); -#elif defined __APPLE__ && defined __MACH__ +#if defined __APPLE__ && defined __MACH__ WriteMacInt32(pb + ioVCrDate, get_creation_time(RootPath)); #else WriteMacInt32(pb + ioVCrDate, 0); @@ -1308,9 +1298,7 @@ read_next_de: WriteMacInt8(pb + ioFlAttrib, access(full_path, W_OK) == 0 ? 0 : faLocked); WriteMacInt32(pb + ioDirID, fs_item->id); -#if defined(__BEOS__) || defined(WIN32) - WriteMacInt32(pb + ioFlCrDat, TimeToMacTime(st.st_crtime)); -#elif defined __APPLE__ && defined __MACH__ +#if defined __APPLE__ && defined __MACH__ WriteMacInt32(pb + ioFlCrDat, get_creation_time(full_path)); #else WriteMacInt32(pb + ioFlCrDat, 0); @@ -1432,9 +1420,7 @@ read_next_de: WriteMacInt8(pb + ioACUser, 0); WriteMacInt32(pb + ioDirID, fs_item->id); WriteMacInt32(pb + ioFlParID, fs_item->parent_id); -#if defined(__BEOS__) || defined(WIN32) - WriteMacInt32(pb + ioFlCrDat, TimeToMacTime(st.st_crtime)); -#elif defined __APPLE__ && defined __MACH__ +#if defined __APPLE__ && defined __MACH__ WriteMacInt32(pb + ioFlCrDat, get_creation_time(full_path)); #else WriteMacInt32(pb + ioFlCrDat, 0); diff --git a/BasiliskII/src/include/debug.h b/BasiliskII/src/include/debug.h index 414ad324..330d7f5b 100644 --- a/BasiliskII/src/include/debug.h +++ b/BasiliskII/src/include/debug.h @@ -21,92 +21,10 @@ #ifndef DEBUG_H #define DEBUG_H -#if defined(WIN32) && !defined(__CYGWIN__) - -// Windows debugging goes where it's supposed to go -#include -#include -#include -#include -#include - -static inline void _cdecl vwinbug(const char *s, va_list vargs) -{ - char msg[1024], date[50], hours[50]; - struct _timeb tstruct; - - _ftime( &tstruct ); - _strtime( hours ); - _strdate( date ); - _snprintf( msg, lengthof(msg), "B2: %s %s:%03u ", date, hours, tstruct.millitm ); - - char *rest = &msg[strlen(msg)]; - _vsnprintf( rest, lengthof(msg) - (rest - msg), s, vargs ); - - OutputDebugStringA(msg); -} -static inline void _cdecl vwwinbug( const wchar_t *s, va_list vargs) -{ - wchar_t msg[1024], date[50], hours[50]; - struct _timeb tstruct; - - _ftime( &tstruct ); - _wstrtime( hours ); - _wstrdate( date ); - _snwprintf( msg, lengthof(msg), L"B2: %s %s:%03u ", date, hours, tstruct.millitm ); - - wchar_t *rest = &msg[wcslen(msg)]; - _vsnwprintf( rest, lengthof(msg) - (rest - msg), s, vargs ); - - OutputDebugStringW(msg); -} -static inline void _cdecl winbug( const char *s, ...) -{ - va_list vargs; - va_start(vargs, s); - vwinbug(s, vargs); - va_end(vargs); -} -static inline void _cdecl wwinbug(const wchar_t *s, ...) -{ - va_list vargs; - va_start(vargs, s); - vwwinbug(s, vargs); - va_end(vargs); -} - -#ifdef __cplusplus -static inline void _cdecl winbug(wchar_t *s, ...) -{ - va_list vargs; - va_start(vargs, s); - vwwinbug(s, vargs); - va_end(vargs); -} -#endif -#define bug winbug -#define wbug wwinbug - -#elif defined(AMIGA) - -// Amiga debugging info goes to serial port (or sushi) -#ifdef __cplusplus -extern "C" { -#endif -extern void kprintf(const char *, ...); -#ifdef __cplusplus -} -#endif -#define bug kprintf - -#else - // Other systems just print it to stdout #include #define bug printf -#endif - #if DEBUG #define D(x) (x); #else diff --git a/BasiliskII/src/include/ether.h b/BasiliskII/src/include/ether.h index e1e988d0..7c02e020 100644 --- a/BasiliskII/src/include/ether.h +++ b/BasiliskII/src/include/ether.h @@ -63,17 +63,13 @@ extern uint32 ether_data; // Mac address of driver data in MacOS RAM // Ethernet packet allocator (optimized for 32-bit platforms in real addressing mode) class EthernetPacket { -#if SIZEOF_VOID_P == 4 && REAL_ADDRESSING - uint8 packet[1516]; - public: - uint32 addr(void) const { return (uint32)packet; } -#else + uint32 packet; public: EthernetPacket(); ~EthernetPacket(); uint32 addr(void) const { return packet; } -#endif + }; // Copy packet data from WDS to linear buffer (must hold at least 1514 bytes), diff --git a/BasiliskII/src/main.cpp b/BasiliskII/src/main.cpp index dcb86e9c..2982bee7 100644 --- a/BasiliskII/src/main.cpp +++ b/BasiliskII/src/main.cpp @@ -42,20 +42,6 @@ #define DEBUG 0 #include "debug.h" -#if ENABLE_MON -#include "mon.h" - -static uint32 mon_read_byte_b2(uintptr adr) -{ - return ReadMacInt8(adr); -} - -static void mon_write_byte_b2(uintptr adr, uint32 b) -{ - WriteMacInt8(adr, b); -} -#endif - /* * Initialize everything, returns false on error @@ -192,13 +178,6 @@ bool InitAll(const char *vmdir) return false; } -#if ENABLE_MON - // Initialize mon - mon_init(); - mon_read_byte = mon_read_byte_b2; - mon_write_byte = mon_write_byte_b2; -#endif - return true; } @@ -209,10 +188,6 @@ bool InitAll(const char *vmdir) void ExitAll(void) { -#if ENABLE_MON - // Deinitialize mon - mon_exit(); -#endif // Save XPRAM XPRAMExit(); diff --git a/BasiliskII/src/native_cpu/cpu_emulation.h b/BasiliskII/src/native_cpu/cpu_emulation.h deleted file mode 100644 index 822ee047..00000000 --- a/BasiliskII/src/native_cpu/cpu_emulation.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * cpu_emulation.h - Definitions for Basilisk II CPU emulation module (native 68k version) - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef CPU_EMULATION_H -#define CPU_EMULATION_H - - -/* - * Memory system - */ - -// RAM and ROM pointers (allocated and set by main_*.cpp) -extern uint32 RAMBaseMac; // RAM base (Mac address space), does not include Low Mem when != 0 -extern uint8 *RAMBaseHost; // RAM base (host address space) -extern uint32 RAMSize; // Size of RAM - -extern uint32 ROMBaseMac; // ROM base (Mac address space) -extern uint8 *ROMBaseHost; // ROM base (host address space) -extern uint32 ROMSize; // Size of ROM - -// Mac memory access functions -static inline uint32 ReadMacInt32(uint32 addr) {return *(uint32 *)addr;} -static inline uint32 ReadMacInt16(uint32 addr) {return *(uint16 *)addr;} -static inline uint32 ReadMacInt8(uint32 addr) {return *(uint8 *)addr;} -static inline void WriteMacInt32(uint32 addr, uint32 l) {*(uint32 *)addr = l;} -static inline void WriteMacInt16(uint32 addr, uint32 w) {*(uint16 *)addr = w;} -static inline void WriteMacInt8(uint32 addr, uint32 b) {*(uint8 *)addr = b;} -static inline uint8 *Mac2HostAddr(uint32 addr) {return (uint8 *)addr;} -static inline uint32 Host2MacAddr(uint8 *addr) {return (uint32)addr;} -static inline void *Mac_memset(uint32 addr, int c, size_t n) {return memset(Mac2HostAddr(addr), c, n);} -static inline void *Mac2Host_memcpy(void *dest, uint32 src, size_t n) {return memcpy(dest, Mac2HostAddr(src), n);} -static inline void *Host2Mac_memcpy(uint32 dest, const void *src, size_t n) {return memcpy(Mac2HostAddr(dest), src, n);} -static inline void *Mac2Mac_memcpy(uint32 dest, uint32 src, size_t n) {return memcpy(Mac2HostAddr(dest), Mac2HostAddr(src), n);} - - -/* - * 680x0 emulation - */ - -// 680x0 emulation functions -struct M68kRegisters; -extern void Start680x0(void); // Reset and start 680x0 -extern "C" void Execute68k(uint32 addr, M68kRegisters *r); // Execute 68k code from EMUL_OP routine -extern "C" void Execute68kTrap(uint16 trap, M68kRegisters *r); // Execute MacOS 68k trap from EMUL_OP routine - -// Interrupt functions -extern void TriggerInterrupt(void); // Trigger interrupt (InterruptFlag must be set first) -extern void TriggerNMI(void); // Trigger interrupt level 7 - -#endif diff --git a/BasiliskII/src/pict.c b/BasiliskII/src/pict.c deleted file mode 100644 index 715c8feb..00000000 --- a/BasiliskII/src/pict.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * pict.c - convert an image to PICT. - * - * Currently creates a bitmap PICT resource; vector graphics are not preserved. - * - * By Charles Srstka. - * - * Public Domain. Do with it as you wish. - * - */ - -/* - * PICT format: - * - * Size: 2 bytes - * Bounding Rect: 8 bytes - * - * This is followed by a series of opcodes. - * Each opcode is 1 byte long for a Version 1 PICT, or 2 bytes long for a Version 2 PICT. - * The ones we currently care about are: - * - * 0x0011 VersionOp: begins PICT version 2 - * 0x02ff Version: identifies PICT version 2 - * 0x0c00 HeaderOp: followed by 24 header bytes - * 4 bytes: 0xFFFFFFFF for regular v2 PICT or 0xFFFE0000 for extended v2 PICT - * 16 bytes: fixed-point bounding rectangle (or resolution, if an extended v2 PICT) - * 4 bytes: reserved - * - * 0x0001 Clip: set clipping region: followed by variable-sized region - * 0x001e DefHilite: set default highlight color - * 0x009b DirectBitsRgn: bitmap data - * pixMap: 50 bytes (PixMap) - * srcRect: 8 bytes (Rect) - * dstRect: 8 bytes (Rect) - * mode: 2 bytes (Mode) - * maskRgn: variable (Region) - * pixData: variable - * 0x00ff End of File - */ - -/* - * PixMap format: - * - * baseAddr: Ptr (4 bytes) - * rowBytes: Integer (2 bytes) - * bounds: Rect (8 bytes) - * pmVersion: Integer (2 bytes) - * packType: Integer (2 bytes) - * packSize: LongInt (4 bytes) - * hRes: Fixed (4 bytes) - * vRes: Fixed (4 bytes) - * pixelType: Integer (2 bytes) - * pixelSize: Integer (2 bytes) - * cmpCount: Integer (2 bytes) - * cmpSize: Integer (2 bytes) - * planeBytes: LongInt (4 bytes) - * pmTable: CTabHandle (4 bytes) - * pmReserved: LongInt (4 bytes) - */ - -#include -#include -#include -#include - -static ssize_t CompressUsingRLE(uint8_t *row, uint16_t uncmpLength, uint8_t *outBuf, size_t bufSize) -{ - int byteCountLength = 1 + (uncmpLength > 250); - - uint16_t cmpCursor = byteCountLength; - uint16_t cursor = 0; - - // enough to output the data uncompressed if we have to, plus the length bytes - size_t maxSize = byteCountLength + uncmpLength + (uncmpLength + 126) / 127; - - int outOfRoom = 0; - uint16_t cmpLength; - - if (row == NULL || outBuf == NULL || bufSize == 0) - return maxSize; - - while (cursor < uncmpLength) { - uint8_t byte = row[cursor++]; - uint8_t nextByte; - - if (cursor < uncmpLength && (nextByte = row[cursor]) == byte) { - int8_t matches = 1; - - while (++cursor < uncmpLength && matches < 127 && row[cursor] == byte) { - matches++; - } - - if(cmpCursor + 2 > bufSize) { - outOfRoom = 1; - break; - } - - outBuf[cmpCursor++] = -matches; - outBuf[cmpCursor++] = byte; - } else { - uint8_t literals = 0; - uint8_t i; - - while (cursor + literals + 1 < uncmpLength && literals < 127 && nextByte != (nextByte = row[cursor + literals + 1])) { - literals++; - } - - if(cmpCursor + 2 + literals > bufSize) { - outOfRoom = 1; - break; - } - - outBuf[cmpCursor++] = literals; - outBuf[cmpCursor++] = byte; - - for (i = 0; i < literals; i++) { - outBuf[cmpCursor++] = row[cursor++]; - } - } - } - - if(outOfRoom) { - // Trying to compress this just made it larger; just output the data uncompressed instead - - if(bufSize < maxSize) { - // sorry folks, don't have enough buffer - return -1; - } - - cursor = 0; - cmpCursor = byteCountLength; - - while (cursor < uncmpLength) { - uint8_t bytesToCopy = uncmpLength - cursor > 128 ? 128 : uncmpLength - cursor; - - outBuf[cmpCursor++] = bytesToCopy - 1; - memcpy(outBuf + cmpCursor, row + cursor, bytesToCopy); cmpCursor += bytesToCopy; cursor += bytesToCopy; - } - - cmpLength = cmpCursor - 1; - } - - cmpLength = cmpCursor - byteCountLength; - - if (byteCountLength == 2) { - outBuf[0] = cmpLength >> 8; - outBuf[1] = cmpLength & 0xff; - } else { - outBuf[0] = cmpLength; - } - - return cmpCursor; -} - -ssize_t ConvertRGBAToPICT(uint8_t *buf, unsigned long bufSize, uint8_t *rgbaPixels, uint16_t width, uint16_t height) -{ - unsigned long initialSize = (10 /* size + rect */ + - 6 /* initial opcodes */ + - 24 /* header */ + - 12 /* clip region */ + - 2 /* DefHilite */ + - 70 /* DirectBitsRgn - pixData - maskRgn */ + - 10 /* maskRgn */); - -#define RECT_SIZE 8 -#define REGION_SIZE 10 -#define FIXED_RECT_SIZE 16 - - char rect[RECT_SIZE] = {0, 0, 0, 0, height >> 8, height & 0xff, width >> 8, width & 0xff }; - char region[REGION_SIZE] = { 0x00, 0x0a, rect[0], rect[1], rect[2], rect[3], rect[4], rect[5], rect[6], rect[7] }; - char fixedRect[FIXED_RECT_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, width >> 8, width & 0xff, 0, 0, height >> 8, height & 0xff, 0, 0 }; - - uint32_t hDPI = htonl(0x00480000); // 72 dpi - uint32_t vDPI = hDPI; - - uint16_t bytesPerPixel = 4; // RGBA - uint16_t bytesPerRow = width * bytesPerPixel; - - unsigned long cursor = 2; // size bytes filled in at the end - - ssize_t cmpBufSize = CompressUsingRLE(NULL, bytesPerRow, NULL, 0); - uint8_t cmpBuf[cmpBufSize]; - - uint16_t i; - - if (buf == NULL || bufSize == 0) { - // Give an upper bound for the buffer size. - - return initialSize + height * cmpBufSize + 2; - } - - if (bufSize < initialSize) { - return -1; - } - - memcpy(buf + cursor, rect, RECT_SIZE); cursor += RECT_SIZE; - - buf[cursor++] = 0x00; buf[cursor++] = 0x11; buf[cursor++] = 0x02; buf[cursor++] = 0xff; - - buf[cursor++] = 0x0c; buf[cursor++] = 0x00; - buf[cursor++] = 0xff; buf[cursor++] = 0xff; buf[cursor++] = 0xff; buf[cursor++] = 0xff; - memcpy(buf + cursor, fixedRect, FIXED_RECT_SIZE); cursor += FIXED_RECT_SIZE; - memset(buf + cursor, '\0', 4); cursor += 4; - - buf[cursor++] = 0x00; buf[cursor++] = 0x1e; - - buf[cursor++] = 0x00; buf[cursor++] = 0x01; - memcpy(buf + cursor, region, REGION_SIZE); cursor += REGION_SIZE; - - buf[cursor++] = 0x00; buf[cursor++] = 0x9b; - memset(buf + cursor, '\0', 4); cursor += 4; // I think this pointer isn't used - buf[cursor++] = (bytesPerRow >> 8) | 0x80; buf[cursor++] = bytesPerRow & 0xff; // rowBytes - memcpy(buf + cursor, rect, RECT_SIZE); cursor += RECT_SIZE; //bounds - buf[cursor++] = 0x00; buf[cursor++] = 0x00; // pmVersion - buf[cursor++] = 0x00; buf[cursor++] = 0x04; // packType - buf[cursor++] = 0x00; buf[cursor++] = 0x00; buf[cursor++] = 0x00; buf[cursor++] = 0x00; // packSize is always 0 - memcpy(buf + cursor, &hDPI, 4); cursor += 4; // hRes - memcpy(buf + cursor, &vDPI, 4); cursor += 4; // vRes - buf[cursor++] = 0x00; buf[cursor++] = 0x10; // pixelType; direct device - buf[cursor++] = 0x00; buf[cursor++] = 0x20; // pixelSize; 32 bits per pixel - buf[cursor++] = bytesPerPixel >> 8; buf[cursor++] = bytesPerPixel & 0xff; // components per pixel - buf[cursor++] = 0x00; buf[cursor++] = 0x08; // 8 bits per component - memset(buf + cursor, '\0', 4); cursor += 4; // planeBytes isn't used - memset(buf + cursor, '\0', 4); cursor += 4; // don't think we need pmTable - memset(buf + cursor, '\0', 4); cursor += 4; // reserved - - memcpy(buf + cursor, rect, RECT_SIZE); cursor += RECT_SIZE; - memcpy(buf + cursor, rect, RECT_SIZE); cursor += RECT_SIZE; - buf[cursor++] = 0x00; buf[cursor++] = 0x00; // no transfer mode - memcpy(buf + cursor, region, REGION_SIZE); cursor += REGION_SIZE; - - for (i = 0; i < height; i++) { - uint8_t row[bytesPerRow]; - ssize_t cmpLength; - uint16_t j; - - for (j = 0; j < width; j++) { - row[j] = rgbaPixels[i * bytesPerRow + j * bytesPerPixel + 3]; - row[width + j] = rgbaPixels[i * bytesPerRow + j * bytesPerPixel]; - row[width * 2 + j] = rgbaPixels[i * bytesPerRow + j * bytesPerPixel + 1]; - row[width * 3 + j] = rgbaPixels[i * bytesPerRow + j * bytesPerPixel + 2]; - } - - cmpLength = CompressUsingRLE(row, bytesPerRow, cmpBuf, cmpBufSize); - - if (cmpLength < 0 || cursor + cmpLength > bufSize) - return -1; - - memcpy(buf + cursor, cmpBuf, cmpLength); cursor += cmpLength; - } - - // Fun fact: forgetting to put 0x00ff at the end of a PICT picture causes the entire - // Classic Mac OS to crash when it tries to read it! Don't ask me how I learned this. - if (cursor + 2 > bufSize) - return -1; - - buf[cursor++] = 0x00; buf[cursor++] = 0xff; - - if(cursor > UINT16_MAX) { - buf[0] = buf[1] = 0xff; - } else { - buf[0] = cursor >> 8; - buf[1] = cursor & 0xff; - } - - return cursor; -} diff --git a/BasiliskII/src/powerrom_cpu/cpu_emulation.h b/BasiliskII/src/powerrom_cpu/cpu_emulation.h deleted file mode 100644 index dbddfbbc..00000000 --- a/BasiliskII/src/powerrom_cpu/cpu_emulation.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * cpu_emulation.h - Definitions for Basilisk II CPU emulation module (Apple PowerMac ROM 680x0 emulator version (BeOS/PPC)) - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef CPU_EMULATION_H -#define CPU_EMULATION_H - - -/* - * Memory system - */ - -// RAM and ROM pointers (allocated and set by main_*.cpp) -extern uint32 RAMBaseMac; // RAM base (Mac address space), does not include Low Mem when != 0 -extern uint8 *RAMBaseHost; // RAM base (host address space) -extern uint32 RAMSize; // Size of RAM - -extern uint32 ROMBaseMac; // ROM base (Mac address space) -extern uint8 *ROMBaseHost; // ROM base (host address space) -extern uint32 ROMSize; // Size of ROM - -// Mac memory access functions -static inline uint32 ReadMacInt32(uint32 addr) {return ntohl(*(uint32 *)addr);} -static inline uint32 ReadMacInt16(uint32 addr) {return ntohs(*(uint16 *)addr);} -static inline uint32 ReadMacInt8(uint32 addr) {return *(uint8 *)addr;} -static inline void WriteMacInt32(uint32 addr, uint32 l) {*(uint32 *)addr = htonl(l);} -static inline void WriteMacInt16(uint32 addr, uint32 w) {*(uint16 *)addr = htons(w);} -static inline void WriteMacInt8(uint32 addr, uint32 b) {*(uint8 *)addr = b;} -static inline uint8 *Mac2HostAddr(uint32 addr) {return (uint8 *)addr;} -static inline uint32 Host2MacAddr(uint8 *addr) {return (uint32)addr;} - - -/* - * 680x0 emulation - */ - -// Initialization -extern bool Init680x0(void); // This routine may want to look at CPUType/FPUType to set up the apropriate emulation -extern void Exit680x0(void); - -// 680x0 emulation functions -struct M68kRegisters; -extern void Start680x0(void); // Reset and start 680x0 -extern "C" void Execute68k(uint32 addr, M68kRegisters *r); // Execute 68k code from EMUL_OP routine -extern "C" void Execute68kTrap(uint16 trap, M68kRegisters *r); // Execute MacOS 68k trap from EMUL_OP routine - -// Interrupt functions -extern void TriggerInterrupt(void); // Trigger interrupt (InterruptFlag must be set first) - -#endif diff --git a/BasiliskII/src/powerrom_cpu/powerrom_cpu.cpp b/BasiliskII/src/powerrom_cpu/powerrom_cpu.cpp deleted file mode 100644 index d91b9049..00000000 --- a/BasiliskII/src/powerrom_cpu/powerrom_cpu.cpp +++ /dev/null @@ -1,1367 +0,0 @@ -/* - * powerrom_cpu.cpp - Using the 680x0 emulator in PowerMac ROMs for Basilisk II - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "emul_op.h" -#include "prefs.h" -#include "timer.h" -#include "user_strings.h" - -#include "sheep_driver.h" - -#define DEBUG 0 -#include "debug.h" - -// Save FP regs in Execute68k()? -#define SAVE_FP_EXEC_68K 0 - - -// Constants -const char ROM_FILE_NAME[] = "PowerROM"; -const char KERNEL_AREA_NAME[] = "Macintosh Kernel Data"; -const char DR_CACHE_AREA_NAME[] = "Macintosh DR Cache"; - -const uint32 ROM_BASE = 0x40800000; // Base address of ROM -const uint32 ROM_SIZE = 0x00400000; // Size of ROM file -const uint32 ROM_AREA_SIZE = 0x00500000; // Size of ROM area - -const uint32 DR_CACHE_BASE = 0x69000000; // Address of DR cache -const uint32 DR_CACHE_SIZE = 0x80000; // Size of DR Cache - -const uint32 SIG_STACK_SIZE = 8192; // Size of signal stack - -// PowerPC opcodes -const uint32 POWERPC_NOP = 0x60000000; -const uint32 POWERPC_ILLEGAL = 0x00000000; -const uint32 POWERPC_BLR = 0x4e800020; -const uint32 POWERPC_BCTR = 0x4e800420; - -// Extra Low Memory Globals -#define MODE_68K 0 // 68k emulator active -#define MODE_EMUL_OP 1 // Within EMUL_OP routine - -#define XLM_RESET_STACK 0x2800 // Reset stack pointer -#define XLM_KERNEL_DATA 0x2804 // Pointer to Kernel Data -#define XLM_TOC 0x2808 // TOC pointer of emulator -#define XLM_RUN_MODE 0x2810 // Current run mode, see enum above -#define XLM_68K_R25 0x2814 // Contents of the 68k emulator's r25 (which contains the interrupt level), saved upon entering EMUL_OP mode, used by Execute68k() and the USR1 signal handler -#define XLM_IRQ_NEST 0x2818 // Interrupt disable nesting counter (>0: disabled) -#define XLM_PVR 0x281c // Theoretical PVR -#define XLM_EMUL_RETURN_PROC 0x2824 // Pointer to EMUL_RETURN routine -#define XLM_EXEC_RETURN_PROC 0x2828 // Pointer to EXEC_RETURN routine -#define XLM_EMUL_OP_PROC 0x282c // Pointer to EMUL_OP routine -#define XLM_EMUL_RETURN_STACK 0x2830 // Stack pointer for EMUL_RETURN - - -// RAM and ROM pointers -uint32 RAMBaseMac; // RAM base (Mac address space) -uint8 *RAMBaseHost; // RAM base (host address space) -uint32 RAMSize; // Size of RAM -uint32 ROMBaseMac; // ROM base (Mac address space) -uint8 *ROMBaseHost; // ROM base (host address space) -uint32 ROMSize; // Size of ROM - - -// Emulator Data -struct EmulatorData { - uint32 v[0x400]; -}; - - -// Kernel Data -struct KernelData { - uint32 v[0x400]; - EmulatorData ed; -}; - - -// Exceptions -class file_open_error {}; -class file_read_error {}; -class rom_size_error {}; - - -// Global variables -static void *TOC; // TOC pointer -static uint32 PVR; // Theoretical PVR -static int64 CPUClockSpeed; // Processor clock speed (Hz) -static int64 BusClockSpeed; // Bus clock speed (Hz) -static system_info SysInfo; // System information - -static area_id kernel_area = -1; // Kernel Data area ID -static KernelData *kernel_data = NULL; // Pointer to Kernel Data -static uint32 KernelDataAddr; // Address of Kernel Data -static EmulatorData *emulator_data = NULL; -static area_id dr_cache_area; // DR Cache area ID -static uint32 DRCacheAddr; // Address of DR Cache - -static struct sigaction sigusr1_action; // Interrupt signal (of emulator thread) -static bool ReadyForSignals = false; // Flag: emul_thread ready to receive signals - - -// Prototypes -static void sigusr1_handler(int sig, void *arg, vregs *r); - -// From main_beos.cpp -extern int sheep_fd; // fd of sheep driver -extern thread_id emul_thread; // Emulator thread - - -/* - * Load ROM file (upper 3MB) - * - * file_open_error: Cannot open ROM file (nor use built-in ROM) - * file_read_error: Cannot read ROM file - */ - -// Decode LZSS data -static void decode_lzss(const uint8 *src, uint8 *dest, int size) -{ - char dict[0x1000]; - int run_mask = 0, dict_idx = 0xfee; - for (;;) { - if (run_mask < 0x100) { - // Start new run - if (--size < 0) - break; - run_mask = *src++ | 0xff00; - } - bool bit = run_mask & 1; - run_mask >>= 1; - if (bit) { - // Verbatim copy - if (--size < 0) - break; - int c = *src++; - dict[dict_idx++] = c; - *dest++ = c; - dict_idx &= 0xfff; - } else { - // Copy from dictionary - if (--size < 0) - break; - int idx = *src++; - if (--size < 0) - break; - int cnt = *src++; - idx |= (cnt << 4) & 0xf00; - cnt = (cnt & 0x0f) + 3; - while (cnt--) { - char c = dict[idx++]; - dict[dict_idx++] = c; - *dest++ = c; - idx &= 0xfff; - dict_idx &= 0xfff; - } - } - } -} - -static void load_rom(void) -{ - // Get rom file path from preferences - const char *rom_path = PrefsFindString("powerrom"); - - // Try to open ROM file - BFile file(rom_path ? rom_path : ROM_FILE_NAME, B_READ_ONLY); - if (file.InitCheck() != B_NO_ERROR) { - - // Failed, then ask sheep driver for ROM - uint8 *rom = new uint8[ROM_SIZE]; // Reading directly into the area doesn't work - ssize_t actual = read(sheep_fd, (void *)rom, ROM_SIZE); - if (actual == ROM_SIZE) { - // Copy upper 3MB - memcpy((void *)(ROM_BASE + 0x100000), rom + 0x100000, ROM_SIZE - 0x100000); - delete[] rom; - return; - } else - throw file_open_error(); - } - - printf(GetString(STR_READING_ROM_FILE)); - - // Get file size - off_t rom_size = 0; - file.GetSize(&rom_size); - - uint8 *rom = new uint8[ROM_SIZE]; // Reading directly into the area doesn't work - ssize_t actual = file.Read((void *)rom, ROM_SIZE); - if (actual == ROM_SIZE) { - // Plain ROM image, copy upper 3MB - memcpy((void *)(ROM_BASE + 0x100000), rom + 0x100000, ROM_SIZE - 0x100000); - delete[] rom; - } else { - if (strncmp((char *)rom, "", 11) == 0) { - // CHRP compressed ROM image - D(bug("CHRP ROM image\n")); - uint32 lzss_offset, lzss_size; - - char *s = strstr((char *)rom, "constant lzss-offset"); - if (s == NULL) - throw rom_size_error(); - s -= 7; - if (sscanf(s, "%06lx", &lzss_offset) != 1) - throw rom_size_error(); - s = strstr((char *)rom, "constant lzss-size"); - if (s == NULL) - throw rom_size_error(); - s -= 7; - if (sscanf(s, "%06lx", &lzss_size) != 1) - throw rom_size_error(); - D(bug("Offset of compressed data: %08lx\n", lzss_offset)); - D(bug("Size of compressed data: %08lx\n", lzss_size)); - - D(bug("Uncompressing ROM...\n")); - uint8 *decoded = new uint8[ROM_SIZE]; - decode_lzss(rom + lzss_offset, decoded, lzss_size); - memcpy((void *)(ROM_BASE + 0x100000), decoded + 0x100000, ROM_SIZE - 0x100000); - delete[] decoded; - delete[] rom; - } else if (rom_size != 4*1024*1024) - throw rom_size_error(); - else - throw file_read_error(); - } -} - - -/* - * Patch PowerMac ROM - */ - -// ROM type -enum { - ROMTYPE_TNT, - ROMTYPE_ALCHEMY, - ROMTYPE_ZANZIBAR, - ROMTYPE_GAZELLE, - ROMTYPE_NEWWORLD -}; -static int ROMType; - -// Nanokernel boot routine patches -static bool patch_nanokernel_boot(void) -{ - uint32 *lp; - int i; - - // Patch ConfigInfo - lp = (uint32 *)(ROM_BASE + 0x30d000); - lp[0x9c >> 2] = KernelDataAddr; // LA_InfoRecord - lp[0xa0 >> 2] = KernelDataAddr; // LA_KernelData - lp[0xa4 >> 2] = KernelDataAddr + 0x1000;// LA_EmulatorData - lp[0xa8 >> 2] = ROM_BASE + 0x480000; // LA_DispatchTable - lp[0xac >> 2] = ROM_BASE + 0x460000; // LA_EmulatorCode - lp[0x360 >> 2] = 0; // Physical RAM base (? on NewWorld ROM, this contains -1) - lp[0xfd8 >> 2] = ROM_BASE + 0x2a; // 68k reset vector - - // Skip SR/BAT/SDR init - if (ROMType == ROMTYPE_GAZELLE || ROMType == ROMTYPE_NEWWORLD) { - lp = (uint32 *)(ROM_BASE + 0x310000); - *lp++ = POWERPC_NOP; - *lp = 0x38000000; - } - static const uint32 sr_init_loc[] = {0x3101b0, 0x3101b0, 0x3101b0, 0x3101ec, 0x310200}; - lp = (uint32 *)(ROM_BASE + 0x310008); - *lp = 0x48000000 | (sr_init_loc[ROMType] - 8) & 0xffff; // b ROM_BASE+0x3101b0 - lp = (uint32 *)(ROM_BASE + sr_init_loc[ROMType]); - *lp++ = 0x80200000 + XLM_KERNEL_DATA; // lwz r1,(pointer to Kernel Data) - *lp++ = 0x3da0dead; // lis r13,0xdead (start of kernel memory) - *lp++ = 0x3dc00010; // lis r14,0x0010 (size of page table) - *lp = 0x3de00010; // lis r15,0x0010 (size of kernel memory) - - // Don't read PVR - static const uint32 pvr_loc[] = {0x3103b0, 0x3103b4, 0x3103b4, 0x310400, 0x310438}; - lp = (uint32 *)(ROM_BASE + pvr_loc[ROMType]); - *lp = 0x81800000 + XLM_PVR; // lwz r12,(theoretical PVR) - - // Set CPU specific data (even if ROM doesn't have support for that CPU) - lp = (uint32 *)(ROM_BASE + pvr_loc[ROMType]); - if (ntohl(lp[6]) != 0x2c0c0001) - return false; - uint32 ofs = lp[7] & 0xffff; - lp[8] = (lp[8] & 0xffff) | 0x48000000; // beq -> b - uint32 loc = (lp[8] & 0xffff) + (uint32)(lp+8) - ROM_BASE; - lp = (uint32 *)(ROM_BASE + ofs + 0x310000); - switch (PVR >> 16) { - case 1: // 601 - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00010040; // Unified caches/Inst cache line size - lp[5] = 0x00400020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00080008; // Inst cache assoc/Data cache assoc - lp[8] = 0x01000002; // TLB total size/TLB assoc - break; - case 3: // 603 - lp[0] = 0x1000; // Page size - lp[1] = 0x2000; // Data cache size - lp[2] = 0x2000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00020002; // Inst cache assoc/Data cache assoc - lp[8] = 0x00400002; // TLB total size/TLB assoc - break; - case 4: // 604 - lp[0] = 0x1000; // Page size - lp[1] = 0x4000; // Data cache size - lp[2] = 0x4000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00040004; // Inst cache assoc/Data cache assoc - lp[8] = 0x00800002; // TLB total size/TLB assoc - break; -// case 5: // 740? - case 6: // 603e - case 7: // 603ev - lp[0] = 0x1000; // Page size - lp[1] = 0x4000; // Data cache size - lp[2] = 0x4000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00040004; // Inst cache assoc/Data cache assoc - lp[8] = 0x00400002; // TLB total size/TLB assoc - break; - case 8: // 750 - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00080008; // Inst cache assoc/Data cache assoc - lp[8] = 0x00800002; // TLB total size/TLB assoc - break; - case 9: // 604e - case 10: // 604ev5 - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00040004; // Inst cache assoc/Data cache assoc - lp[8] = 0x00800002; // TLB total size/TLB assoc - break; -// case 11: // X704? - case 12: // ??? - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00080008; // Inst cache assoc/Data cache assoc - lp[8] = 0x00800002; // TLB total size/TLB assoc - break; - case 13: // ??? - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00080008; // Inst cache assoc/Data cache assoc - lp[8] = 0x01000004; // TLB total size/TLB assoc - break; -// case 50: // 821 -// case 80: // 860 - case 96: // ??? - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00010020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00080008; // Inst cache assoc/Data cache assoc - lp[8] = 0x00800004; // TLB total size/TLB assoc - break; - default: - printf("WARNING: Unknown CPU type\n"); - break; - } - - // Don't set SPRG3, don't test MQ - lp = (uint32 *)(ROM_BASE + loc + 0x20); - *lp++ = POWERPC_NOP; - lp++; - *lp++ = POWERPC_NOP; - lp++; - *lp = POWERPC_NOP; - - // Don't read MSR - lp = (uint32 *)(ROM_BASE + loc + 0x40); - *lp = 0x39c00000; // li r14,0 - - // Don't write to DEC - lp = (uint32 *)(ROM_BASE + loc + 0x70); - *lp++ = POWERPC_NOP; - loc = (lp[0] & 0xffff) + (uint32)lp - ROM_BASE; - - // Don't set SPRG3 - lp = (uint32 *)(ROM_BASE + loc + 0x2c); - *lp = POWERPC_NOP; - - // Don't read PVR - static const uint32 pvr_ofs[] = {0x138, 0x138, 0x138, 0x140, 0x148}; - lp = (uint32 *)(ROM_BASE + loc + pvr_ofs[ROMType]); - *lp = 0x82e00000 + XLM_PVR; // lwz r23,(theoretical PVR) - lp = (uint32 *)(ROM_BASE + loc + 0x170); - if (*lp == 0x7eff42a6) // NewWorld ROM - *lp = 0x82e00000 + XLM_PVR; // lwz r23,(theoretical PVR) - lp = (uint32 *)(ROM_BASE + 0x313134); - if (*lp == 0x7e5f42a6) - *lp = 0x82400000 + XLM_PVR; // lwz r18,(theoretical PVR) - lp = (uint32 *)(ROM_BASE + 0x3131f4); - if (*lp == 0x7e5f42a6) // NewWorld ROM - *lp = 0x82400000 + XLM_PVR; // lwz r18,(theoretical PVR) - - // Don't read SDR1 - static const uint32 sdr1_ofs[] = {0x174, 0x174, 0x174, 0x17c, 0x19c}; - lp = (uint32 *)(ROM_BASE + loc + sdr1_ofs[ROMType]); - *lp++ = 0x3d00dead; // lis r8,0xdead (pointer to page table) - *lp++ = 0x3ec0001f; // lis r22,0x001f (size of page table) - *lp = POWERPC_NOP; - - // Don't clear page table - static const uint32 pgtb_ofs[] = {0x198, 0x198, 0x198, 0x1a0, 0x1c4}; - lp = (uint32 *)(ROM_BASE + loc + pgtb_ofs[ROMType]); - *lp = POWERPC_NOP; - - // Don't invalidate TLB - static const uint32 tlb_ofs[] = {0x1a0, 0x1a0, 0x1a0, 0x1a8, 0x1cc}; - lp = (uint32 *)(ROM_BASE + loc + tlb_ofs[ROMType]); - *lp = POWERPC_NOP; - - // Don't create RAM descriptor table - static const uint32 desc_ofs[] = {0x350, 0x350, 0x350, 0x358, 0x37c}; - lp = (uint32 *)(ROM_BASE + loc + desc_ofs[ROMType]); - *lp = POWERPC_NOP; - - // Don't load SRs and BATs - static const uint32 sr_ofs[] = {0x3d8, 0x3d8, 0x3d8, 0x3e0, 0x404}; - lp = (uint32 *)(ROM_BASE + loc + sr_ofs[ROMType]); - *lp = POWERPC_NOP; - - // Don't mess with SRs - static const uint32 sr2_ofs[] = {0x312118, 0x312118, 0x312118, 0x312118, 0x3121b4}; - lp = (uint32 *)(ROM_BASE + sr2_ofs[ROMType]); - *lp = POWERPC_BLR; - - // Don't check performance monitor - static const uint32 pm_ofs[] = {0x313148, 0x313148, 0x313148, 0x313148, 0x313218}; - lp = (uint32 *)(ROM_BASE + pm_ofs[ROMType]); - while (*lp != 0x7e58eba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e78eaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e59eba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e79eaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5aeba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7aeaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5beba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7beaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5feba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7feaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5ceba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7ceaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5deba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7deaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5eeba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7eeaa6) lp++; - *lp++ = POWERPC_NOP; - - // Jump to 68k emulator - static const uint32 jump68k_ofs[] = {0x40c, 0x40c, 0x40c, 0x414, 0x438}; - lp = (uint32 *)(ROM_BASE + loc + jump68k_ofs[ROMType]); - *lp++ = 0x80610634; // lwz r3,0x0634(r1) (pointer to Emulator Data) - *lp++ = 0x8081119c; // lwz r4,0x119c(r1) (pointer to opcode table) - *lp++ = 0x80011184; // lwz r0,0x1184(r1) (pointer to emulator entry) - *lp++ = 0x7c0903a6; // mtctr r0 - *lp = POWERPC_BCTR; - return true; -} - -// 68k emulator patches -static bool patch_68k_emul(void) -{ - uint32 *lp; - uint32 base; - - // Overwrite twi instructions - static const uint32 twi_loc[] = {0x36e680, 0x36e6c0, 0x36e6c0, 0x36e6c0, 0x36e740}; - base = twi_loc[ROMType]; - lp = (uint32 *)(ROM_BASE + base); - *lp++ = 0x48000000 + 0x36f900 - base; // b 0x36f900 (Emulator start) - *lp++ = POWERPC_ILLEGAL; - *lp++ = 0x48000000 + 0x36fb00 - base - 8; // b 0x36fb00 (Reset opcode) - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - - // Set reset stack pointer - lp = (uint32 *)(ROM_BASE + base + 0xf0); - *lp++ = 0x80200000 + XLM_RESET_STACK; // lwz r1,XLM_RESET_STACK - - // Install EXEC_RETURN and EMUL_OP opcodes - lp = (uint32 *)(ROM_BASE + 0x380000 + (M68K_EXEC_RETURN << 3)); - *lp++ = 0x80000000 + XLM_EXEC_RETURN_PROC; // lwz r0,XLM_EXEC_RETURN_PROC - *lp++ = 0x4bfb6ffc; // b 0x36f800 - for (int i=0; i> 16); // lis r0,xxx - *lp++ = 0x60000000 + ((ROM_BASE + 0x46d0a4) & 0xffff); // ori r0,r0,xxx - *lp++ = 0x7c0903a6; // mtctr r0 - *lp = POWERPC_BCTR; // bctr - return true; -} - -// Nanokernel patches -static bool patch_nanokernel(void) -{ - uint32 *lp; - - // Patch 68k emulator trap routine - lp = (uint32 *)(ROM_BASE + 0x312994); // Always restore FPU state - while (*lp != 0x39260040) lp++; - lp--; - *lp = 0x48000441; // bl 0x00312dd4 - lp = (uint32 *)(ROM_BASE + 0x312dd8); // Don't modify MSR to turn on FPU - while (*lp != 0x810600e4) lp++; - lp--; - *lp++ = POWERPC_NOP; - lp += 2; - *lp++ = POWERPC_NOP; - lp++; - *lp++ = POWERPC_NOP; - *lp++ = POWERPC_NOP; - *lp = POWERPC_NOP; - - // Patch trap return routine - lp = (uint32 *)(ROM_BASE + 0x312c20); - while (*lp != 0x7d5a03a6) lp++; - *lp++ = 0x7d4903a6; // mtctr r10 - *lp++ = 0x7daff120; // mtcr r13 - *lp++ = 0x48000000 + 0x8000 - ((uint32)lp & 0xffff); // b ROM_BASE+0x318000 - uint32 xlp = (uint32)lp & 0xffff; - - lp = (uint32 *)(ROM_BASE + 0x312c50); // Replace rfi - while (*lp != 0x4c000064) lp++; - *lp = POWERPC_BCTR; - - lp = (uint32 *)(ROM_BASE + 0x318000); - *lp++ = 0x81400000 + XLM_IRQ_NEST; // lwz r10,XLM_IRQ_NEST - *lp++ = 0x394affff; // subi r10,r10,1 - *lp++ = 0x91400000 + XLM_IRQ_NEST; // stw r10,XLM_IRQ_NEST - *lp = 0x48000000 + ((xlp - 0x800c) & 0x03fffffc); // b ROM_BASE+0x312c2c - return true; -} - -static bool patch_rom(void) -{ - // Detect ROM type - if (!memcmp((void *)(ROM_BASE + 0x30d064), "Boot TNT", 8)) - ROMType = ROMTYPE_TNT; - else if (!memcmp((void *)(ROM_BASE + 0x30d064), "Boot Alchemy", 12)) - ROMType = ROMTYPE_ALCHEMY; - else if (!memcmp((void *)(ROM_BASE + 0x30d064), "Boot Zanzibar", 13)) - ROMType = ROMTYPE_ZANZIBAR; - else if (!memcmp((void *)(ROM_BASE + 0x30d064), "Boot Gazelle", 12)) - ROMType = ROMTYPE_GAZELLE; - else if (!memcmp((void *)(ROM_BASE + 0x30d064), "NewWorld", 8)) - ROMType = ROMTYPE_NEWWORLD; - else - return false; - - // Apply patches - if (!patch_nanokernel_boot()) return false; - if (!patch_68k_emul()) return false; - if (!patch_nanokernel()) return false; - - // Copy 68k emulator to 2MB boundary - memcpy((void *)(ROM_BASE + ROM_SIZE), (void *)(ROM_BASE + ROM_SIZE - 0x100000), 0x100000); - return true; -} - - -/* - * Initialize 680x0 emulation - */ - -static asm void *get_toc(void) -{ - mr r3,r2 - blr -} - -bool Init680x0(void) -{ - char str[256]; - - // Mac address space = host address space - RAMBaseMac = (uint32)RAMBaseHost; - ROMBaseMac = (uint32)ROMBaseHost; - - // Get TOC pointer - TOC = get_toc(); - - // Get system info - get_system_info(&SysInfo); - switch (SysInfo.cpu_type) { - case B_CPU_PPC_601: - PVR = 0x00010000; - break; - case B_CPU_PPC_603: - PVR = 0x00030000; - break; - case B_CPU_PPC_603e: - PVR = 0x00060000; - break; - case B_CPU_PPC_604: - PVR = 0x00040000; - break; - case B_CPU_PPC_604e: - PVR = 0x00090000; - break; - default: - PVR = 0x00040000; - break; - } - CPUClockSpeed = SysInfo.cpu_clock_speed; - BusClockSpeed = SysInfo.bus_clock_speed; - - // Delete old areas - area_id old_kernel_area = find_area(KERNEL_AREA_NAME); - if (old_kernel_area > 0) - delete_area(old_kernel_area); - area_id old_dr_cache_area = find_area(DR_CACHE_AREA_NAME); - if (old_dr_cache_area > 0) - delete_area(old_dr_cache_area); - - // Create area for Kernel Data - kernel_data = (KernelData *)0x68ffe000; - kernel_area = create_area(KERNEL_AREA_NAME, &kernel_data, B_EXACT_ADDRESS, 0x2000, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (kernel_area < 0) { - sprintf(str, GetString(STR_NO_KERNEL_DATA_ERR), strerror(kernel_area), kernel_area); - ErrorAlert(str); - return false; - } - emulator_data = &kernel_data->ed; - KernelDataAddr = (uint32)kernel_data; - D(bug("Kernel Data area %ld at %p, Emulator Data at %p\n", kernel_area, kernel_data, emulator_data)); - - // Load PowerMac ROM (upper 3MB) - try { - load_rom(); - } catch (file_open_error) { - ErrorAlert(STR_NO_ROM_FILE_ERR); - return false; - } catch (file_read_error) { - ErrorAlert(STR_ROM_FILE_READ_ERR); - return false; - } catch (rom_size_error) { - ErrorAlert(STR_ROM_SIZE_ERR); - return false; - } - - // Install ROM patches - if (!patch_rom()) { - ErrorAlert("Unsupported PowerMac ROM version"); - return false; - } - - // Create area for DR Cache - DRCacheAddr = DR_CACHE_BASE; - dr_cache_area = create_area(DR_CACHE_AREA_NAME, (void **)&DRCacheAddr, B_EXACT_ADDRESS, DR_CACHE_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (dr_cache_area < 0) { - sprintf(str, GetString(STR_NO_KERNEL_DATA_ERR), strerror(dr_cache_area), dr_cache_area); - ErrorAlert(str); - return false; - } - D(bug("DR Cache area %ld at %p\n", dr_cache_area, DRCacheAddr)); - - // Initialize Kernel Data - memset(kernel_data, 0, sizeof(KernelData)); - if (ROMType == ROMTYPE_NEWWORLD) { - kernel_data->v[0xc20 >> 2] = RAMSize; - kernel_data->v[0xc24 >> 2] = RAMSize; - kernel_data->v[0xc30 >> 2] = RAMSize; - kernel_data->v[0xc34 >> 2] = RAMSize; - kernel_data->v[0xc38 >> 2] = 0x00010020; - kernel_data->v[0xc3c >> 2] = 0x00200001; - kernel_data->v[0xc40 >> 2] = 0x00010000; - kernel_data->v[0xc50 >> 2] = RAMBaseMac; - kernel_data->v[0xc54 >> 2] = RAMSize; - kernel_data->v[0xf60 >> 2] = PVR; - kernel_data->v[0xf64 >> 2] = CPUClockSpeed; - kernel_data->v[0xf68 >> 2] = BusClockSpeed; - kernel_data->v[0xf6c >> 2] = CPUClockSpeed; - } else { - kernel_data->v[0xc80 >> 2] = RAMSize; - kernel_data->v[0xc84 >> 2] = RAMSize; - kernel_data->v[0xc90 >> 2] = RAMSize; - kernel_data->v[0xc94 >> 2] = RAMSize; - kernel_data->v[0xc98 >> 2] = 0x00010020; - kernel_data->v[0xc9c >> 2] = 0x00200001; - kernel_data->v[0xca0 >> 2] = 0x00010000; - kernel_data->v[0xcb0 >> 2] = RAMBaseMac; - kernel_data->v[0xcb4 >> 2] = RAMSize; - kernel_data->v[0xf80 >> 2] = PVR; - kernel_data->v[0xf84 >> 2] = CPUClockSpeed; - kernel_data->v[0xf88 >> 2] = BusClockSpeed; - kernel_data->v[0xf8c >> 2] = CPUClockSpeed; - } - - // Initialize extra low memory - memset((void *)0x2000, 0, 0x1000); - *(uint32 *)XLM_RESET_STACK = 0x2000; // Reset stack pointer - *(KernelData **)XLM_KERNEL_DATA = kernel_data;// For trap replacement routines - *(void **)XLM_TOC = TOC; // TOC pointer of emulator - *(uint32 *)XLM_PVR = PVR; // Theoretical PVR - - // Clear caches (as we loaded and patched code) - clear_caches((void *)ROM_BASE, ROM_AREA_SIZE, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE); - return true; -} - - -/* - * Deinitialize 680x0 emulation - */ - -void Exit680x0(void) -{ - // Delete DR Cache area - if (dr_cache_area >= 0) - delete_area(dr_cache_area); - - // Delete Kernel Data area - if (kernel_area >= 0) - delete_area(kernel_area); -} - - -/* - * Quit emulator (must only be called from main thread) - */ - -asm void QuitEmulator(void) -{ - lwz r0,XLM_EMUL_RETURN_PROC - mtlr r0 - blr -} - - -/* - * Reset and start 680x0 emulation - */ - -static asm void jump_to_rom(register uint32 entry) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - mfcr r0 - stw r0,4(r1) - stwu r1,-(56+19*4+18*8)(r1) - - // Save PowerPC registers - stmw r13,56(r1) - stfd f14,56+19*4+0*8(r1) - stfd f15,56+19*4+1*8(r1) - stfd f16,56+19*4+2*8(r1) - stfd f17,56+19*4+3*8(r1) - stfd f18,56+19*4+4*8(r1) - stfd f19,56+19*4+5*8(r1) - stfd f20,56+19*4+6*8(r1) - stfd f21,56+19*4+7*8(r1) - stfd f22,56+19*4+8*8(r1) - stfd f23,56+19*4+9*8(r1) - stfd f24,56+19*4+10*8(r1) - stfd f25,56+19*4+11*8(r1) - stfd f26,56+19*4+12*8(r1) - stfd f27,56+19*4+13*8(r1) - stfd f28,56+19*4+14*8(r1) - stfd f29,56+19*4+15*8(r1) - stfd f30,56+19*4+16*8(r1) - stfd f31,56+19*4+17*8(r1) - - // Move entry address to ctr, get pointer to Emulator Data - mtctr r3 - lwz r3,emulator_data(r2) - - // Skip over EMUL_RETURN routine and get its address - bl @1 - - - /* - * EMUL_RETURN: Returned from emulator - */ - - // Restore PowerPC registers - lwz r1,XLM_EMUL_RETURN_STACK - lwz r2,XLM_TOC - lmw r13,56(r1) - lfd f14,56+19*4+0*8(r1) - lfd f15,56+19*4+1*8(r1) - lfd f16,56+19*4+2*8(r1) - lfd f17,56+19*4+3*8(r1) - lfd f18,56+19*4+4*8(r1) - lfd f19,56+19*4+5*8(r1) - lfd f20,56+19*4+6*8(r1) - lfd f21,56+19*4+7*8(r1) - lfd f22,56+19*4+8*8(r1) - lfd f23,56+19*4+9*8(r1) - lfd f24,56+19*4+10*8(r1) - lfd f25,56+19*4+11*8(r1) - lfd f26,56+19*4+12*8(r1) - lfd f27,56+19*4+13*8(r1) - lfd f28,56+19*4+14*8(r1) - lfd f29,56+19*4+15*8(r1) - lfd f30,56+19*4+16*8(r1) - lfd f31,56+19*4+17*8(r1) - - // Exiting from 68k emulator - li r0,1 - stw r0,XLM_IRQ_NEST - li r0,MODE_EMUL_OP - stw r0,XLM_RUN_MODE - - // Return to caller of jump_to_rom() - lwz r0,56+19*4+18*8+8(r1) - mtlr r0 - lwz r0,56+19*4+18*8+4(r1) - mtcrf 0xff,r0 - addi r1,r1,56+19*4+18*8 - blr - - - // Save address of EMUL_RETURN routine for 68k emulator patch -@1 mflr r0 - stw r0,XLM_EMUL_RETURN_PROC - - // Skip over EXEC_RETURN routine and get its address - bl @2 - - - /* - * EXEC_RETURN: Returned from 68k routine executed with Execute68k() - */ - - // Save r25 (contains current 68k interrupt level) - stw r25,XLM_68K_R25 - - // Reentering EMUL_OP mode - li r0,MODE_EMUL_OP - stw r0,XLM_RUN_MODE - - // Save 68k registers - lwz r4,56+19*4+18*8+12(r1) - stw r8,M68kRegisters.d[0](r4) - stw r9,M68kRegisters.d[1](r4) - stw r10,M68kRegisters.d[2](r4) - stw r11,M68kRegisters.d[3](r4) - stw r12,M68kRegisters.d[4](r4) - stw r13,M68kRegisters.d[5](r4) - stw r14,M68kRegisters.d[6](r4) - stw r15,M68kRegisters.d[7](r4) - stw r16,M68kRegisters.a[0](r4) - stw r17,M68kRegisters.a[1](r4) - stw r18,M68kRegisters.a[2](r4) - stw r19,M68kRegisters.a[3](r4) - stw r20,M68kRegisters.a[4](r4) - stw r21,M68kRegisters.a[5](r4) - stw r22,M68kRegisters.a[6](r4) - - // Restore PowerPC registers - lmw r13,56(r1) -#if SAVE_FP_EXEC_68K - lfd f14,56+19*4+0*8(r1) - lfd f15,56+19*4+1*8(r1) - lfd f16,56+19*4+2*8(r1) - lfd f17,56+19*4+3*8(r1) - lfd f18,56+19*4+4*8(r1) - lfd f19,56+19*4+5*8(r1) - lfd f20,56+19*4+6*8(r1) - lfd f21,56+19*4+7*8(r1) - lfd f22,56+19*4+8*8(r1) - lfd f23,56+19*4+9*8(r1) - lfd f24,56+19*4+10*8(r1) - lfd f25,56+19*4+11*8(r1) - lfd f26,56+19*4+12*8(r1) - lfd f27,56+19*4+13*8(r1) - lfd f28,56+19*4+14*8(r1) - lfd f29,56+19*4+15*8(r1) - lfd f30,56+19*4+16*8(r1) - lfd f31,56+19*4+17*8(r1) -#endif - - // Return to caller - lwz r0,56+19*4+18*8+8(r1) - mtlr r0 - addi r1,r1,56+19*4+18*8 - blr - - - // Stave address of EXEC_RETURN routine for 68k emulator patch -@2 mflr r0 - stw r0,XLM_EXEC_RETURN_PROC - - // Skip over EMUL_OP routine and get its address - bl @3 - - - /* - * EMUL_OP: Execute native routine, selector in r5 (my own private mode switch) - * - * 68k registers are stored in a M68kRegisters struct on the stack - * which the native routine may read and modify - */ - - // Save r25 (contains current 68k interrupt level) - stw r25,XLM_68K_R25 - - // Entering EMUL_OP mode within 68k emulator - li r0,MODE_EMUL_OP - stw r0,XLM_RUN_MODE - - // Create PowerPC stack frame, reserve space for M68kRegisters - mr r3,r1 - subi r1,r1,56 // Fake "caller" frame - rlwinm r1,r1,0,0,29 // Align stack - - mfcr r0 - rlwinm r0,r0,0,11,8 - stw r0,4(r1) - mfxer r0 - stw r0,16(r1) - stw r2,12(r1) - stwu r1,-(56+16*4+15*8)(r1) - lwz r2,XLM_TOC - - // Save 68k registers - stw r8,56+M68kRegisters.d[0](r1) - stw r9,56+M68kRegisters.d[1](r1) - stw r10,56+M68kRegisters.d[2](r1) - stw r11,56+M68kRegisters.d[3](r1) - stw r12,56+M68kRegisters.d[4](r1) - stw r13,56+M68kRegisters.d[5](r1) - stw r14,56+M68kRegisters.d[6](r1) - stw r15,56+M68kRegisters.d[7](r1) - stw r16,56+M68kRegisters.a[0](r1) - stw r17,56+M68kRegisters.a[1](r1) - stw r18,56+M68kRegisters.a[2](r1) - stw r19,56+M68kRegisters.a[3](r1) - stw r20,56+M68kRegisters.a[4](r1) - stw r21,56+M68kRegisters.a[5](r1) - stw r22,56+M68kRegisters.a[6](r1) - stw r3,56+M68kRegisters.a[7](r1) - stfd f0,56+16*4+0*8(r1) - stfd f1,56+16*4+1*8(r1) - stfd f2,56+16*4+2*8(r1) - stfd f3,56+16*4+3*8(r1) - stfd f4,56+16*4+4*8(r1) - stfd f5,56+16*4+5*8(r1) - stfd f6,56+16*4+6*8(r1) - stfd f7,56+16*4+7*8(r1) - mffs f0 - stfd f8,56+16*4+8*8(r1) - stfd f9,56+16*4+9*8(r1) - stfd f10,56+16*4+10*8(r1) - stfd f11,56+16*4+11*8(r1) - stfd f12,56+16*4+12*8(r1) - stfd f13,56+16*4+13*8(r1) - stfd f0,56+16*4+14*8(r1) - - // Execute native routine - mr r3,r5 - addi r4,r1,56 - bl EmulOp - - // Restore 68k registers - lwz r8,56+M68kRegisters.d[0](r1) - lwz r9,56+M68kRegisters.d[1](r1) - lwz r10,56+M68kRegisters.d[2](r1) - lwz r11,56+M68kRegisters.d[3](r1) - lwz r12,56+M68kRegisters.d[4](r1) - lwz r13,56+M68kRegisters.d[5](r1) - lwz r14,56+M68kRegisters.d[6](r1) - lwz r15,56+M68kRegisters.d[7](r1) - lwz r16,56+M68kRegisters.a[0](r1) - lwz r17,56+M68kRegisters.a[1](r1) - lwz r18,56+M68kRegisters.a[2](r1) - lwz r19,56+M68kRegisters.a[3](r1) - lwz r20,56+M68kRegisters.a[4](r1) - lwz r21,56+M68kRegisters.a[5](r1) - lwz r22,56+M68kRegisters.a[6](r1) - lwz r3,56+M68kRegisters.a[7](r1) - lfd f13,56+16*4+14*8(r1) - lfd f0,56+16*4+0*8(r1) - lfd f1,56+16*4+1*8(r1) - lfd f2,56+16*4+2*8(r1) - lfd f3,56+16*4+3*8(r1) - lfd f4,56+16*4+4*8(r1) - lfd f5,56+16*4+5*8(r1) - lfd f6,56+16*4+6*8(r1) - lfd f7,56+16*4+7*8(r1) - mtfsf 0xff,f13 - lfd f8,56+16*4+8*8(r1) - lfd f9,56+16*4+9*8(r1) - lfd f10,56+16*4+10*8(r1) - lfd f11,56+16*4+11*8(r1) - lfd f12,56+16*4+12*8(r1) - lfd f13,56+16*4+13*8(r1) - - // Delete PowerPC stack frame - lwz r2,56+16*4+15*8+12(r1) - lwz r0,56+16*4+15*8+16(r1) - mtxer r0 - lwz r0,56+16*4+15*8+4(r1) - mtcrf 0xff,r0 - mr r1,r3 - - // Reeintering 68k emulator - li r0,MODE_68K - stw r0,XLM_RUN_MODE - - // Set r0 to 0 for 68k emulator - li r0,0 - - // Execute next 68k opcode - rlwimi r29,r27,3,13,28 - lhau r27,2(r24) - mtlr r29 - blr - - - // Save address of EMUL_OP routine for 68k emulator patch -@3 mflr r0 - stw r0,XLM_EMUL_OP_PROC - - // Save stack pointer for EMUL_RETURN - stw r1,XLM_EMUL_RETURN_STACK - - // Preset registers for ROM boot routine - lis r3,0x40b0 // Pointer to ROM boot structure - ori r3,r3,0xd000 - - // 68k emulator is now active - li r0,MODE_68K - stw r0,XLM_RUN_MODE - - // Jump to ROM - bctr -} - -void Start680x0(void) -{ - // Install interrupt signal handler - sigemptyset(&sigusr1_action.sa_mask); - sigusr1_action.sa_handler = (__signal_func_ptr)(sigusr1_handler); - sigusr1_action.sa_flags = 0; - sigusr1_action.sa_userdata = NULL; - sigaction(SIGUSR1, &sigusr1_action, NULL); - - // Install signal stack - set_signal_stack(malloc(SIG_STACK_SIZE), SIG_STACK_SIZE); - - // We're now ready to receive signals - ReadyForSignals = true; - - D(bug("Jumping to ROM\n")); - jump_to_rom(ROM_BASE + 0x310000); - D(bug("Returned from ROM\n")); - - // We're no longer ready to receive signals - ReadyForSignals = false; -} - - -/* - * Trigger interrupt - */ - -void TriggerInterrupt(void) -{ - idle_resume(); - if (emul_thread > 0 && ReadyForSignals) - send_signal(emul_thread, SIGUSR1); -} - -void TriggerNMI(void) -{ - //!! not implemented yet -} - - -/* - * Execute 68k subroutine - * r->a[7] and r->sr are unused! - */ - -static asm void execute_68k(register uint32 addr, register M68kRegisters *r) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - stw r4,12(r1) - stwu r1,-(56+19*4+18*8)(r1) - - // Save PowerPC registers - stmw r13,56(r1) -#if SAVE_FP_EXEC_68K - stfd f14,56+19*4+0*8(r1) - stfd f15,56+19*4+1*8(r1) - stfd f16,56+19*4+2*8(r1) - stfd f17,56+19*4+3*8(r1) - stfd f18,56+19*4+4*8(r1) - stfd f19,56+19*4+5*8(r1) - stfd f20,56+19*4+6*8(r1) - stfd f21,56+19*4+7*8(r1) - stfd f22,56+19*4+8*8(r1) - stfd f23,56+19*4+9*8(r1) - stfd f24,56+19*4+10*8(r1) - stfd f25,56+19*4+11*8(r1) - stfd f26,56+19*4+12*8(r1) - stfd f27,56+19*4+13*8(r1) - stfd f28,56+19*4+14*8(r1) - stfd f29,56+19*4+15*8(r1) - stfd f30,56+19*4+16*8(r1) - stfd f31,56+19*4+17*8(r1) -#endif - - // Set up registers for 68k emulator - lwz r31,XLM_KERNEL_DATA // Pointer to Kernel Data - addi r31,r31,0x1000 // points to Emulator Data - li r0,0 - mtcrf 0xff,r0 - creqv 11,11,11 // Supervisor mode - lwz r8,M68kRegisters.d[0](r4) - lwz r9,M68kRegisters.d[1](r4) - lwz r10,M68kRegisters.d[2](r4) - lwz r11,M68kRegisters.d[3](r4) - lwz r12,M68kRegisters.d[4](r4) - lwz r13,M68kRegisters.d[5](r4) - lwz r14,M68kRegisters.d[6](r4) - lwz r15,M68kRegisters.d[7](r4) - lwz r16,M68kRegisters.a[0](r4) - lwz r17,M68kRegisters.a[1](r4) - lwz r18,M68kRegisters.a[2](r4) - lwz r19,M68kRegisters.a[3](r4) - lwz r20,M68kRegisters.a[4](r4) - lwz r21,M68kRegisters.a[5](r4) - lwz r22,M68kRegisters.a[6](r4) - li r23,0 - mr r24,r3 - lwz r25,XLM_68K_R25 // MSB of SR - li r26,0 - li r28,0 // VBR - lwz r29,0x74(r31) // Pointer to opcode table - lwz r30,0x78(r31) // Address of emulator - - // Reentering 68k emulator - li r0,MODE_68K - stw r0,XLM_RUN_MODE - - // Set r0 to 0 for 68k emulator - li r0,0 - - // Execute 68k opcode - lha r27,0(r24) - rlwimi r29,r27,3,13,28 - lhau r27,2(r24) - mtlr r29 - blr -} - -void Execute68k(uint32 addr, M68kRegisters *r) -{ - uint16 proc[4] = {M68K_JSR, addr >> 16, addr & 0xffff, M68K_EXEC_RETURN}; - execute_68k((uint32)proc, r); -} - - -/* - * Execute MacOS 68k trap - * r->a[7] and r->sr are unused! - */ - -void Execute68kTrap(uint16 trap, struct M68kRegisters *r) -{ - uint16 proc[2] = {trap, M68K_EXEC_RETURN}; - execute_68k((uint32)proc, r); -} - - -/* - * USR1 handler - */ - -static void sigusr1_handler(int sig, void *arg, vregs *r) -{ - // Do nothing if interrupts are disabled - if ((*(int32 *)XLM_IRQ_NEST) > 0) - return; - - // 68k emulator active? Then trigger 68k interrupt level 1 - if (*(uint32 *)XLM_RUN_MODE == MODE_68K) { - *(uint16 *)(kernel_data->v[0x67c >> 2]) = 1; - r->cr |= kernel_data->v[0x674 >> 2]; - } -} diff --git a/BasiliskII/src/prefs_items.cpp b/BasiliskII/src/prefs_items.cpp index 4a7f1a34..afb692b9 100644 --- a/BasiliskII/src/prefs_items.cpp +++ b/BasiliskII/src/prefs_items.cpp @@ -92,17 +92,7 @@ void AddPrefsDefaults(void) PrefsAddBool("noclipconversion", false); PrefsAddBool("nogui", false); -#if USE_JIT - // JIT compiler specific options - PrefsAddBool("jit", true); - PrefsAddBool("jitfpu", true); - PrefsAddBool("jitdebug", false); - PrefsAddInt32("jitcachesize", 8192); - PrefsAddBool("jitlazyflush", true); - PrefsAddBool("jitinline", true); -#else PrefsAddBool("jit", false); -#endif PrefsAddInt32("keyboardtype", 5); } diff --git a/BasiliskII/src/rom_patches.cpp b/BasiliskII/src/rom_patches.cpp index db404169..4b79f01c 100644 --- a/BasiliskII/src/rom_patches.cpp +++ b/BasiliskII/src/rom_patches.cpp @@ -827,7 +827,7 @@ bool CheckROM(void) // Read version ROMVersion = ntohs(*(uint16 *)(ROMBaseHost + 8)); -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING // Real and direct addressing modes require a 32-bit clean ROM return ROMVersion == ROM_VERSION_32; #else @@ -1254,15 +1254,6 @@ static bool patch_rom_32(void) *wp++ = htons(0x0cea); *wp = htons(M68K_RTS); -#if REAL_ADDRESSING - // Move system zone to start of Mac RAM - wp = (uint16 *)(ROMBaseHost + 0x50a); - *wp++ = htons(HiWord(RAMBaseMac + 0x2000)); - *wp++ = htons(LoWord(RAMBaseMac + 0x2000)); - *wp++ = htons(HiWord(RAMBaseMac + 0x3800)); - *wp = htons(LoWord(RAMBaseMac + 0x3800)); -#endif - #if !ROM_IS_WRITE_PROTECTED #if defined(USE_SCRATCHMEM_SUBTERFUGE) // Set fake handle at 0x0000 to scratch memory area (so broken Mac programs won't write into Mac ROM) @@ -1277,20 +1268,6 @@ static bool patch_rom_32(void) #endif #endif -#if REAL_ADDRESSING && defined(AMIGA) - // Don't overwrite SysBase under AmigaOS - wp = (uint16 *)(ROMBaseHost + 0xccb4); - *wp++ = htons(M68K_NOP); - *wp = htons(M68K_NOP); -#endif - -#if REAL_ADDRESSING && !defined(AMIGA) - // gb-- Temporary hack to get rid of crashes in Speedometer - wp = (uint16 *)(ROMBaseHost + 0xdba2); - if (ntohs(*wp) == 0x662c) // bne.b #$2c - *wp = htons(0x602c); // bra.b #$2c -#endif - // Don't write to VIA in InitTimeMgr wp = (uint16 *)(ROMBaseHost + 0xb0e2); *wp++ = htons(0x4cdf); // movem.l (sp)+,d0-d5/a0-a4 diff --git a/BasiliskII/src/rsrc_patches.cpp b/BasiliskII/src/rsrc_patches.cpp index cdff157e..5faeeb36 100644 --- a/BasiliskII/src/rsrc_patches.cpp +++ b/BasiliskII/src/rsrc_patches.cpp @@ -30,9 +30,6 @@ #include "audio_defs.h" #include "rsrc_patches.h" -#if ENABLE_MON -#include "mon.h" -#endif #define DEBUG 0 #include "debug.h" diff --git a/BasiliskII/src/slirp/COPYRIGHT b/BasiliskII/src/slirp/COPYRIGHT deleted file mode 100644 index b7d6568e..00000000 --- a/BasiliskII/src/slirp/COPYRIGHT +++ /dev/null @@ -1,61 +0,0 @@ -Slirp was written by Danny Gasparovski. -Copyright (c), 1995,1996 All Rights Reserved. - -Slirp is maintained by Kelly Price - -Slirp is free software; "free" as in you don't have to pay for it, and you -are free to do whatever you want with it. I do not accept any donations, -monetary or otherwise, for Slirp. Instead, I would ask you to pass this -potential donation to your favorite charity. In fact, I encourage -*everyone* who finds Slirp useful to make a small donation to their -favorite charity (for example, GreenPeace). This is not a requirement, but -a suggestion from someone who highly values the service they provide. - -The copyright terms and conditions: - ----BEGIN--- - - Copyright (c) 1995,1996 Danny Gasparovski. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - DANNY GASPAROVSKI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 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 SUCH DAMAGE. - ----END--- - -This basically means you can do anything you want with the software, except -1) call it your own, and 2) claim warranty on it. There is no warranty for -this software. None. Nada. If you lose a million dollars while using -Slirp, that's your loss not mine. So, ***USE AT YOUR OWN RISK!***. - -If these conditions cannot be met due to legal restrictions (E.g. where it -is against the law to give out Software without warranty), you must cease -using the software and delete all copies you have. - -Slirp uses code that is copyrighted by the following people/organizations: - -Juha Pirkola. -Gregory M. Christy. -The Regents of the University of California. -Carnegie Mellon University. -The Australian National University. -RSA Data Security, Inc. - -Please read the top of each source file for the details on the various -copyrights. diff --git a/BasiliskII/src/slirp/VERSION b/BasiliskII/src/slirp/VERSION deleted file mode 100644 index 353ad940..00000000 --- a/BasiliskII/src/slirp/VERSION +++ /dev/null @@ -1 +0,0 @@ -qemu 0.9.0 (2007/02/05) diff --git a/BasiliskII/src/slirp/bootp.c b/BasiliskII/src/slirp/bootp.c deleted file mode 100644 index a51b80c9..00000000 --- a/BasiliskII/src/slirp/bootp.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * QEMU BOOTP/DHCP server - * - * Copyright (c) 2004 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, 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: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * 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, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include - -/* XXX: only DHCP is supported */ - -#define NB_ADDR 16 - -#define START_ADDR 15 - -#define LEASE_TIME (24 * 3600) - -typedef struct { - uint8_t allocated; - uint8_t macaddr[6]; -} BOOTPClient; - -BOOTPClient bootp_clients[NB_ADDR]; - -static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE }; - -static BOOTPClient *get_new_addr(struct in_addr *paddr) -{ - BOOTPClient *bc; - int i; - - for(i = 0; i < NB_ADDR; i++) { - if (!bootp_clients[i].allocated) - goto found; - } - return NULL; - found: - bc = &bootp_clients[i]; - bc->allocated = 1; - paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); - return bc; -} - -static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t *macaddr) -{ - BOOTPClient *bc; - int i; - - for(i = 0; i < NB_ADDR; i++) { - if (!memcmp(macaddr, bootp_clients[i].macaddr, 6)) - goto found; - } - return NULL; - found: - bc = &bootp_clients[i]; - bc->allocated = 1; - paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); - return bc; -} - -static void dhcp_decode(const uint8_t *buf, int size, - int *pmsg_type) -{ - const uint8_t *p, *p_end; - int len, tag; - - *pmsg_type = 0; - - p = buf; - p_end = buf + size; - if (size < 5) - return; - if (memcmp(p, rfc1533_cookie, 4) != 0) - return; - p += 4; - while (p < p_end) { - tag = p[0]; - if (tag == RFC1533_PAD) { - p++; - } else if (tag == RFC1533_END) { - break; - } else { - p++; - if (p >= p_end) - break; - len = *p++; - - switch(tag) { - case RFC2132_MSG_TYPE: - if (len >= 1) - *pmsg_type = p[0]; - break; - default: - break; - } - p += len; - } - } -} - -static void bootp_reply(struct bootp_t *bp) -{ - BOOTPClient *bc; - struct mbuf *m; - struct bootp_t *rbp; - struct sockaddr_in saddr, daddr; - struct in_addr dns_addr; - int dhcp_msg_type, val; - uint8_t *q; - - /* extract exact DHCP msg type */ - dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type); - - if (dhcp_msg_type == 0) - dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */ - - if (dhcp_msg_type != DHCPDISCOVER && - dhcp_msg_type != DHCPREQUEST) - return; - /* XXX: this is a hack to get the client mac address */ - memcpy(client_ethaddr, bp->bp_hwaddr, 6); - - if ((m = m_get()) == NULL) - return; - m->m_data += if_maxlinkhdr; - rbp = (struct bootp_t *)m->m_data; - m->m_data += sizeof(struct udpiphdr); - memset(rbp, 0, sizeof(struct bootp_t)); - - if (dhcp_msg_type == DHCPDISCOVER) { - new_addr: - bc = get_new_addr(&daddr.sin_addr); - if (!bc) - return; - memcpy(bc->macaddr, client_ethaddr, 6); - } else { - bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr); - if (!bc) { - /* if never assigned, behaves as if it was already - assigned (windows fix because it remembers its address) */ - goto new_addr; - } - } - - saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS); - saddr.sin_port = htons(BOOTP_SERVER); - - daddr.sin_port = htons(BOOTP_CLIENT); - - rbp->bp_op = BOOTP_REPLY; - rbp->bp_xid = bp->bp_xid; - rbp->bp_htype = 1; - rbp->bp_hlen = 6; - memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6); - - rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */ - rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */ - - q = rbp->bp_vend; - memcpy(q, rfc1533_cookie, 4); - q += 4; - - if (dhcp_msg_type == DHCPDISCOVER) { - *q++ = RFC2132_MSG_TYPE; - *q++ = 1; - *q++ = DHCPOFFER; - } else if (dhcp_msg_type == DHCPREQUEST) { - *q++ = RFC2132_MSG_TYPE; - *q++ = 1; - *q++ = DHCPACK; - } - - if (dhcp_msg_type == DHCPDISCOVER || - dhcp_msg_type == DHCPREQUEST) { - *q++ = RFC2132_SRV_ID; - *q++ = 4; - memcpy(q, &saddr.sin_addr, 4); - q += 4; - - *q++ = RFC1533_NETMASK; - *q++ = 4; - *q++ = 0xff; - *q++ = 0xff; - *q++ = 0xff; - *q++ = 0x00; - - *q++ = RFC1533_GATEWAY; - *q++ = 4; - memcpy(q, &saddr.sin_addr, 4); - q += 4; - - *q++ = RFC1533_DNS; - *q++ = 4; - dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS); - memcpy(q, &dns_addr, 4); - q += 4; - - *q++ = RFC2132_LEASE_TIME; - *q++ = 4; - val = htonl(LEASE_TIME); - memcpy(q, &val, 4); - q += 4; - - if (*slirp_hostname) { - val = strlen(slirp_hostname); - *q++ = RFC1533_HOSTNAME; - *q++ = val; - memcpy(q, slirp_hostname, val); - q += val; - } - } - *q++ = RFC1533_END; - - m->m_len = sizeof(struct bootp_t) - - sizeof(struct ip) - sizeof(struct udphdr); - udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); -} - -void bootp_input(struct mbuf *m) -{ - struct bootp_t *bp = mtod(m, struct bootp_t *); - - if (bp->bp_op == BOOTP_REQUEST) { - bootp_reply(bp); - } -} diff --git a/BasiliskII/src/slirp/bootp.h b/BasiliskII/src/slirp/bootp.h deleted file mode 100644 index 54a86ca2..00000000 --- a/BasiliskII/src/slirp/bootp.h +++ /dev/null @@ -1,121 +0,0 @@ -/* bootp/dhcp defines */ - -#define BOOTP_SERVER 67 -#define BOOTP_CLIENT 68 - -#define BOOTP_REQUEST 1 -#define BOOTP_REPLY 2 - -#define RFC1533_COOKIE 99, 130, 83, 99 -#define RFC1533_PAD 0 -#define RFC1533_NETMASK 1 -#define RFC1533_TIMEOFFSET 2 -#define RFC1533_GATEWAY 3 -#define RFC1533_TIMESERVER 4 -#define RFC1533_IEN116NS 5 -#define RFC1533_DNS 6 -#define RFC1533_LOGSERVER 7 -#define RFC1533_COOKIESERVER 8 -#define RFC1533_LPRSERVER 9 -#define RFC1533_IMPRESSSERVER 10 -#define RFC1533_RESOURCESERVER 11 -#define RFC1533_HOSTNAME 12 -#define RFC1533_BOOTFILESIZE 13 -#define RFC1533_MERITDUMPFILE 14 -#define RFC1533_DOMAINNAME 15 -#define RFC1533_SWAPSERVER 16 -#define RFC1533_ROOTPATH 17 -#define RFC1533_EXTENSIONPATH 18 -#define RFC1533_IPFORWARDING 19 -#define RFC1533_IPSOURCEROUTING 20 -#define RFC1533_IPPOLICYFILTER 21 -#define RFC1533_IPMAXREASSEMBLY 22 -#define RFC1533_IPTTL 23 -#define RFC1533_IPMTU 24 -#define RFC1533_IPMTUPLATEAU 25 -#define RFC1533_INTMTU 26 -#define RFC1533_INTLOCALSUBNETS 27 -#define RFC1533_INTBROADCAST 28 -#define RFC1533_INTICMPDISCOVER 29 -#define RFC1533_INTICMPRESPOND 30 -#define RFC1533_INTROUTEDISCOVER 31 -#define RFC1533_INTROUTESOLICIT 32 -#define RFC1533_INTSTATICROUTES 33 -#define RFC1533_LLTRAILERENCAP 34 -#define RFC1533_LLARPCACHETMO 35 -#define RFC1533_LLETHERNETENCAP 36 -#define RFC1533_TCPTTL 37 -#define RFC1533_TCPKEEPALIVETMO 38 -#define RFC1533_TCPKEEPALIVEGB 39 -#define RFC1533_NISDOMAIN 40 -#define RFC1533_NISSERVER 41 -#define RFC1533_NTPSERVER 42 -#define RFC1533_VENDOR 43 -#define RFC1533_NBNS 44 -#define RFC1533_NBDD 45 -#define RFC1533_NBNT 46 -#define RFC1533_NBSCOPE 47 -#define RFC1533_XFS 48 -#define RFC1533_XDM 49 - -#define RFC2132_REQ_ADDR 50 -#define RFC2132_LEASE_TIME 51 -#define RFC2132_MSG_TYPE 53 -#define RFC2132_SRV_ID 54 -#define RFC2132_PARAM_LIST 55 -#define RFC2132_MAX_SIZE 57 -#define RFC2132_RENEWAL_TIME 58 -#define RFC2132_REBIND_TIME 59 - -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPACK 5 - -#define RFC1533_VENDOR_MAJOR 0 -#define RFC1533_VENDOR_MINOR 0 - -#define RFC1533_VENDOR_MAGIC 128 -#define RFC1533_VENDOR_ADDPARM 129 -#define RFC1533_VENDOR_ETHDEV 130 -#define RFC1533_VENDOR_HOWTO 132 -#define RFC1533_VENDOR_MNUOPTS 160 -#define RFC1533_VENDOR_SELECTION 176 -#define RFC1533_VENDOR_MOTD 184 -#define RFC1533_VENDOR_NUMOFMOTD 8 -#define RFC1533_VENDOR_IMG 192 -#define RFC1533_VENDOR_NUMOFIMG 16 - -#define RFC1533_END 255 -#define BOOTP_VENDOR_LEN 64 -#define DHCP_OPT_LEN 312 - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct bootp_t { - struct ip ip; - struct udphdr udp; - uint8_t bp_op; - uint8_t bp_htype; - uint8_t bp_hlen; - uint8_t bp_hops; - uint32_t bp_xid; - uint16_t bp_secs; - uint16_t unused; - struct in_addr bp_ciaddr; - struct in_addr bp_yiaddr; - struct in_addr bp_siaddr; - struct in_addr bp_giaddr; - uint8_t bp_hwaddr[16]; - uint8_t bp_sname[64]; - uint8_t bp_file[128]; - uint8_t bp_vend[DHCP_OPT_LEN]; -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) -#endif - -void bootp_input(struct mbuf *m); diff --git a/BasiliskII/src/slirp/cksum.c b/BasiliskII/src/slirp/cksum.c deleted file mode 100644 index 66d3f230..00000000 --- a/BasiliskII/src/slirp/cksum.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 1988, 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93 - * in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp - */ - -#include - -/* - * Checksum routine for Internet Protocol family headers (Portable Version). - * - * This routine is very heavily used in the network - * code and should be modified for each CPU to be as fast as possible. - * - * XXX Since we will never span more than 1 mbuf, we can optimise this - */ - -#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) -#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} - -int cksum(struct mbuf *m, int len) -{ - register u_int16_t *w; - register int sum = 0; - register int mlen = 0; - int byte_swapped = 0; - - union { - u_int8_t c[2]; - u_int16_t s; - } s_util; - union { - u_int16_t s[2]; - u_int32_t l; - } l_util; - - if (m->m_len == 0) - goto cont; - w = mtod(m, u_int16_t *); - - mlen = m->m_len; - - if (len < mlen) - mlen = len; - len -= mlen; - /* - * Force to even boundary. - */ - if ((1 & (long) w) && (mlen > 0)) { - REDUCE; - sum <<= 8; - s_util.c[0] = *(u_int8_t *)w; - w = (u_int16_t *)((int8_t *)w + 1); - mlen--; - byte_swapped = 1; - } - /* - * Unroll the loop to make overhead from - * branches &c small. - */ - while ((mlen -= 32) >= 0) { - sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; - sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; - sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11]; - sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15]; - w += 16; - } - mlen += 32; - while ((mlen -= 8) >= 0) { - sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; - w += 4; - } - mlen += 8; - if (mlen == 0 && byte_swapped == 0) - goto cont; - REDUCE; - while ((mlen -= 2) >= 0) { - sum += *w++; - } - - if (byte_swapped) { - REDUCE; - sum <<= 8; - byte_swapped = 0; - if (mlen == -1) { - s_util.c[1] = *(u_int8_t *)w; - sum += s_util.s; - mlen = 0; - } else - - mlen = -1; - } else if (mlen == -1) - s_util.c[0] = *(u_int8_t *)w; - -cont: -#ifdef DEBUG - if (len) { - DEBUG_ERROR((dfd, "cksum: out of data\n")); - DEBUG_ERROR((dfd, " len = %d\n", len)); - } -#endif - if (mlen == -1) { - /* The last mbuf has odd # of bytes. Follow the - standard (the odd byte may be shifted left by 8 bits - or not as determined by endian-ness of the machine) */ - s_util.c[1] = 0; - sum += s_util.s; - } - REDUCE; - return (~sum & 0xffff); -} diff --git a/BasiliskII/src/slirp/ctl.h b/BasiliskII/src/slirp/ctl.h deleted file mode 100644 index 4a8576dc..00000000 --- a/BasiliskII/src/slirp/ctl.h +++ /dev/null @@ -1,7 +0,0 @@ -#define CTL_CMD 0 -#define CTL_EXEC 1 -#define CTL_ALIAS 2 -#define CTL_DNS 3 - -#define CTL_SPECIAL "10.0.2.0" -#define CTL_LOCAL "10.0.2.15" diff --git a/BasiliskII/src/slirp/debug.c b/BasiliskII/src/slirp/debug.c deleted file mode 100644 index 916b9a8e..00000000 --- a/BasiliskII/src/slirp/debug.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * Portions copyright (c) 2000 Kelly Price. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include - -FILE *dfd = NULL; -#ifdef DEBUG -int dostats = 1; -#else -int dostats = 0; -#endif -int slirp_debug = 0; - -/* Carry over one item from main.c so that the tty's restored. - * Only done when the tty being used is /dev/tty --RedWolf */ -extern struct termios slirp_tty_settings; -extern int slirp_tty_restore; - - -void -debug_init(file, dbg) - char *file; - int dbg; -{ - /* Close the old debugging file */ - if (dfd) - fclose(dfd); - - dfd = fopen(file,"w"); - if (dfd != NULL) { -#if 0 - fprintf(dfd,"Slirp %s - Debugging Started.\n", SLIRP_VERSION); -#endif - fprintf(dfd,"Debugging Started level %i.\r\n",dbg); - fflush(dfd); - slirp_debug = dbg; - } else { - lprint("Error: Debugging file \"%s\" could not be opened: %s\r\n", - file, strerror(errno)); - } -} - -/* - * Dump a packet in the same format as tcpdump -x - */ -#ifdef DEBUG -void -dump_packet(dat, n) - void *dat; - int n; -{ - u_char *pptr = (u_char *)dat; - int j,k; - - n /= 16; - n++; - DEBUG_MISC((dfd, "PACKET DUMPED: \n")); - for(j = 0; j < n; j++) { - for(k = 0; k < 6; k++) - DEBUG_MISC((dfd, "%02x ", *pptr++)); - DEBUG_MISC((dfd, "\n")); - fflush(dfd); - } -} -#endif - -#if 0 -/* - * Statistic routines - * - * These will print statistics to the screen, the debug file (dfd), or - * a buffer, depending on "type", so that the stats can be sent over - * the link as well. - */ - -void -ttystats(ttyp) - struct ttys *ttyp; -{ - struct slirp_ifstats *is = &ttyp->ifstats; - char buff[512]; - - lprint(" \r\n"); - - if (if_comp & IF_COMPRESS) - strcpy(buff, "on"); - else if (if_comp & IF_NOCOMPRESS) - strcpy(buff, "off"); - else - strcpy(buff, "off (for now)"); - lprint("Unit %d:\r\n", ttyp->unit); - lprint(" using %s encapsulation (VJ compression is %s)\r\n", ( -#ifdef USE_PPP - ttyp->proto==PROTO_PPP?"PPP": -#endif - "SLIP"), buff); - lprint(" %d baudrate\r\n", ttyp->baud); - lprint(" interface is %s\r\n", ttyp->up?"up":"down"); - lprint(" using fd %d, guardian pid is %d\r\n", ttyp->fd, ttyp->pid); -#ifndef FULL_BOLT - lprint(" towrite is %d bytes\r\n", ttyp->towrite); -#endif - if (ttyp->zeros) - lprint(" %d zeros have been typed\r\n", ttyp->zeros); - else if (ttyp->ones) - lprint(" %d ones have been typed\r\n", ttyp->ones); - lprint("Interface stats:\r\n"); - lprint(" %6d output packets sent (%d bytes)\r\n", is->out_pkts, is->out_bytes); - lprint(" %6d output packets dropped (%d bytes)\r\n", is->out_errpkts, is->out_errbytes); - lprint(" %6d input packets received (%d bytes)\r\n", is->in_pkts, is->in_bytes); - lprint(" %6d input packets dropped (%d bytes)\r\n", is->in_errpkts, is->in_errbytes); - lprint(" %6d bad input packets\r\n", is->in_mbad); -} - -void -allttystats() -{ - struct ttys *ttyp; - - for (ttyp = ttys; ttyp; ttyp = ttyp->next) - ttystats(ttyp); -} -#endif - -void -ipstats() -{ - lprint(" \r\n"); - - lprint("IP stats:\r\n"); - lprint(" %6d total packets received (%d were unaligned)\r\n", - ipstat.ips_total, ipstat.ips_unaligned); - lprint(" %6d with incorrect version\r\n", ipstat.ips_badvers); - lprint(" %6d with bad header checksum\r\n", ipstat.ips_badsum); - lprint(" %6d with length too short (len < sizeof(iphdr))\r\n", ipstat.ips_tooshort); - lprint(" %6d with length too small (len < ip->len)\r\n", ipstat.ips_toosmall); - lprint(" %6d with bad header length\r\n", ipstat.ips_badhlen); - lprint(" %6d with bad packet length\r\n", ipstat.ips_badlen); - lprint(" %6d fragments received\r\n", ipstat.ips_fragments); - lprint(" %6d fragments dropped\r\n", ipstat.ips_fragdropped); - lprint(" %6d fragments timed out\r\n", ipstat.ips_fragtimeout); - lprint(" %6d packets reassembled ok\r\n", ipstat.ips_reassembled); - lprint(" %6d outgoing packets fragmented\r\n", ipstat.ips_fragmented); - lprint(" %6d total outgoing fragments\r\n", ipstat.ips_ofragments); - lprint(" %6d with bad protocol field\r\n", ipstat.ips_noproto); - lprint(" %6d total packets delivered\r\n", ipstat.ips_delivered); -} - -#if 0 -void -vjstats() -{ - lprint(" \r\n"); - - lprint("VJ compression stats:\r\n"); - - lprint(" %6d outbound packets (%d compressed)\r\n", - comp_s.sls_packets, comp_s.sls_compressed); - lprint(" %6d searches for connection stats (%d misses)\r\n", - comp_s.sls_searches, comp_s.sls_misses); - lprint(" %6d inbound uncompressed packets\r\n", comp_s.sls_uncompressedin); - lprint(" %6d inbound compressed packets\r\n", comp_s.sls_compressedin); - lprint(" %6d inbound unknown type packets\r\n", comp_s.sls_errorin); - lprint(" %6d inbound packets tossed due to error\r\n", comp_s.sls_tossed); -} -#endif - -void -tcpstats() -{ - lprint(" \r\n"); - - lprint("TCP stats:\r\n"); - - lprint(" %6d packets sent\r\n", tcpstat.tcps_sndtotal); - lprint(" %6d data packets (%d bytes)\r\n", - tcpstat.tcps_sndpack, tcpstat.tcps_sndbyte); - lprint(" %6d data packets retransmitted (%d bytes)\r\n", - tcpstat.tcps_sndrexmitpack, tcpstat.tcps_sndrexmitbyte); - lprint(" %6d ack-only packets (%d delayed)\r\n", - tcpstat.tcps_sndacks, tcpstat.tcps_delack); - lprint(" %6d URG only packets\r\n", tcpstat.tcps_sndurg); - lprint(" %6d window probe packets\r\n", tcpstat.tcps_sndprobe); - lprint(" %6d window update packets\r\n", tcpstat.tcps_sndwinup); - lprint(" %6d control (SYN/FIN/RST) packets\r\n", tcpstat.tcps_sndctrl); - lprint(" %6d times tcp_output did nothing\r\n", tcpstat.tcps_didnuttin); - - lprint(" %6d packets received\r\n", tcpstat.tcps_rcvtotal); - lprint(" %6d acks (for %d bytes)\r\n", - tcpstat.tcps_rcvackpack, tcpstat.tcps_rcvackbyte); - lprint(" %6d duplicate acks\r\n", tcpstat.tcps_rcvdupack); - lprint(" %6d acks for unsent data\r\n", tcpstat.tcps_rcvacktoomuch); - lprint(" %6d packets received in sequence (%d bytes)\r\n", - tcpstat.tcps_rcvpack, tcpstat.tcps_rcvbyte); - lprint(" %6d completely duplicate packets (%d bytes)\r\n", - tcpstat.tcps_rcvduppack, tcpstat.tcps_rcvdupbyte); - - lprint(" %6d packets with some duplicate data (%d bytes duped)\r\n", - tcpstat.tcps_rcvpartduppack, tcpstat.tcps_rcvpartdupbyte); - lprint(" %6d out-of-order packets (%d bytes)\r\n", - tcpstat.tcps_rcvoopack, tcpstat.tcps_rcvoobyte); - lprint(" %6d packets of data after window (%d bytes)\r\n", - tcpstat.tcps_rcvpackafterwin, tcpstat.tcps_rcvbyteafterwin); - lprint(" %6d window probes\r\n", tcpstat.tcps_rcvwinprobe); - lprint(" %6d window update packets\r\n", tcpstat.tcps_rcvwinupd); - lprint(" %6d packets received after close\r\n", tcpstat.tcps_rcvafterclose); - lprint(" %6d discarded for bad checksums\r\n", tcpstat.tcps_rcvbadsum); - lprint(" %6d discarded for bad header offset fields\r\n", - tcpstat.tcps_rcvbadoff); - - lprint(" %6d connection requests\r\n", tcpstat.tcps_connattempt); - lprint(" %6d connection accepts\r\n", tcpstat.tcps_accepts); - lprint(" %6d connections established (including accepts)\r\n", tcpstat.tcps_connects); - lprint(" %6d connections closed (including %d drop)\r\n", - tcpstat.tcps_closed, tcpstat.tcps_drops); - lprint(" %6d embryonic connections dropped\r\n", tcpstat.tcps_conndrops); - lprint(" %6d segments we tried to get rtt (%d succeeded)\r\n", - tcpstat.tcps_segstimed, tcpstat.tcps_rttupdated); - lprint(" %6d retransmit timeouts\r\n", tcpstat.tcps_rexmttimeo); - lprint(" %6d connections dropped by rxmt timeout\r\n", - tcpstat.tcps_timeoutdrop); - lprint(" %6d persist timeouts\r\n", tcpstat.tcps_persisttimeo); - lprint(" %6d keepalive timeouts\r\n", tcpstat.tcps_keeptimeo); - lprint(" %6d keepalive probes sent\r\n", tcpstat.tcps_keepprobe); - lprint(" %6d connections dropped by keepalive\r\n", tcpstat.tcps_keepdrops); - lprint(" %6d correct ACK header predictions\r\n", tcpstat.tcps_predack); - lprint(" %6d correct data packet header predictions\n", tcpstat.tcps_preddat); - lprint(" %6d TCP cache misses\r\n", tcpstat.tcps_socachemiss); - - -/* lprint(" Packets received too short: %d\r\n", tcpstat.tcps_rcvshort); */ -/* lprint(" Segments dropped due to PAWS: %d\r\n", tcpstat.tcps_pawsdrop); */ - -} - -void -udpstats() -{ - lprint(" \r\n"); - - lprint("UDP stats:\r\n"); - lprint(" %6d datagrams received\r\n", udpstat.udps_ipackets); - lprint(" %6d with packets shorter than header\r\n", udpstat.udps_hdrops); - lprint(" %6d with bad checksums\r\n", udpstat.udps_badsum); - lprint(" %6d with data length larger than packet\r\n", udpstat.udps_badlen); - lprint(" %6d UDP socket cache misses\r\n", udpstat.udpps_pcbcachemiss); - lprint(" %6d datagrams sent\r\n", udpstat.udps_opackets); -} - -void -icmpstats() -{ - lprint(" \r\n"); - lprint("ICMP stats:\r\n"); - lprint(" %6d ICMP packets received\r\n", icmpstat.icps_received); - lprint(" %6d were too short\r\n", icmpstat.icps_tooshort); - lprint(" %6d with bad checksums\r\n", icmpstat.icps_checksum); - lprint(" %6d with type not supported\r\n", icmpstat.icps_notsupp); - lprint(" %6d with bad type feilds\r\n", icmpstat.icps_badtype); - lprint(" %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect); -} - -void -mbufstats() -{ - struct mbuf *m; - int i; - - lprint(" \r\n"); - - lprint("Mbuf stats:\r\n"); - - lprint(" %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max); - - i = 0; - for (m = m_freelist.m_next; m != &m_freelist; m = m->m_next) - i++; - lprint(" %6d mbufs on free list\r\n", i); - - i = 0; - for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) - i++; - lprint(" %6d mbufs on used list\r\n", i); - lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued); -} - -void -sockstats() -{ - char addr[INET_ADDRSTRLEN]; - char buff[256]; - int n; - struct socket *so; - - lprint(" \r\n"); - - lprint( - "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n"); - - for (so = tcb.so_next; so != &tcb; so = so->so_next) { - - n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE"); - while (n < 17) - buff[n++] = ' '; - buff[17] = 0; - lprint("%s %3d %15s %5d ", - buff, so->s, - inet_ntop(AF_INET, &so->so_laddr, addr, sizeof(addr)), - ntohs(so->so_lport)); - lprint("%15s %5d %5d %5d\r\n", - inet_ntop(AF_INET, &so->so_faddr, addr, sizeof(addr)), - ntohs(so->so_fport), - so->so_rcv.sb_cc, so->so_snd.sb_cc); - } - - for (so = udb.so_next; so != &udb; so = so->so_next) { - - n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000); - while (n < 17) - buff[n++] = ' '; - buff[17] = 0; - lprint("%s %3d %15s %5d ", - buff, so->s, - inet_ntop(AF_INET, &so->so_laddr, addr, sizeof(addr)), - ntohs(so->so_lport)); - lprint("%15s %5d %5d %5d\r\n", - inet_ntop(AF_INET, &so->so_faddr, addr, sizeof(addr)), - ntohs(so->so_fport), - so->so_rcv.sb_cc, so->so_snd.sb_cc); - } -} - -#if 0 -void -slirp_exit(exit_status) - int exit_status; -{ - struct ttys *ttyp; - - DEBUG_CALL("slirp_exit"); - DEBUG_ARG("exit_status = %d", exit_status); - - if (dostats) { - lprint_print = (int (*) _P((void *, const char *, va_list)))vfprintf; - if (!dfd) - debug_init("slirp_stats", 0xf); - lprint_arg = (char **)&dfd; - - ipstats(); - tcpstats(); - udpstats(); - icmpstats(); - mbufstats(); - sockstats(); - allttystats(); - vjstats(); - } - - for (ttyp = ttys; ttyp; ttyp = ttyp->next) - tty_detached(ttyp, 1); - - if (slirp_forked) { - /* Menendez time */ - if (kill(getppid(), SIGQUIT) < 0) - lprint("Couldn't kill parent process %ld!\n", - (long) getppid()); - } - - /* Restore the terminal if we gotta */ - if(slirp_tty_restore) - tcsetattr(0,TCSANOW, &slirp_tty_settings); /* NOW DAMMIT! */ - exit(exit_status); -} -#endif diff --git a/BasiliskII/src/slirp/debug.h b/BasiliskII/src/slirp/debug.h deleted file mode 100644 index c5d42195..00000000 --- a/BasiliskII/src/slirp/debug.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#define PRN_STDERR 1 -#define PRN_SPRINTF 2 - -extern FILE *dfd; -extern FILE *lfd; -extern int dostats; -extern int slirp_debug; - -#define DBG_CALL 0x1 -#define DBG_MISC 0x2 -#define DBG_ERROR 0x4 -#define DEBUG_DEFAULT DBG_CALL|DBG_MISC|DBG_ERROR - -#ifdef DEBUG -#define DEBUG_CALL(x) if (slirp_debug & DBG_CALL) { fprintf(dfd, "%s...\n", x); fflush(dfd); } -#define DEBUG_ARG(x, y) if (slirp_debug & DBG_CALL) { fputc(' ', dfd); fprintf(dfd, x, y); fputc('\n', dfd); fflush(dfd); } -#define DEBUG_ARGS(x) if (slirp_debug & DBG_CALL) { fprintf x ; fflush(dfd); } -#define DEBUG_MISC(x) if (slirp_debug & DBG_MISC) { fprintf x ; fflush(dfd); } -#define DEBUG_ERROR(x) if (slirp_debug & DBG_ERROR) {fprintf x ; fflush(dfd); } - - -#else - -#define DEBUG_CALL(x) -#define DEBUG_ARG(x, y) -#define DEBUG_ARGS(x) -#define DEBUG_MISC(x) -#define DEBUG_ERROR(x) - -#endif - -void debug_init(char *, int); -//void ttystats(struct ttys *); -void allttystats(void); -void ipstats(void); -void vjstats(void); -void tcpstats(void); -void udpstats(void); -void icmpstats(void); -void mbufstats(void); -void sockstats(void); -void slirp_exit(int); - diff --git a/BasiliskII/src/slirp/icmp_var.h b/BasiliskII/src/slirp/icmp_var.h deleted file mode 100644 index 9af222fb..00000000 --- a/BasiliskII/src/slirp/icmp_var.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)icmp_var.h 8.1 (Berkeley) 6/10/93 - * icmp_var.h,v 1.4 1995/02/16 00:27:40 wollman Exp - */ - -#ifndef _NETINET_ICMP_VAR_H_ -#define _NETINET_ICMP_VAR_H_ - -/* - * Variables related to this implementation - * of the internet control message protocol. - */ -struct icmpstat { -/* statistics related to input messages processed */ - u_long icps_received; /* #ICMP packets received */ - u_long icps_tooshort; /* packet < ICMP_MINLEN */ - u_long icps_checksum; /* bad checksum */ - u_long icps_notsupp; /* #ICMP packets not supported */ - u_long icps_badtype; /* #with bad type feild */ - u_long icps_reflect; /* number of responses */ -}; - -/* - * Names for ICMP sysctl objects - */ -#define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */ -#define ICMPCTL_STATS 2 /* statistics (read-only) */ -#define ICMPCTL_MAXID 3 - -#define ICMPCTL_NAMES { \ - { 0, 0 }, \ - { "maskrepl", CTLTYPE_INT }, \ - { "stats", CTLTYPE_STRUCT }, \ -} - -extern struct icmpstat icmpstat; - -#endif diff --git a/BasiliskII/src/slirp/if.c b/BasiliskII/src/slirp/if.c deleted file mode 100644 index 9185dcf6..00000000 --- a/BasiliskII/src/slirp/if.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include - -size_t if_mtu, if_mru; -int if_comp; -int if_maxlinkhdr; -int if_queued = 0; /* Number of packets queued so far */ -int if_thresh = 10; /* Number of packets queued before we start sending - * (to prevent allocing too many mbufs) */ - -struct mbuf if_fastq; /* fast queue (for interactive data) */ -struct mbuf if_batchq; /* queue for non-interactive data */ -struct mbuf *next_m; /* Pointer to next mbuf to output */ - -#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) - -void -ifs_insque(ifm, ifmhead) - struct mbuf *ifm, *ifmhead; -{ - ifm->ifs_next = ifmhead->ifs_next; - ifmhead->ifs_next = ifm; - ifm->ifs_prev = ifmhead; - ifm->ifs_next->ifs_prev = ifm; -} - -void -ifs_remque(ifm) - struct mbuf *ifm; -{ - ifm->ifs_prev->ifs_next = ifm->ifs_next; - ifm->ifs_next->ifs_prev = ifm->ifs_prev; -} - -void -if_init() -{ -#if 0 - /* - * Set if_maxlinkhdr to 48 because it's 40 bytes for TCP/IP, - * and 8 bytes for PPP, but need to have it on an 8byte boundary - */ -#ifdef USE_PPP - if_maxlinkhdr = 48; -#else - if_maxlinkhdr = 40; -#endif -#else - /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */ - if_maxlinkhdr = 2 + 14 + 40; -#endif - if_mtu = 1500; - if_mru = 1500; - if_comp = IF_AUTOCOMP; - if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq; - if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq; - // sl_compress_init(&comp_s); - next_m = &if_batchq; -} - -#if 0 -/* - * This shouldn't be needed since the modem is blocking and - * we don't expect any signals, but what the hell.. - */ -inline int -writen(fd, bptr, n) - int fd; - char *bptr; - int n; -{ - int ret; - int total; - - /* This should succeed most of the time */ - ret = send(fd, bptr, n,0); - if (ret == n || ret <= 0) - return ret; - - /* Didn't write everything, go into the loop */ - total = ret; - while (n > total) { - ret = send(fd, bptr+total, n-total,0); - if (ret <= 0) - return ret; - total += ret; - } - return total; -} - -/* - * if_input - read() the tty, do "top level" processing (ie: check for any escapes), - * and pass onto (*ttyp->if_input) - * - * XXXXX Any zeros arriving by themselves are NOT placed into the arriving packet. - */ -#define INBUFF_SIZE 2048 /* XXX */ -void -if_input(ttyp) - struct ttys *ttyp; -{ - u_char if_inbuff[INBUFF_SIZE]; - int if_n; - - DEBUG_CALL("if_input"); - DEBUG_ARG("ttyp = %lx", (long)ttyp); - - if_n = recv(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE,0); - - DEBUG_MISC((dfd, " read %d bytes\n", if_n)); - - if (if_n <= 0) { - int error = WSAGetLastError(); - if (if_n == 0 || (error != WSAEINTR && error != EAGAIN)) { - if (ttyp->up) - link_up--; - tty_detached(ttyp, 0); - } - return; - } - if (if_n == 1) { - if (*if_inbuff == '0') { - ttyp->ones = 0; - if (++ttyp->zeros >= 5) - slirp_exit(0); - return; - } - if (*if_inbuff == '1') { - ttyp->zeros = 0; - if (++ttyp->ones >= 5) - tty_detached(ttyp, 0); - return; - } - } - ttyp->ones = ttyp->zeros = 0; - - (*ttyp->if_input)(ttyp, if_inbuff, if_n); -} -#endif - -/* - * if_output: Queue packet into an output queue. - * There are 2 output queue's, if_fastq and if_batchq. - * Each output queue is a doubly linked list of double linked lists - * of mbufs, each list belonging to one "session" (socket). This - * way, we can output packets fairly by sending one packet from each - * session, instead of all the packets from one session, then all packets - * from the next session, etc. Packets on the if_fastq get absolute - * priority, but if one session hogs the link, it gets "downgraded" - * to the batchq until it runs out of packets, then it'll return - * to the fastq (eg. if the user does an ls -alR in a telnet session, - * it'll temporarily get downgraded to the batchq) - */ -void -if_output(so, ifm) - struct socket *so; - struct mbuf *ifm; -{ - struct mbuf *ifq; - int on_fastq = 1; - - DEBUG_CALL("if_output"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("ifm = %lx", (long)ifm); - - /* - * First remove the mbuf from m_usedlist, - * since we're gonna use m_next and m_prev ourselves - * XXX Shouldn't need this, gotta change dtom() etc. - */ - if (ifm->m_flags & M_USEDLIST) { - remque(ifm); - ifm->m_flags &= ~M_USEDLIST; - } - - /* - * See if there's already a batchq list for this session. - * This can include an interactive session, which should go on fastq, - * but gets too greedy... hence it'll be downgraded from fastq to batchq. - * We mustn't put this packet back on the fastq (or we'll send it out of order) - * XXX add cache here? - */ - for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) { - if (so == ifq->ifq_so) { - /* A match! */ - ifm->ifq_so = so; - ifs_insque(ifm, ifq->ifs_prev); - goto diddit; - } - } - - /* No match, check which queue to put it on */ - if (so && (so->so_iptos & IPTOS_LOWDELAY)) { - ifq = if_fastq.ifq_prev; - on_fastq = 1; - /* - * Check if this packet is a part of the last - * packet's session - */ - if (ifq->ifq_so == so) { - ifm->ifq_so = so; - ifs_insque(ifm, ifq->ifs_prev); - goto diddit; - } - } else - ifq = if_batchq.ifq_prev; - - /* Create a new doubly linked list for this session */ - ifm->ifq_so = so; - ifs_init(ifm); - insque(ifm, ifq); - -diddit: - ++if_queued; - - if (so) { - /* Update *_queued */ - so->so_queued++; - so->so_nqueued++; - /* - * Check if the interactive session should be downgraded to - * the batchq. A session is downgraded if it has queued 6 - * packets without pausing, and at least 3 of those packets - * have been sent over the link - * (XXX These are arbitrary numbers, probably not optimal..) - */ - if (on_fastq && ((so->so_nqueued >= 6) && - (so->so_nqueued - so->so_queued) >= 3)) { - - /* Remove from current queue... */ - remque(ifm->ifs_next); - - /* ...And insert in the new. That'll teach ya! */ - insque(ifm->ifs_next, &if_batchq); - } - } - -#ifndef FULL_BOLT - /* - * This prevents us from malloc()ing too many mbufs - */ - if (link_up) { - /* if_start will check towrite */ - if_start(); - } -#endif -} - -/* - * Send a packet - * We choose a packet based on it's position in the output queues; - * If there are packets on the fastq, they are sent FIFO, before - * everything else. Otherwise we choose the first packet from the - * batchq and send it. the next packet chosen will be from the session - * after this one, then the session after that one, and so on.. So, - * for example, if there are 3 ftp session's fighting for bandwidth, - * one packet will be sent from the first session, then one packet - * from the second session, then one packet from the third, then back - * to the first, etc. etc. - */ -void -if_start(void) -{ - struct mbuf *ifm, *ifqt; - - DEBUG_CALL("if_start"); - - if (if_queued == 0) - return; /* Nothing to do */ - - again: - /* check if we can really output */ - if (!slirp_can_output()) - return; - - /* - * See which queue to get next packet from - * If there's something in the fastq, select it immediately - */ - if (if_fastq.ifq_next != &if_fastq) { - ifm = if_fastq.ifq_next; - } else { - /* Nothing on fastq, see if next_m is valid */ - if (next_m != &if_batchq) - ifm = next_m; - else - ifm = if_batchq.ifq_next; - - /* Set which packet to send on next iteration */ - next_m = ifm->ifq_next; - } - /* Remove it from the queue */ - ifqt = ifm->ifq_prev; - remque(ifm); - --if_queued; - - /* If there are more packets for this session, re-queue them */ - if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) { - insque(ifm->ifs_next, ifqt); - ifs_remque(ifm); - } - - /* Update so_queued */ - if (ifm->ifq_so) { - if (--ifm->ifq_so->so_queued == 0) - /* If there's no more queued, reset nqueued */ - ifm->ifq_so->so_nqueued = 0; - } - - /* Encapsulate the packet for sending */ - if_encap((uint8_t*)ifm->m_data, ifm->m_len); - - m_free(ifm); - - if (if_queued) - goto again; -} diff --git a/BasiliskII/src/slirp/if.h b/BasiliskII/src/slirp/if.h deleted file mode 100644 index a2564ab1..00000000 --- a/BasiliskII/src/slirp/if.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#ifndef _IF_H_ -#define _IF_H_ - -#define IF_COMPRESS 0x01 /* We want compression */ -#define IF_NOCOMPRESS 0x02 /* Do not do compression */ -#define IF_AUTOCOMP 0x04 /* Autodetect (default) */ -#define IF_NOCIDCOMP 0x08 /* CID compression */ - -/* Needed for FreeBSD */ -#undef if_mtu -extern size_t if_mtu; -extern size_t if_mru; /* MTU and MRU */ -extern int if_comp; /* Flags for compression */ -extern int if_maxlinkhdr; -extern int if_queued; /* Number of packets queued so far */ -extern int if_thresh; /* Number of packets queued before we start sending - * (to prevent allocing too many mbufs) */ - -extern struct mbuf if_fastq; /* fast queue (for interactive data) */ -extern struct mbuf if_batchq; /* queue for non-interactive data */ -extern struct mbuf *next_m; - -#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) - -/* Interface statistics */ -struct slirp_ifstats { - u_int out_pkts; /* Output packets */ - u_int out_bytes; /* Output bytes */ - u_int out_errpkts; /* Output Error Packets */ - u_int out_errbytes; /* Output Error Bytes */ - u_int in_pkts; /* Input packets */ - u_int in_bytes; /* Input bytes */ - u_int in_errpkts; /* Input Error Packets */ - u_int in_errbytes; /* Input Error Bytes */ - - u_int bytes_saved; /* Number of bytes that compression "saved" */ - /* ie: number of bytes that didn't need to be sent over the link - * because of compression */ - - u_int in_mbad; /* Bad incoming packets */ -}; - -#endif diff --git a/BasiliskII/src/slirp/ip.h b/BasiliskII/src/slirp/ip.h deleted file mode 100644 index e0c7de96..00000000 --- a/BasiliskII/src/slirp/ip.h +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)ip.h 8.1 (Berkeley) 6/10/93 - * ip.h,v 1.3 1994/08/21 05:27:30 paul Exp - */ - -#ifndef _IP_H_ -#define _IP_H_ - -#ifdef WORDS_BIGENDIAN -# ifndef NTOHL -# define NTOHL(d) -# endif -# ifndef NTOHS -# define NTOHS(d) -# endif -# ifndef HTONL -# define HTONL(d) -# endif -# ifndef HTONS -# define HTONS(d) -# endif -#else -# ifndef NTOHL -# define NTOHL(d) ((d) = ntohl((d))) -# endif -# ifndef NTOHS -# define NTOHS(d) ((d) = ntohs((u_int16_t)(d))) -# endif -# ifndef HTONL -# define HTONL(d) ((d) = htonl((d))) -# endif -# ifndef HTONS -# define HTONS(d) ((d) = htons((u_int16_t)(d))) -# endif -#endif - -typedef u_int32_t n_long; /* long as received from the net */ - -/* - * Definitions for internet protocol version 4. - * Per RFC 791, September 1981. - */ -#define IPVERSION 4 - -/* - * Structure of an internet header, naked of options. - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct ip { -#ifdef WORDS_BIGENDIAN - u_char ip_v:4, /* version */ - ip_hl:4; /* header length */ -#else - u_char ip_hl:4, /* header length */ - ip_v:4; /* version */ -#endif - u_int8_t ip_tos; /* type of service */ - u_int16_t ip_len; /* total length */ - u_int16_t ip_id; /* identification */ - u_int16_t ip_off; /* fragment offset field */ -#define IP_DF 0x4000 /* don't fragment flag */ -#define IP_MF 0x2000 /* more fragments flag */ -#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ - u_int8_t ip_ttl; /* time to live */ - u_int8_t ip_p; /* protocol */ - u_int16_t ip_sum; /* checksum */ - struct in_addr ip_src,ip_dst; /* source and dest address */ -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) -#endif - -#define IP_MAXPACKET 65535 /* maximum packet size */ - -/* - * Definitions for IP type of service (ip_tos) - */ -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 - -/* - * Definitions for options. - */ -#define IPOPT_COPIED(o) ((o)&0x80) -#define IPOPT_CLASS(o) ((o)&0x60) -#define IPOPT_NUMBER(o) ((o)&0x1f) - -#define IPOPT_CONTROL 0x00 -#define IPOPT_RESERVED1 0x20 -#define IPOPT_DEBMEAS 0x40 -#define IPOPT_RESERVED2 0x60 - -#define IPOPT_EOL 0 /* end of option list */ -#define IPOPT_NOP 1 /* no operation */ - -#define IPOPT_RR 7 /* record packet route */ -#define IPOPT_TS 68 /* timestamp */ -#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ -#define IPOPT_LSRR 131 /* loose source route */ -#define IPOPT_SATID 136 /* satnet id */ -#define IPOPT_SSRR 137 /* strict source route */ - -/* - * Offsets to fields in options other than EOL and NOP. - */ -#define IPOPT_OPTVAL 0 /* option ID */ -#define IPOPT_OLEN 1 /* option length */ -#define IPOPT_OFFSET 2 /* offset within option */ -#define IPOPT_MINOFF 4 /* min value of above */ - -/* - * Time stamp option structure. - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct ip_timestamp { - u_int8_t ipt_code; /* IPOPT_TS */ - u_int8_t ipt_len; /* size of structure (variable) */ - u_int8_t ipt_ptr; /* index of current entry */ -#ifdef WORDS_BIGENDIAN - u_char ipt_oflw:4, /* overflow counter */ - ipt_flg:4; /* flags, see below */ -#else - u_char ipt_flg:4, /* flags, see below */ - ipt_oflw:4; /* overflow counter */ -#endif - union ipt_timestamp { - n_long ipt_time[1]; - struct ipt_ta { - struct in_addr ipt_addr; - n_long ipt_time; - } ipt_ta[1]; - } ipt_timestamp; -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) -#endif - -/* flag bits for ipt_flg */ -#define IPOPT_TS_TSONLY 0 /* timestamps only */ -#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ -#define IPOPT_TS_PRESPEC 3 /* specified modules only */ - -/* bits for security (not byte swapped) */ -#define IPOPT_SECUR_UNCLASS 0x0000 -#define IPOPT_SECUR_CONFID 0xf135 -#define IPOPT_SECUR_EFTO 0x789a -#define IPOPT_SECUR_MMMM 0xbc4d -#define IPOPT_SECUR_RESTR 0xaf13 -#define IPOPT_SECUR_SECRET 0xd788 -#define IPOPT_SECUR_TOPSECRET 0x6bc5 - -/* - * Internet implementation parameters. - */ -#define MAXTTL 255 /* maximum time to live (seconds) */ -#define IPDEFTTL 64 /* default ttl, from RFC 1340 */ -#define IPFRAGTTL 60 /* time to live for frags, slowhz */ -#define IPTTLDEC 1 /* subtracted when forwarding */ - -#define IP_MSS 576 /* default maximum segment size */ - -#ifdef HAVE_SYS_TYPES32_H /* Overcome some Solaris 2.x junk */ -#include -#else -#if SIZEOF_CHAR_P == 4 -typedef caddr_t caddr32_t; -#else -typedef u_int32_t caddr32_t; -#endif -#endif - -#if SIZEOF_CHAR_P == 4 -typedef struct ipq *ipqp_32; -typedef struct ipasfrag *ipasfragp_32; -#else -typedef caddr32_t ipqp_32; -typedef caddr32_t ipasfragp_32; -#endif - -/* - * Overlay for ip header used by other protocols (tcp, udp). - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct ipovly { - caddr32_t ih_next, ih_prev; /* for protocol sequence q's */ - u_int8_t ih_x1; /* (unused) */ - u_int8_t ih_pr; /* protocol */ - u_int16_t ih_len; /* protocol length */ - struct in_addr ih_src; /* source internet address */ - struct in_addr ih_dst; /* destination internet address */ -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) -#endif - -/* - * Ip reassembly queue structure. Each fragment - * being reassembled is attached to one of these structures. - * They are timed out after ipq_ttl drops to 0, and may also - * be reclaimed if memory becomes tight. - * size 28 bytes - */ -struct ipq { - ipqp_32 next,prev; /* to other reass headers */ - u_int8_t ipq_ttl; /* time for reass q to live */ - u_int8_t ipq_p; /* protocol of this fragment */ - u_int16_t ipq_id; /* sequence id for reassembly */ - ipasfragp_32 ipq_next,ipq_prev; - /* to ip headers of fragments */ - struct in_addr ipq_src,ipq_dst; -}; - -/* - * Ip header, when holding a fragment. - * - * Note: ipf_next must be at same offset as ipq_next above - */ -struct ipasfrag { -#ifdef WORDS_BIGENDIAN - u_char ip_v:4, - ip_hl:4; -#else - u_char ip_hl:4, - ip_v:4; -#endif - /* BUG : u_int changed to u_int8_t. - * sizeof(u_int)==4 on linux 2.0 - */ - u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit - * to avoid destroying tos (PPPDTRuu); - * copied from (ip_off&IP_MF) */ - u_int16_t ip_len; - u_int16_t ip_id; - u_int16_t ip_off; - u_int8_t ip_ttl; - u_int8_t ip_p; - u_int16_t ip_sum; - ipasfragp_32 ipf_next; /* next fragment */ - ipasfragp_32 ipf_prev; /* previous fragment */ -}; - -/* - * Structure stored in mbuf in inpcb.ip_options - * and passed to ip_output when ip options are in use. - * The actual length of the options (including ipopt_dst) - * is in m_len. - */ -#define MAX_IPOPTLEN 40 - -struct ipoption { - struct in_addr ipopt_dst; /* first-hop dst if source routed */ - int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */ -}; - -/* - * Structure attached to inpcb.ip_moptions and - * passed to ip_output when IP multicast options are in use. - */ - -struct ipstat { - u_long ips_total; /* total packets received */ - u_long ips_badsum; /* checksum bad */ - u_long ips_tooshort; /* packet too short */ - u_long ips_toosmall; /* not enough data */ - u_long ips_badhlen; /* ip header length < data size */ - u_long ips_badlen; /* ip length < ip header length */ - u_long ips_fragments; /* fragments received */ - u_long ips_fragdropped; /* frags dropped (dups, out of space) */ - u_long ips_fragtimeout; /* fragments timed out */ - u_long ips_forward; /* packets forwarded */ - u_long ips_cantforward; /* packets rcvd for unreachable dest */ - u_long ips_redirectsent; /* packets forwarded on same net */ - u_long ips_noproto; /* unknown or unsupported protocol */ - u_long ips_delivered; /* datagrams delivered to upper level*/ - u_long ips_localout; /* total ip packets generated here */ - u_long ips_odropped; /* lost packets due to nobufs, etc. */ - u_long ips_reassembled; /* total packets reassembled ok */ - u_long ips_fragmented; /* datagrams successfully fragmented */ - u_long ips_ofragments; /* output fragments created */ - u_long ips_cantfrag; /* don't fragment flag was set, etc. */ - u_long ips_badoptions; /* error in option processing */ - u_long ips_noroute; /* packets discarded due to no route */ - u_long ips_badvers; /* ip version != 4 */ - u_long ips_rawout; /* total raw ip packets generated */ - u_long ips_unaligned; /* times the ip packet was not aligned */ -}; - -extern struct ipstat ipstat; -extern struct ipq ipq; /* ip reass. queue */ -extern u_int16_t ip_id; /* ip packet ctr, for ids */ -extern int ip_defttl; /* default IP ttl */ - -#endif diff --git a/BasiliskII/src/slirp/ip_icmp.c b/BasiliskII/src/slirp/ip_icmp.c deleted file mode 100644 index 75a4614a..00000000 --- a/BasiliskII/src/slirp/ip_icmp.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 - * ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp - */ - -#include "slirp.h" -#include "ip_icmp.h" - -struct icmpstat icmpstat; - -/* The message sent when emulating PING */ -/* Be nice and tell them it's just a psuedo-ping packet */ -char icmp_ping_msg[] = "This is a psuedo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST packets.\n"; - -/* list of actions for icmp_error() on RX of an icmp message */ -static int icmp_flush[19] = { -/* ECHO REPLY (0) */ 0, - 1, - 1, -/* DEST UNREACH (3) */ 1, -/* SOURCE QUENCH (4)*/ 1, -/* REDIRECT (5) */ 1, - 1, - 1, -/* ECHO (8) */ 0, -/* ROUTERADVERT (9) */ 1, -/* ROUTERSOLICIT (10) */ 1, -/* TIME EXCEEDED (11) */ 1, -/* PARAMETER PROBLEM (12) */ 1, -/* TIMESTAMP (13) */ 0, -/* TIMESTAMP REPLY (14) */ 0, -/* INFO (15) */ 0, -/* INFO REPLY (16) */ 0, -/* ADDR MASK (17) */ 0, -/* ADDR MASK REPLY (18) */ 0 -}; - -/* - * Process a received ICMP message. - */ -void -icmp_input(m, hlen) - struct mbuf *m; - int hlen; -{ - register struct icmp *icp; - register struct ip *ip=mtod(m, struct ip *); - int icmplen=ip->ip_len; - /* int code; */ - - DEBUG_CALL("icmp_input"); - DEBUG_ARG("m = %lx", (long )m); - DEBUG_ARG("m_len = %d", m->m_len); - - icmpstat.icps_received++; - - /* - * Locate icmp structure in mbuf, and check - * that its not corrupted and of at least minimum length. - */ - if (icmplen < ICMP_MINLEN) { /* min 8 bytes payload */ - icmpstat.icps_tooshort++; - freeit: - m_freem(m); - goto end_error; - } - - m->m_len -= hlen; - m->m_data += hlen; - icp = mtod(m, struct icmp *); - if (cksum(m, icmplen)) { - icmpstat.icps_checksum++; - goto freeit; - } - m->m_len += hlen; - m->m_data -= hlen; - - /* icmpstat.icps_inhist[icp->icmp_type]++; */ - /* code = icp->icmp_code; */ - - DEBUG_ARG("icmp_type = %d", icp->icmp_type); - switch (icp->icmp_type) { - case ICMP_ECHO: - icp->icmp_type = ICMP_ECHOREPLY; - ip->ip_len += hlen; /* since ip_input subtracts this */ - if (ip->ip_dst.s_addr == alias_addr.s_addr) { - icmp_reflect(m); - } else { - struct socket *so; - struct sockaddr_in addr; - if ((so = socreate()) == NULL) goto freeit; - if(udp_attach(so) == -1) { - DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n", - errno,strerror(errno))); - sofree(so); - m_free(m); - goto end_error; - } - so->so_m = m; - so->so_faddr = ip->ip_dst; - so->so_fport = htons(7); - so->so_laddr = ip->ip_src; - so->so_lport = htons(9); - so->so_iptos = ip->ip_tos; - so->so_type = IPPROTO_ICMP; - so->so_state = SS_ISFCONNECTED; - - /* Send the packet */ - addr.sin_family = AF_INET; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { - /* It's an alias */ - switch(ntohl(so->so_faddr.s_addr) & 0xff) { - case CTL_DNS: - addr.sin_addr = dns_addr; - break; - case CTL_ALIAS: - default: - addr.sin_addr = loopback_addr; - break; - } - } else { - addr.sin_addr = so->so_faddr; - } - addr.sin_port = so->so_fport; - if(sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0, - (struct sockaddr *)&addr, sizeof(addr)) == -1) { - DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n", - errno,strerror(errno))); - icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); - udp_detach(so); - } - } /* if ip->ip_dst.s_addr == alias_addr.s_addr */ - break; - case ICMP_UNREACH: - /* XXX? report error? close socket? */ - case ICMP_TIMXCEED: - case ICMP_PARAMPROB: - case ICMP_SOURCEQUENCH: - case ICMP_TSTAMP: - case ICMP_MASKREQ: - case ICMP_REDIRECT: - icmpstat.icps_notsupp++; - m_freem(m); - break; - - default: - icmpstat.icps_badtype++; - m_freem(m); - } /* swith */ - -end_error: - /* m is m_free()'d xor put in a socket xor or given to ip_send */ - return; -} - - -/* - * Send an ICMP message in response to a situation - * - * RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header. MAY send more (we do). - * MUST NOT change this header information. - * MUST NOT reply to a multicast/broadcast IP address. - * MUST NOT reply to a multicast/broadcast MAC address. - * MUST reply to only the first fragment. - */ -/* - * Send ICMP_UNREACH back to the source regarding msrc. - * mbuf *msrc is used as a template, but is NOT m_free()'d. - * It is reported as the bad ip packet. The header should - * be fully correct and in host byte order. - * ICMP fragmentation is illegal. All machines must accept 576 bytes in one - * packet. The maximum payload is 576-20(ip hdr)-8(icmp hdr)=548 - */ - -#define ICMP_MAXDATALEN (IP_MSS-28) -void -icmp_error(msrc, type, code, minsize, message) - struct mbuf *msrc; - u_char type; - u_char code; - int minsize; - char *message; -{ - unsigned hlen, shlen, s_ip_len; - register struct ip *ip; - register struct icmp *icp; - register struct mbuf *m; - - DEBUG_CALL("icmp_error"); - DEBUG_ARG("msrc = %lx", (long )msrc); - DEBUG_ARG("msrc_len = %d", msrc->m_len); - - if(type!=ICMP_UNREACH && type!=ICMP_TIMXCEED) goto end_error; - - /* check msrc */ - if(!msrc) goto end_error; - ip = mtod(msrc, struct ip *); -#if DEBUG - { char bufa[INET_ADDRSTRLEN], bufb[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &ip->ip_src, bufa, sizeof(bufa)); - inet_ntop(AF_INET, &ip->ip_dst, bufb, sizeof(bufb)); - DEBUG_MISC((dfd, " %.16s to %.16s\n", bufa, bufb)); - } -#endif - if(ip->ip_off & IP_OFFMASK) goto end_error; /* Only reply to fragment 0 */ - - shlen=ip->ip_hl << 2; - s_ip_len=ip->ip_len; - if(ip->ip_p == IPPROTO_ICMP) { - icp = (struct icmp *)((char *)ip + shlen); - /* - * Assume any unknown ICMP type is an error. This isn't - * specified by the RFC, but think about it.. - */ - if(icp->icmp_type>18 || icmp_flush[icp->icmp_type]) goto end_error; - } - - /* make a copy */ - if(!(m=m_get())) goto end_error; /* get mbuf */ - { u_int new_m_size; - new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN; - if(new_m_size>m->m_size) m_inc(m, new_m_size); - } - memcpy(m->m_data, msrc->m_data, msrc->m_len); - m->m_len = msrc->m_len; /* copy msrc to m */ - - /* make the header of the reply packet */ - ip = mtod(m, struct ip *); - hlen= sizeof(struct ip ); /* no options in reply */ - - /* fill in icmp */ - m->m_data += hlen; - m->m_len -= hlen; - - icp = mtod(m, struct icmp *); - - if(minsize) s_ip_len=shlen+ICMP_MINLEN; /* return header+8b only */ - else if(s_ip_len>ICMP_MAXDATALEN) /* maximum size */ - s_ip_len=ICMP_MAXDATALEN; - - m->m_len=ICMP_MINLEN+s_ip_len; /* 8 bytes ICMP header */ - - /* min. size = 8+sizeof(struct ip)+8 */ - - icp->icmp_type = type; - icp->icmp_code = code; - icp->icmp_id = 0; - icp->icmp_seq = 0; - - memcpy(&icp->icmp_ip, msrc->m_data, s_ip_len); /* report the ip packet */ - HTONS(icp->icmp_ip.ip_len); - HTONS(icp->icmp_ip.ip_id); - HTONS(icp->icmp_ip.ip_off); - -#if DEBUG - if(message) { /* DEBUG : append message to ICMP packet */ - int message_len; - char *cpnt; - message_len=strlen(message); - if(message_len>ICMP_MAXDATALEN) message_len=ICMP_MAXDATALEN; - cpnt=(char *)m->m_data+m->m_len; - memcpy(cpnt, message, message_len); - m->m_len+=message_len; - } -#endif - - icp->icmp_cksum = 0; - icp->icmp_cksum = cksum(m, m->m_len); - - m->m_data -= hlen; - m->m_len += hlen; - - /* fill in ip */ - ip->ip_hl = hlen >> 2; - ip->ip_len = (u_int16_t)m->m_len; - - ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */ - - ip->ip_ttl = MAXTTL; - ip->ip_p = IPPROTO_ICMP; - ip->ip_dst = ip->ip_src; /* ip adresses */ - ip->ip_src = alias_addr; - - (void ) ip_output((struct socket *)NULL, m); - - icmpstat.icps_reflect++; - -end_error: - return; -} -#undef ICMP_MAXDATALEN - -/* - * Reflect the ip packet back to the source - */ -void -icmp_reflect(m) - struct mbuf *m; -{ - register struct ip *ip = mtod(m, struct ip *); - int hlen = ip->ip_hl << 2; - int optlen = hlen - sizeof(struct ip ); - register struct icmp *icp; - - /* - * Send an icmp packet back to the ip level, - * after supplying a checksum. - */ - m->m_data += hlen; - m->m_len -= hlen; - icp = mtod(m, struct icmp *); - - icp->icmp_cksum = 0; - icp->icmp_cksum = cksum(m, ip->ip_len - hlen); - - m->m_data -= hlen; - m->m_len += hlen; - - /* fill in ip */ - if (optlen > 0) { - /* - * Strip out original options by copying rest of first - * mbuf's data back, and adjust the IP length. - */ - memmove((caddr_t)(ip + 1), (caddr_t)ip + hlen, - (unsigned )(m->m_len - hlen)); - hlen -= optlen; - ip->ip_hl = hlen >> 2; - ip->ip_len -= optlen; - m->m_len -= optlen; - } - - ip->ip_ttl = MAXTTL; - { /* swap */ - struct in_addr icmp_dst; - icmp_dst = ip->ip_dst; - ip->ip_dst = ip->ip_src; - ip->ip_src = icmp_dst; - } - - (void ) ip_output((struct socket *)NULL, m); - - icmpstat.icps_reflect++; -} diff --git a/BasiliskII/src/slirp/ip_icmp.h b/BasiliskII/src/slirp/ip_icmp.h deleted file mode 100644 index 683dc87f..00000000 --- a/BasiliskII/src/slirp/ip_icmp.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93 - * ip_icmp.h,v 1.4 1995/05/30 08:09:43 rgrimes Exp - */ - -#ifndef _NETINET_IP_ICMP_H_ -#define _NETINET_IP_ICMP_H_ - -/* - * Interface Control Message Protocol Definitions. - * Per RFC 792, September 1981. - */ - -typedef u_int32_t n_time; - -/* - * Structure of an icmp header. - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct icmp { - u_char icmp_type; /* type of message, see below */ - u_char icmp_code; /* type sub code */ - u_short icmp_cksum; /* ones complement cksum of struct */ - union { - u_char ih_pptr; /* ICMP_PARAMPROB */ - struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ - struct ih_idseq { - u_short icd_id; - u_short icd_seq; - } ih_idseq; - int ih_void; - - /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ - struct ih_pmtu { - u_short ipm_void; - u_short ipm_nextmtu; - } ih_pmtu; - } icmp_hun; -#define icmp_pptr icmp_hun.ih_pptr -#define icmp_gwaddr icmp_hun.ih_gwaddr -#define icmp_id icmp_hun.ih_idseq.icd_id -#define icmp_seq icmp_hun.ih_idseq.icd_seq -#define icmp_void icmp_hun.ih_void -#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void -#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu - union { - struct id_ts { - n_time its_otime; - n_time its_rtime; - n_time its_ttime; - } id_ts; - struct id_ip { - struct ip idi_ip; - /* options and then 64 bits of data */ - } id_ip; - uint32_t id_mask; - char id_data[1]; - } icmp_dun; -#define icmp_otime icmp_dun.id_ts.its_otime -#define icmp_rtime icmp_dun.id_ts.its_rtime -#define icmp_ttime icmp_dun.id_ts.its_ttime -#define icmp_ip icmp_dun.id_ip.idi_ip -#define icmp_mask icmp_dun.id_mask -#define icmp_data icmp_dun.id_data -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) -#endif - -/* - * Lower bounds on packet lengths for various types. - * For the error advice packets must first insure that the - * packet is large enought to contain the returned ip header. - * Only then can we do the check to see if 64 bits of packet - * data have been returned, since we need to check the returned - * ip header length. - */ -#define ICMP_MINLEN 8 /* abs minimum */ -#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */ -#define ICMP_MASKLEN 12 /* address mask */ -#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ -#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8) - /* N.B.: must separately check that ip_hl >= 5 */ - -/* - * Definition of type and code field values. - */ -#define ICMP_ECHOREPLY 0 /* echo reply */ -#define ICMP_UNREACH 3 /* dest unreachable, codes: */ -#define ICMP_UNREACH_NET 0 /* bad net */ -#define ICMP_UNREACH_HOST 1 /* bad host */ -#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ -#define ICMP_UNREACH_PORT 3 /* bad port */ -#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ -#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ -#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ -#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ -#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ -#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ -#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ -#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ -#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ -#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ -#define ICMP_REDIRECT 5 /* shorter route, codes: */ -#define ICMP_REDIRECT_NET 0 /* for network */ -#define ICMP_REDIRECT_HOST 1 /* for host */ -#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ -#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ -#define ICMP_ECHO 8 /* echo service */ -#define ICMP_ROUTERADVERT 9 /* router advertisement */ -#define ICMP_ROUTERSOLICIT 10 /* router solicitation */ -#define ICMP_TIMXCEED 11 /* time exceeded, code: */ -#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ -#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ -#define ICMP_PARAMPROB 12 /* ip header bad */ -#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ -#define ICMP_TSTAMP 13 /* timestamp request */ -#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ -#define ICMP_IREQ 15 /* information request */ -#define ICMP_IREQREPLY 16 /* information reply */ -#define ICMP_MASKREQ 17 /* address mask request */ -#define ICMP_MASKREPLY 18 /* address mask reply */ - -#define ICMP_MAXTYPE 18 - -#define ICMP_INFOTYPE(type) \ - ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ - (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ - (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ - (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ - (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) - -void icmp_input(struct mbuf *, int); -void icmp_error(struct mbuf *, u_char, u_char, int, char *); -void icmp_reflect(struct mbuf *); - -#endif diff --git a/BasiliskII/src/slirp/ip_input.c b/BasiliskII/src/slirp/ip_input.c deleted file mode 100644 index d9426997..00000000 --- a/BasiliskII/src/slirp/ip_input.c +++ /dev/null @@ -1,693 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 - * ip_input.c,v 1.11 1994/11/16 10:17:08 jkh Exp - */ - -/* - * Changes and additions relating to SLiRP are - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include -#include "ip_icmp.h" - -int ip_defttl; -struct ipstat ipstat; -struct ipq ipq; - -/* - * IP initialization: fill in IP protocol switch table. - * All protocols not implemented in kernel go to raw IP protocol handler. - */ -void -ip_init() -{ - ipq.next = ipq.prev = (ipqp_32)&ipq; - ip_id = tt.tv_sec & 0xffff; - udp_init(); - tcp_init(); - ip_defttl = IPDEFTTL; -} - -/* - * Ip input routine. Checksum and byte swap header. If fragmented - * try to reassemble. Process options. Pass to next level. - */ -void -ip_input(m) - struct mbuf *m; -{ - register struct ip *ip; - u_int hlen; - - DEBUG_CALL("ip_input"); - DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("m_len = %d", m->m_len); - - ipstat.ips_total++; - - if (m->m_len < sizeof (struct ip)) { - ipstat.ips_toosmall++; - return; - } - - ip = mtod(m, struct ip *); - - if (ip->ip_v != IPVERSION) { - ipstat.ips_badvers++; - goto bad; - } - - hlen = ip->ip_hl << 2; - if (hlenm->m_len) {/* min header length */ - ipstat.ips_badhlen++; /* or packet too short */ - goto bad; - } - - /* keep ip header intact for ICMP reply - * ip->ip_sum = cksum(m, hlen); - * if (ip->ip_sum) { - */ - if(cksum(m,hlen)) { - ipstat.ips_badsum++; - goto bad; - } - - /* - * Convert fields to host representation. - */ - NTOHS(ip->ip_len); - if (ip->ip_len < hlen) { - ipstat.ips_badlen++; - goto bad; - } - NTOHS(ip->ip_id); - NTOHS(ip->ip_off); - - /* - * Check that the amount of data in the buffers - * is as at least much as the IP header would have us expect. - * Trim mbufs if longer than we expect. - * Drop packet if shorter than we expect. - */ - if (m->m_len < ip->ip_len) { - ipstat.ips_tooshort++; - goto bad; - } - /* Should drop packet if mbuf too long? hmmm... */ - if (m->m_len > ip->ip_len) - m_adj(m, ip->ip_len - m->m_len); - - /* check ip_ttl for a correct ICMP reply */ - if(ip->ip_ttl==0 || ip->ip_ttl==1) { - icmp_error(m, ICMP_TIMXCEED,ICMP_TIMXCEED_INTRANS, 0,"ttl"); - goto bad; - } - - /* - * Process options and, if not destined for us, - * ship it on. ip_dooptions returns 1 when an - * error was detected (causing an icmp message - * to be sent and the original packet to be freed). - */ -/* We do no IP options */ -/* if (hlen > sizeof (struct ip) && ip_dooptions(m)) - * goto next; - */ - /* - * If offset or IP_MF are set, must reassemble. - * Otherwise, nothing need be done. - * (We could look in the reassembly queue to see - * if the packet was previously fragmented, - * but it's not worth the time; just let them time out.) - * - * XXX This should fail, don't fragment yet - */ - if (ip->ip_off &~ IP_DF) { - register struct ipq *fp; - /* - * Look for queue of fragments - * of this datagram. - */ - for (fp = (struct ipq *) ipq.next; fp != &ipq; - fp = (struct ipq *) fp->next) - if (ip->ip_id == fp->ipq_id && - ip->ip_src.s_addr == fp->ipq_src.s_addr && - ip->ip_dst.s_addr == fp->ipq_dst.s_addr && - ip->ip_p == fp->ipq_p) - goto found; - fp = 0; - found: - - /* - * Adjust ip_len to not reflect header, - * set ip_mff if more fragments are expected, - * convert offset of this to bytes. - */ - ip->ip_len -= hlen; - if (ip->ip_off & IP_MF) - ((struct ipasfrag *)ip)->ipf_mff |= 1; - else - ((struct ipasfrag *)ip)->ipf_mff &= ~1; - - ip->ip_off <<= 3; - - /* - * If datagram marked as having more fragments - * or if this is not the first fragment, - * attempt reassembly; if it succeeds, proceed. - */ - if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) { - ipstat.ips_fragments++; - ip = ip_reass((struct ipasfrag *)ip, fp); - if (ip == 0) - return; - ipstat.ips_reassembled++; - m = dtom(ip); - } else - if (fp) - ip_freef(fp); - - } else - ip->ip_len -= hlen; - - /* - * Switch out to protocol's input routine. - */ - ipstat.ips_delivered++; - switch (ip->ip_p) { - case IPPROTO_TCP: - tcp_input(m, hlen, (struct socket *)NULL); - break; - case IPPROTO_UDP: - udp_input(m, hlen); - break; - case IPPROTO_ICMP: - icmp_input(m, hlen); - break; - default: - ipstat.ips_noproto++; - m_free(m); - } - return; -bad: - m_freem(m); - return; -} - -/* - * Take incoming datagram fragment and try to - * reassemble it into whole datagram. If a chain for - * reassembly of this datagram already exists, then it - * is given as fp; otherwise have to make a chain. - */ -struct ip * -ip_reass(ip, fp) - register struct ipasfrag *ip; - register struct ipq *fp; -{ - register struct mbuf *m = dtom(ip); - register struct ipasfrag *q; - int hlen = ip->ip_hl << 2; - int i, next; - - DEBUG_CALL("ip_reass"); - DEBUG_ARG("ip = %lx", (long)ip); - DEBUG_ARG("fp = %lx", (long)fp); - DEBUG_ARG("m = %lx", (long)m); - - /* - * Presence of header sizes in mbufs - * would confuse code below. - * Fragment m_data is concatenated. - */ - m->m_data += hlen; - m->m_len -= hlen; - - /* - * If first fragment to arrive, create a reassembly queue. - */ - if (fp == 0) { - struct mbuf *t; - if ((t = m_get()) == NULL) goto dropfrag; - fp = mtod(t, struct ipq *); - insque_32(fp, &ipq); - fp->ipq_ttl = IPFRAGTTL; - fp->ipq_p = ip->ip_p; - fp->ipq_id = ip->ip_id; - fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp; - fp->ipq_src = ((struct ip *)ip)->ip_src; - fp->ipq_dst = ((struct ip *)ip)->ip_dst; - q = (struct ipasfrag *)fp; - goto insert; - } - - /* - * Find a segment which begins after this one does. - */ - for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp; - q = (struct ipasfrag *)q->ipf_next) - if (q->ip_off > ip->ip_off) - break; - - /* - * If there is a preceding segment, it may provide some of - * our data already. If so, drop the data from the incoming - * segment. If it provides all of our data, drop us. - */ - if (q->ipf_prev != (ipasfragp_32)fp) { - i = ((struct ipasfrag *)(q->ipf_prev))->ip_off + - ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off; - if (i > 0) { - if (i >= ip->ip_len) - goto dropfrag; - m_adj(dtom(ip), i); - ip->ip_off += i; - ip->ip_len -= i; - } - } - - /* - * While we overlap succeeding segments trim them or, - * if they are completely covered, dequeue them. - */ - while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) { - i = (ip->ip_off + ip->ip_len) - q->ip_off; - if (i < q->ip_len) { - q->ip_len -= i; - q->ip_off += i; - m_adj(dtom(q), i); - break; - } - q = (struct ipasfrag *) q->ipf_next; - m_freem(dtom((struct ipasfrag *) q->ipf_prev)); - ip_deq((struct ipasfrag *) q->ipf_prev); - } - -insert: - /* - * Stick new segment in its place; - * check for complete reassembly. - */ - ip_enq(ip, (struct ipasfrag *) q->ipf_prev); - next = 0; - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; - q = (struct ipasfrag *) q->ipf_next) { - if (q->ip_off != next) - return (0); - next += q->ip_len; - } - if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1) - return (0); - - /* - * Reassembly is complete; concatenate fragments. - */ - q = (struct ipasfrag *) fp->ipq_next; - m = dtom(q); - - q = (struct ipasfrag *) q->ipf_next; - while (q != (struct ipasfrag *)fp) { - struct mbuf *t; - t = dtom(q); - q = (struct ipasfrag *) q->ipf_next; - m_cat(m, t); - } - - /* - * Create header for new ip packet by - * modifying header of first packet; - * dequeue and discard fragment reassembly header. - * Make header visible. - */ - ip = (struct ipasfrag *) fp->ipq_next; - - /* - * If the fragments concatenated to an mbuf that's - * bigger than the total size of the fragment, then and - * m_ext buffer was alloced. But fp->ipq_next points to - * the old buffer (in the mbuf), so we must point ip - * into the new buffer. - */ - if (m->m_flags & M_EXT) { - int delta; - delta = (char *)ip - m->m_dat; - ip = (struct ipasfrag *)(m->m_ext + delta); - } - - /* DEBUG_ARG("ip = %lx", (long)ip); - * ip=(struct ipasfrag *)m->m_data; */ - - ip->ip_len = next; - ip->ipf_mff &= ~1; - ((struct ip *)ip)->ip_src = fp->ipq_src; - ((struct ip *)ip)->ip_dst = fp->ipq_dst; - remque_32(fp); - (void) m_free(dtom(fp)); - m = dtom(ip); - m->m_len += (ip->ip_hl << 2); - m->m_data -= (ip->ip_hl << 2); - - return ((struct ip *)ip); - -dropfrag: - ipstat.ips_fragdropped++; - m_freem(m); - return (0); -} - -/* - * Free a fragment reassembly header and all - * associated datagrams. - */ -void -ip_freef(fp) - struct ipq *fp; -{ - register struct ipasfrag *q, *p; - - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; - q = p) { - p = (struct ipasfrag *) q->ipf_next; - ip_deq(q); - m_freem(dtom(q)); - } - remque_32(fp); - (void) m_free(dtom(fp)); -} - -/* - * Put an ip fragment on a reassembly chain. - * Like insque, but pointers in middle of structure. - */ -void -ip_enq(p, prev) - register struct ipasfrag *p, *prev; -{ - DEBUG_CALL("ip_enq"); - DEBUG_ARG("prev = %lx", (long)prev); - p->ipf_prev = (ipasfragp_32) prev; - p->ipf_next = prev->ipf_next; - ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p; - prev->ipf_next = (ipasfragp_32) p; -} - -/* - * To ip_enq as remque is to insque. - */ -void -ip_deq(p) - register struct ipasfrag *p; -{ - ((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next; - ((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev; -} - -/* - * IP timer processing; - * if a timer expires on a reassembly - * queue, discard it. - */ -void -ip_slowtimo() -{ - register struct ipq *fp; - - DEBUG_CALL("ip_slowtimo"); - - fp = (struct ipq *) ipq.next; - if (fp == 0) - return; - - while (fp != &ipq) { - --fp->ipq_ttl; - fp = (struct ipq *) fp->next; - if (((struct ipq *)(fp->prev))->ipq_ttl == 0) { - ipstat.ips_fragtimeout++; - ip_freef((struct ipq *) fp->prev); - } - } -} - -/* - * Do option processing on a datagram, - * possibly discarding it if bad options are encountered, - * or forwarding it if source-routed. - * Returns 1 if packet has been forwarded/freed, - * 0 if the packet should be processed further. - */ - -#ifdef notdef - -int -ip_dooptions(m) - struct mbuf *m; -{ - register struct ip *ip = mtod(m, struct ip *); - register u_char *cp; - register struct ip_timestamp *ipt; - register struct in_ifaddr *ia; -/* int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; */ - int opt, optlen, cnt, off, code, type, forward = 0; - struct in_addr *sin, dst; -typedef u_int32_t n_time; - n_time ntime; - - dst = ip->ip_dst; - cp = (u_char *)(ip + 1); - cnt = (ip->ip_hl << 2) - sizeof (struct ip); - for (; cnt > 0; cnt -= optlen, cp += optlen) { - opt = cp[IPOPT_OPTVAL]; - if (opt == IPOPT_EOL) - break; - if (opt == IPOPT_NOP) - optlen = 1; - else { - optlen = cp[IPOPT_OLEN]; - if (optlen <= 0 || optlen > cnt) { - code = &cp[IPOPT_OLEN] - (u_char *)ip; - goto bad; - } - } - switch (opt) { - - default: - break; - - /* - * Source routing with record. - * Find interface with current destination address. - * If none on this machine then drop if strictly routed, - * or do nothing if loosely routed. - * Record interface address and bring up next address - * component. If strictly routed make sure next - * address is on directly accessible net. - */ - case IPOPT_LSRR: - case IPOPT_SSRR: - if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) { - code = &cp[IPOPT_OFFSET] - (u_char *)ip; - goto bad; - } - ipaddr.sin_addr = ip->ip_dst; - ia = (struct in_ifaddr *) - ifa_ifwithaddr((struct sockaddr *)&ipaddr); - if (ia == 0) { - if (opt == IPOPT_SSRR) { - type = ICMP_UNREACH; - code = ICMP_UNREACH_SRCFAIL; - goto bad; - } - /* - * Loose routing, and not at next destination - * yet; nothing to do except forward. - */ - break; - } - off--; / * 0 origin * / - if (off > optlen - sizeof(struct in_addr)) { - /* - * End of source route. Should be for us. - */ - save_rte(cp, ip->ip_src); - break; - } - /* - * locate outgoing interface - */ - bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr, - sizeof(ipaddr.sin_addr)); - if (opt == IPOPT_SSRR) { -#define INA struct in_ifaddr * -#define SA struct sockaddr * - if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0) - ia = (INA)ifa_ifwithnet((SA)&ipaddr); - } else - ia = ip_rtaddr(ipaddr.sin_addr); - if (ia == 0) { - type = ICMP_UNREACH; - code = ICMP_UNREACH_SRCFAIL; - goto bad; - } - ip->ip_dst = ipaddr.sin_addr; - bcopy((caddr_t)&(IA_SIN(ia)->sin_addr), - (caddr_t)(cp + off), sizeof(struct in_addr)); - cp[IPOPT_OFFSET] += sizeof(struct in_addr); - /* - * Let ip_intr's mcast routing check handle mcast pkts - */ - forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr)); - break; - - case IPOPT_RR: - if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) { - code = &cp[IPOPT_OFFSET] - (u_char *)ip; - goto bad; - } - /* - * If no space remains, ignore. - */ - off--; * 0 origin * - if (off > optlen - sizeof(struct in_addr)) - break; - bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr, - sizeof(ipaddr.sin_addr)); - /* - * locate outgoing interface; if we're the destination, - * use the incoming interface (should be same). - */ - if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 && - (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) { - type = ICMP_UNREACH; - code = ICMP_UNREACH_HOST; - goto bad; - } - bcopy((caddr_t)&(IA_SIN(ia)->sin_addr), - (caddr_t)(cp + off), sizeof(struct in_addr)); - cp[IPOPT_OFFSET] += sizeof(struct in_addr); - break; - - case IPOPT_TS: - code = cp - (u_char *)ip; - ipt = (struct ip_timestamp *)cp; - if (ipt->ipt_len < 5) - goto bad; - if (ipt->ipt_ptr > ipt->ipt_len - sizeof (int32_t)) { - if (++ipt->ipt_oflw == 0) - goto bad; - break; - } - sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1); - switch (ipt->ipt_flg) { - - case IPOPT_TS_TSONLY: - break; - - case IPOPT_TS_TSANDADDR: - if (ipt->ipt_ptr + sizeof(n_time) + - sizeof(struct in_addr) > ipt->ipt_len) - goto bad; - ipaddr.sin_addr = dst; - ia = (INA)ifaof_ i f p foraddr((SA)&ipaddr, - m->m_pkthdr.rcvif); - if (ia == 0) - continue; - bcopy((caddr_t)&IA_SIN(ia)->sin_addr, - (caddr_t)sin, sizeof(struct in_addr)); - ipt->ipt_ptr += sizeof(struct in_addr); - break; - - case IPOPT_TS_PRESPEC: - if (ipt->ipt_ptr + sizeof(n_time) + - sizeof(struct in_addr) > ipt->ipt_len) - goto bad; - bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr, - sizeof(struct in_addr)); - if (ifa_ifwithaddr((SA)&ipaddr) == 0) - continue; - ipt->ipt_ptr += sizeof(struct in_addr); - break; - - default: - goto bad; - } - ntime = iptime(); - bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1, - sizeof(n_time)); - ipt->ipt_ptr += sizeof(n_time); - } - } - if (forward) { - ip_forward(m, 1); - return (1); - } - } - } - return (0); -bad: - /* ip->ip_len -= ip->ip_hl << 2; XXX icmp_error adds in hdr length */ - -/* Not yet */ - icmp_error(m, type, code, 0, 0); - - ipstat.ips_badoptions++; - return (1); -} - -#endif /* notdef */ - -/* - * Strip out IP options, at higher - * level protocol in the kernel. - * Second argument is buffer to which options - * will be moved, and return value is their length. - * (XXX) should be deleted; last arg currently ignored. - */ -void -ip_stripoptions(m, mopt) - register struct mbuf *m; - struct mbuf *mopt; -{ - register int i; - struct ip *ip = mtod(m, struct ip *); - register caddr_t opts; - int olen; - - olen = (ip->ip_hl<<2) - sizeof (struct ip); - opts = (caddr_t)(ip + 1); - i = m->m_len - (sizeof (struct ip) + olen); - memcpy(opts, opts + olen, (unsigned)i); - m->m_len -= olen; - - ip->ip_hl = sizeof(struct ip) >> 2; -} diff --git a/BasiliskII/src/slirp/ip_output.c b/BasiliskII/src/slirp/ip_output.c deleted file mode 100644 index fb9a9420..00000000 --- a/BasiliskII/src/slirp/ip_output.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 - * ip_output.c,v 1.9 1994/11/16 10:17:10 jkh Exp - */ - -/* - * Changes and additions relating to SLiRP are - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include - -u_int16_t ip_id; - -/* - * IP output. The packet in mbuf chain m contains a skeletal IP - * header (with len, off, ttl, proto, tos, src, dst). - * The mbuf chain containing the packet will be freed. - * The mbuf opt, if present, will not be freed. - */ -int -ip_output(so, m0) - struct socket *so; - struct mbuf *m0; -{ - register struct ip *ip; - register struct mbuf *m = m0; - register u_int hlen = sizeof(struct ip); - u_int len, off; - int error = 0; - - DEBUG_CALL("ip_output"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("m0 = %lx", (long)m0); - - /* We do no options */ -/* if (opt) { - * m = ip_insertoptions(m, opt, &len); - * hlen = len; - * } - */ - ip = mtod(m, struct ip *); - /* - * Fill in IP header. - */ - ip->ip_v = IPVERSION; - ip->ip_off &= IP_DF; - ip->ip_id = htons(ip_id++); - ip->ip_hl = hlen >> 2; - ipstat.ips_localout++; - - /* - * Verify that we have any chance at all of being able to queue - * the packet or packet fragments - */ - /* XXX Hmmm... */ -/* if (if_queued > if_thresh && towrite <= 0) { - * error = ENOBUFS; - * goto bad; - * } - */ - - /* - * If small enough for interface, can just send directly. - */ - if ((u_int16_t)ip->ip_len <= if_mtu) { - ip->ip_len = htons((u_int16_t)ip->ip_len); - ip->ip_off = htons((u_int16_t)ip->ip_off); - ip->ip_sum = 0; - ip->ip_sum = cksum(m, hlen); - - if_output(so, m); - goto done; - } - - /* - * Too large for interface; fragment if possible. - * Must be able to put at least 8 bytes per fragment. - */ - if (ip->ip_off & IP_DF) { - error = -1; - ipstat.ips_cantfrag++; - goto bad; - } - - len = (if_mtu - hlen) &~ 7; /* ip databytes per packet */ - if (len < 8) { - error = -1; - goto bad; - } - - { - int mhlen, firstlen = len; - struct mbuf **mnext = &m->m_nextpkt; - - /* - * Loop through length of segment after first fragment, - * make new header and copy data of each part and link onto chain. - */ - m0 = m; - mhlen = sizeof (struct ip); - for (off = hlen + len; off < ip->ip_len; off += len) { - register struct ip *mhip; - m = m_get(); - if (m == 0) { - error = -1; - ipstat.ips_odropped++; - goto sendorfree; - } - m->m_data += if_maxlinkhdr; - mhip = mtod(m, struct ip *); - *mhip = *ip; - - /* No options */ -/* if (hlen > sizeof (struct ip)) { - * mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); - * mhip->ip_hl = mhlen >> 2; - * } - */ - m->m_len = mhlen; - mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); - if (ip->ip_off & IP_MF) - mhip->ip_off |= IP_MF; - if (off + len >= (u_int16_t)ip->ip_len) - len = (u_int16_t)ip->ip_len - off; - else - mhip->ip_off |= IP_MF; - mhip->ip_len = htons((u_int16_t)(len + mhlen)); - - if (m_copy(m, m0, off, len) < 0) { - error = -1; - goto sendorfree; - } - - mhip->ip_off = htons((u_int16_t)mhip->ip_off); - mhip->ip_sum = 0; - mhip->ip_sum = cksum(m, mhlen); - *mnext = m; - mnext = &m->m_nextpkt; - ipstat.ips_ofragments++; - } - /* - * Update first fragment by trimming what's been copied out - * and updating header, then send each fragment (in order). - */ - m = m0; - m_adj(m, hlen + firstlen - ip->ip_len); - ip->ip_len = htons((u_int16_t)m->m_len); - ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF)); - ip->ip_sum = 0; - ip->ip_sum = cksum(m, hlen); -sendorfree: - for (m = m0; m; m = m0) { - m0 = m->m_nextpkt; - m->m_nextpkt = 0; - if (error == 0) - if_output(so, m); - else - m_freem(m); - } - - if (error == 0) - ipstat.ips_fragmented++; - } - -done: - return (error); - -bad: - m_freem(m0); - goto done; -} diff --git a/BasiliskII/src/slirp/libslirp.h b/BasiliskII/src/slirp/libslirp.h deleted file mode 100644 index 8a1aa31e..00000000 --- a/BasiliskII/src/slirp/libslirp.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _LIBSLIRP_H -#define _LIBSLIRP_H - -#ifdef _WIN32 -#include -int inet_aton(const char *cp, struct in_addr *ia); -#else -#include -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -int slirp_init(void); - -int slirp_select_fill(int *pnfds, - fd_set *readfds, fd_set *writefds, fd_set *xfds); - -void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds); - -void slirp_input(const uint8 *pkt, int pkt_len); - -/* you must provide the following functions: */ -int slirp_can_output(void); -void slirp_output(const uint8 *pkt, int pkt_len); - -int slirp_redir(int is_udp, int host_port, - struct in_addr guest_addr, int guest_port); -int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, - int guest_port); - -extern const char *tftp_prefix; -extern char slirp_hostname[33]; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/BasiliskII/src/slirp/main.h b/BasiliskII/src/slirp/main.h deleted file mode 100644 index 181b6ae8..00000000 --- a/BasiliskII/src/slirp/main.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -#define TOWRITEMAX 512 - -extern struct timeval tt; -extern int link_up; -extern int slirp_socket; -extern int slirp_socket_unit; -extern int slirp_socket_port; -extern u_int32_t slirp_socket_addr; -extern char *slirp_socket_passwd; -extern int ctty_closed; - -/* - * Get the difference in 2 times from updtim() - * Allow for wraparound times, "just in case" - * x is the greater of the 2 (current time) and y is - * what it's being compared against. - */ -#define TIME_DIFF(x,y) (x)-(y) < 0 ? ~0-(y)+(x) : (x)-(y) - -extern char *slirp_tty; -extern char *exec_shell; -extern u_int curtime; -extern fd_set *global_readfds, *global_writefds, *global_xfds; -extern struct in_addr ctl_addr; -extern struct in_addr special_addr; -extern struct in_addr alias_addr; -extern struct in_addr our_addr; -extern struct in_addr loopback_addr; -extern struct in_addr dns_addr; -extern char *username; -extern char *socket_path; -extern int towrite_max; -extern int ppp_exit; -extern int so_options; -extern int tcp_keepintvl; -extern uint8_t client_ethaddr[6]; - -#define PROTO_SLIP 0x1 -#ifdef USE_PPP -#define PROTO_PPP 0x2 -#endif - -void if_encap(const uint8_t *ip_data, int ip_data_len); diff --git a/BasiliskII/src/slirp/mbuf.c b/BasiliskII/src/slirp/mbuf.c deleted file mode 100644 index 5a16fab8..00000000 --- a/BasiliskII/src/slirp/mbuf.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -/* - * mbuf's in SLiRP are much simpler than the real mbufs in - * FreeBSD. They are fixed size, determined by the MTU, - * so that one whole packet can fit. Mbuf's cannot be - * chained together. If there's more data than the mbuf - * could hold, an external malloced buffer is pointed to - * by m_ext (and the data pointers) and M_EXT is set in - * the flags - */ - -#include -#include - -struct mbuf *mbutl; -char *mclrefcnt; -int mbuf_alloced = 0; -struct mbuf m_freelist, m_usedlist; -int mbuf_thresh = 30; -int mbuf_max = 0; -size_t msize; - -void m_init() -{ - m_freelist.m_next = m_freelist.m_prev = &m_freelist; - m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist; - msize_init(); -} - -void msize_init() -{ - /* - * Find a nice value for msize - * XXX if_maxlinkhdr already in mtu - */ - msize = (if_mtu>if_mru?if_mtu:if_mru) + - if_maxlinkhdr + sizeof(struct m_hdr ) + 6; -} - -/* - * Get an mbuf from the free list, if there are none - * malloc one - * - * Because fragmentation can occur if we alloc new mbufs and - * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE, - * which tells m_free to actually free() it - */ -struct mbuf *m_get() -{ - register struct mbuf *m; - int flags = 0; - - DEBUG_CALL("m_get"); - - if (m_freelist.m_next == &m_freelist) { - m = (struct mbuf *)malloc(msize); - if (m == NULL) goto end_error; - mbuf_alloced++; - if (mbuf_alloced > mbuf_thresh) - flags = M_DOFREE; - if (mbuf_alloced > mbuf_max) - mbuf_max = mbuf_alloced; - } else { - m = m_freelist.m_next; - remque(m); - } - - /* Insert it in the used list */ - insque(m,&m_usedlist); - m->m_flags = (flags | M_USEDLIST); - - /* Initialise it */ - m->m_size = msize - sizeof(struct m_hdr); - m->m_data = m->m_dat; - m->m_len = 0; - m->m_nextpkt = 0; - m->m_prevpkt = 0; -end_error: - DEBUG_ARG("m = %lx", (long )m); - return m; -} - -void m_free(struct mbuf *m) -{ - - DEBUG_CALL("m_free"); - DEBUG_ARG("m = %lx", (long )m); - - if(m) { - /* Remove from m_usedlist */ - if (m->m_flags & M_USEDLIST) - remque(m); - - /* If it's M_EXT, free() it */ - if (m->m_flags & M_EXT) - free(m->m_ext); - - /* - * Either free() it or put it on the free list - */ - if (m->m_flags & M_DOFREE) { - free(m); - mbuf_alloced--; - } else if ((m->m_flags & M_FREELIST) == 0) { - insque(m,&m_freelist); - m->m_flags = M_FREELIST; /* Clobber other flags */ - } - } /* if(m) */ -} - -/* - * Copy data from one mbuf to the end of - * the other.. if result is too big for one mbuf, malloc() - * an M_EXT data segment - */ -void m_cat(register struct mbuf *m, register struct mbuf *n) -{ - /* - * If there's no room, realloc - */ - if (M_FREEROOM(m) < n->m_len) - m_inc(m,m->m_size+MINCSIZE); - - memcpy(m->m_data+m->m_len, n->m_data, n->m_len); - m->m_len += n->m_len; - - m_free(n); -} - - -/* make m size bytes large */ -void m_inc(struct mbuf *m, u_int size) -{ - int datasize; - - /* some compiles throw up on gotos. This one we can fake. */ - if(m->m_size>size) return; - - if (m->m_flags & M_EXT) { - datasize = m->m_data - m->m_ext; - m->m_ext = (char *)realloc(m->m_ext,size); -/* if (m->m_ext == NULL) - * return (struct mbuf *)NULL; - */ - m->m_data = m->m_ext + datasize; - } else { - char *dat; - datasize = m->m_data - m->m_dat; - dat = (char *)malloc(size); -/* if (dat == NULL) - * return (struct mbuf *)NULL; - */ - memcpy(dat, m->m_dat, m->m_size); - - m->m_ext = dat; - m->m_data = m->m_ext + datasize; - m->m_flags |= M_EXT; - } - - m->m_size = size; - -} - - - -void m_adj(struct mbuf *m, int len) -{ - if (m == NULL) - return; - if (len >= 0) { - /* Trim from head */ - m->m_data += len; - m->m_len -= len; - } else { - /* Trim from tail */ - len = -len; - m->m_len -= len; - } -} - - -/* - * Copy len bytes from m, starting off bytes into n - */ -int -m_copy(struct mbuf *n, struct mbuf *m, u_int off, u_int len) -{ - if (len > M_FREEROOM(n)) - return -1; - - memcpy((n->m_data + n->m_len), (m->m_data + off), len); - n->m_len += len; - return 0; -} - - -/* - * Given a pointer into an mbuf, return the mbuf - * XXX This is a kludge, I should eliminate the need for it - * Fortunately, it's not used often - */ -struct mbuf *dtom(void *dat) -{ - struct mbuf *m; - - DEBUG_CALL("dtom"); - DEBUG_ARG("dat = %lx", (long )dat); - - /* bug corrected for M_EXT buffers */ - for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) { - if (m->m_flags & M_EXT) { - if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) ) - return m; - } else { - if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) ) - return m; - } - } - - DEBUG_ERROR((dfd, "dtom failed")); - - return (struct mbuf *)0; -} - diff --git a/BasiliskII/src/slirp/mbuf.h b/BasiliskII/src/slirp/mbuf.h deleted file mode 100644 index 11b252bb..00000000 --- a/BasiliskII/src/slirp/mbuf.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)mbuf.h 8.3 (Berkeley) 1/21/94 - * mbuf.h,v 1.9 1994/11/14 13:54:20 bde Exp - */ - -#ifndef _MBUF_H_ -#define _MBUF_H_ - -#define m_freem m_free - - -#define MINCSIZE 4096 /* Amount to increase mbuf if too small */ - -/* - * Macros for type conversion - * mtod(m,t) - convert mbuf pointer to data pointer of correct type - * dtom(x) - convert data pointer within mbuf to mbuf pointer (XXX) - */ -#define mtod(m,t) ((t)(m)->m_data) -/* #define dtom(x) ((struct mbuf *)((int)(x) & ~(M_SIZE-1))) */ - -/* XXX About mbufs for slirp: - * Only one mbuf is ever used in a chain, for each "cell" of data. - * m_nextpkt points to the next packet, if fragmented. - * If the data is too large, the M_EXT is used, and a larger block - * is alloced. Therefore, m_free[m] must check for M_EXT and if set - * free the m_ext. This is inefficient memory-wise, but who cares. - */ - -/* XXX should union some of these! */ -/* header at beginning of each mbuf: */ -struct m_hdr { - struct mbuf *mh_next; /* Linked list of mbufs */ - struct mbuf *mh_prev; - struct mbuf *mh_nextpkt; /* Next packet in queue/record */ - struct mbuf *mh_prevpkt; /* Flags aren't used in the output queue */ - int mh_flags; /* Misc flags */ - - size_t mh_size; /* Size of data */ - struct socket *mh_so; - - caddr_t mh_data; /* Location of data */ - size_t mh_len; /* Amount of data in this mbuf */ -}; - -/* - * How much room is in the mbuf, from m_data to the end of the mbuf - */ -#define M_ROOM(m) ((m->m_flags & M_EXT)? \ - (((m)->m_ext + (m)->m_size) - (m)->m_data) \ - : \ - (((m)->m_dat + (m)->m_size) - (m)->m_data)) - -/* - * How much free room there is - */ -#define M_FREEROOM(m) (M_ROOM(m) - (m)->m_len) -#define M_TRAILINGSPACE M_FREEROOM - -struct mbuf { - struct m_hdr m_hdr; - union M_dat { - char m_dat_[1]; /* ANSI don't like 0 sized arrays */ - char *m_ext_; - } M_dat; -}; - -#define m_next m_hdr.mh_next -#define m_prev m_hdr.mh_prev -#define m_nextpkt m_hdr.mh_nextpkt -#define m_prevpkt m_hdr.mh_prevpkt -#define m_flags m_hdr.mh_flags -#define m_len m_hdr.mh_len -#define m_data m_hdr.mh_data -#define m_size m_hdr.mh_size -#define m_dat M_dat.m_dat_ -#define m_ext M_dat.m_ext_ -#define m_so m_hdr.mh_so - -#define ifq_prev m_prev -#define ifq_next m_next -#define ifs_prev m_prevpkt -#define ifs_next m_nextpkt -#define ifq_so m_so - -#define M_EXT 0x01 /* m_ext points to more (malloced) data */ -#define M_FREELIST 0x02 /* mbuf is on free list */ -#define M_USEDLIST 0x04 /* XXX mbuf is on used list (for dtom()) */ -#define M_DOFREE 0x08 /* when m_free is called on the mbuf, free() - * it rather than putting it on the free list */ - -/* - * Mbuf statistics. XXX - */ - -struct mbstat { - int mbs_alloced; /* Number of mbufs allocated */ - -}; - -extern struct mbstat mbstat; -extern int mbuf_alloced; -extern struct mbuf m_freelist, m_usedlist; -extern int mbuf_max; - -void m_init(void); -void msize_init(void); -struct mbuf * m_get(void); -void m_free(struct mbuf *); -void m_cat(register struct mbuf *, register struct mbuf *); -void m_inc(struct mbuf *, u_int); -void m_adj(struct mbuf *, int); -int m_copy(struct mbuf *, struct mbuf *, u_int, u_int); -struct mbuf * dtom(void *); - -#endif diff --git a/BasiliskII/src/slirp/misc.c b/BasiliskII/src/slirp/misc.c deleted file mode 100644 index b80caf66..00000000 --- a/BasiliskII/src/slirp/misc.c +++ /dev/null @@ -1,863 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#define WANT_SYS_IOCTL_H -#include -#include - -u_int curtime, time_fasttimo, last_slowtimo, detach_time; -u_int detach_wait = 600000; /* 10 minutes */ - -#if 0 -int x_port = -1; -int x_display = 0; -int x_screen = 0; - -int show_x(char *buff, struct socket *inso) -{ - if (x_port < 0) { - lprint("X Redir: X not being redirected.\r\n"); - } else { - lprint("X Redir: In sh/bash/zsh/etc. type: DISPLAY=%s:%d.%d; export DISPLAY\r\n", - inet_ntoa(our_addr), x_port, x_screen); - lprint("X Redir: In csh/tcsh/etc. type: setenv DISPLAY %s:%d.%d\r\n", - inet_ntoa(our_addr), x_port, x_screen); - if (x_display) - lprint("X Redir: Redirecting to display %d\r\n", x_display); - } - - return CFG_OK; -} - - -/* - * XXX Allow more than one X redirection? - */ -void redir_x(u_int32_t inaddr, int start_port, int display, int screen) -{ - int i; - - if (x_port >= 0) { - lprint("X Redir: X already being redirected.\r\n"); - show_x(0, 0); - } else { - for (i = 6001 + (start_port-1); i <= 6100; i++) { - if (solisten(htons(i), inaddr, htons(6000 + display), 0)) { - /* Success */ - x_port = i - 6000; - x_display = display; - x_screen = screen; - show_x(0, 0); - return; - } - } - lprint("X Redir: Error: Couldn't redirect a port for X. Weird.\r\n"); - } -} -#endif - -#ifndef HAVE_INET_ATON -int inet_aton(const char *cp, struct in_addr *ia) -{ - return inet_pton(AF_INET, cp, &ia->s_addr); -} -#endif - -/* - * Get our IP address and put it in our_addr - */ -void getouraddr() -{ - char buff[256]; - - if (gethostname(buff, sizeof(buff)) == 0) - { - struct addrinfo hints = { 0 }; - hints.ai_flags = AI_NUMERICHOST; - hints.ai_family = AF_INET; - struct addrinfo* ai; - if (getaddrinfo(buff, NULL, &hints, &ai) == 0) - { - our_addr = *(struct in_addr *)ai->ai_addr->sa_data; - freeaddrinfo(ai); - } - } - if (our_addr.s_addr == 0) - our_addr.s_addr = loopback_addr.s_addr; -} - -#if SIZEOF_CHAR_P == 8 - -struct quehead_32 { - u_int32_t qh_link; - u_int32_t qh_rlink; -}; - -inline void insque_32(void *a, void *b) -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - register struct quehead_32 *head = (struct quehead_32 *) b; - element->qh_link = head->qh_link; - head->qh_link = (u_int32_t)element; - element->qh_rlink = (u_int32_t)head; - ((struct quehead_32 *)(element->qh_link))->qh_rlink - = (u_int32_t)element; -} - -inline void remque_32(void *a) -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink; - ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link; - element->qh_rlink = 0; -} - -#endif /* SIZEOF_CHAR_P == 8 */ - -struct quehead { - struct quehead *qh_link; - struct quehead *qh_rlink; -}; - -void insque(void *a, void *b) -{ - register struct quehead *element = (struct quehead *) a; - register struct quehead *head = (struct quehead *) b; - element->qh_link = head->qh_link; - head->qh_link = (struct quehead *)element; - element->qh_rlink = (struct quehead *)head; - ((struct quehead *)(element->qh_link))->qh_rlink - = (struct quehead *)element; -} - -void remque(void *a) -{ - register struct quehead *element = (struct quehead *) a; - ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink; - ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link; - element->qh_rlink = NULL; - /* element->qh_link = NULL; TCP FIN1 crashes if you do this. Why ? */ -} - -/* #endif */ - - -int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int port) -{ - struct ex_list *tmp_ptr; - - /* First, check if the port is "bound" */ - for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) { - if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr) - return -1; - } - - tmp_ptr = *ex_ptr; - *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list)); - (*ex_ptr)->ex_fport = port; - (*ex_ptr)->ex_addr = addr; - (*ex_ptr)->ex_pty = do_pty; - (*ex_ptr)->ex_exec = strdup(exec); - (*ex_ptr)->ex_next = tmp_ptr; - return 0; -} - -#ifndef HAVE_STRERROR - -/* - * For systems with no strerror - */ - -extern int sys_nerr; -extern char *sys_errlist[]; - -char *strerror(int error) -{ - if (error < sys_nerr) - return sys_errlist[error]; - else - return "Unknown error."; -} - -#endif - - -#ifdef _WIN32 - -int fork_exec(struct socket *so, char *ex, int do_pty) -{ - /* not implemented */ - return 0; -} - -#else - -int slirp_openpty(int *amaster, int *aslave) -{ - register int master, slave; - -#ifdef HAVE_GRANTPT - char *ptr; - - if ((master = open("/dev/ptmx", O_RDWR)) < 0 || - grantpt(master) < 0 || - unlockpt(master) < 0 || - (ptr = ptsname(master)) == NULL) { - close(master); - return -1; - } - - if ((slave = open(ptr, O_RDWR)) < 0 || - ioctl(slave, I_PUSH, "ptem") < 0 || - ioctl(slave, I_PUSH, "ldterm") < 0 || - ioctl(slave, I_PUSH, "ttcompat") < 0) { - close(master); - close(slave); - return -1; - } - - *amaster = master; - *aslave = slave; - return 0; - -#else - - static char line[] = "/dev/ptyXX"; - register const char *cp1, *cp2; - - for (cp1 = "pqrsPQRS"; *cp1; cp1++) { - line[8] = *cp1; - for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) { - line[9] = *cp2; - if ((master = open(line, O_RDWR, 0)) == -1) { - if (errno == ENOENT) - return (-1); /* out of ptys */ - } else { - line[5] = 't'; - /* These will fail */ - (void) chown(line, getuid(), 0); - (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP); -#ifdef HAVE_REVOKE - (void) revoke(line); -#endif - if ((slave = open(line, O_RDWR, 0)) != -1) { - *amaster = master; - *aslave = slave; - return 0; - } - (void) close(master); - line[5] = 'p'; - } - } - } - errno = ENOENT; /* out of ptys */ - return (-1); -#endif -} - -/* - * XXX This is ugly - * We create and bind a socket, then fork off to another - * process, which connects to this socket, after which we - * exec the wanted program. If something (strange) happens, - * the accept() call could block us forever. - * - * do_pty = 0 Fork/exec inetd style - * do_pty = 1 Fork/exec using slirp.telnetd - * do_ptr = 2 Fork/exec using pty - */ -int fork_exec(struct socket *so, char *ex, int do_pty) -{ - int s; - struct sockaddr_in addr; - socklen_t addrlen = sizeof(addr); - int opt; - int master; - char *argv[256]; -#if 0 - char buff[256]; -#endif - /* don't want to clobber the original */ - char *bptr; - char *curarg; - int c, i, ret; - - DEBUG_CALL("fork_exec"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("ex = %lx", (long)ex); - DEBUG_ARG("do_pty = %lx", (long)do_pty); - - if (do_pty == 2) { - if (slirp_openpty(&master, &s) == -1) { - lprint("Error: openpty failed: %s\n", strerror(errno)); - return 0; - } - } else { - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = 0; - addr.sin_addr.s_addr = INADDR_ANY; - - if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 || - bind(s, (struct sockaddr *)&addr, addrlen) < 0 || - listen(s, 1) < 0) { - lprint("Error: inet socket: %s\n", strerror(errno)); - closesocket(s); - - return 0; - } - } - - switch(fork()) { - case -1: - lprint("Error: fork failed: %s\n", strerror(errno)); - close(s); - if (do_pty == 2) - close(master); - return 0; - - case 0: - /* Set the DISPLAY */ - if (do_pty == 2) { - (void) close(master); -#ifdef TIOCSCTTY /* XXXXX */ - (void) setsid(); - ioctl(s, TIOCSCTTY, (char *)NULL); -#endif - } else { - getsockname(s, (struct sockaddr *)&addr, &addrlen); - close(s); - /* - * Connect to the socket - * XXX If any of these fail, we're in trouble! - */ - s = socket(AF_INET, SOCK_STREAM, 0); - addr.sin_addr = loopback_addr; - do { - ret = connect(s, (struct sockaddr *)&addr, addrlen); - } while (ret < 0 && errno == EINTR); - } - -#if 0 - if (x_port >= 0) { -#ifdef HAVE_SETENV - sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); - setenv("DISPLAY", buff, 1); -#else - sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); - putenv(buff); -#endif - } -#endif - dup2(s, 0); - dup2(s, 1); - dup2(s, 2); - for (s = 3; s <= 255; s++) - close(s); - - i = 0; - bptr = strdup(ex); /* No need to free() this */ - if (do_pty == 1) { - /* Setup "slirp.telnetd -x" */ - argv[i++] = "slirp.telnetd"; - argv[i++] = "-x"; - argv[i++] = bptr; - } else - do { - /* Change the string into argv[] */ - curarg = bptr; - while (*bptr != ' ' && *bptr != (char)0) - bptr++; - c = *bptr; - *bptr++ = (char)0; - argv[i++] = strdup(curarg); - } while (c); - - argv[i] = 0; - execvp(argv[0], argv); - - /* Ooops, failed, let's tell the user why */ - { - char buff[256]; - - sprintf(buff, "Error: execvp of %s failed: %s\n", - argv[0], strerror(errno)); - write(2, buff, strlen(buff)+1); - } - close(0); close(1); close(2); /* XXX */ - exit(1); - - default: - if (do_pty == 2) { - close(s); - so->s = master; - } else { - /* - * XXX this could block us... - * XXX Should set a timer here, and if accept() doesn't - * return after X seconds, declare it a failure - * The only reason this will block forever is if socket() - * of connect() fail in the child process - */ - do { - so->s = accept(s, (struct sockaddr *)&addr, &addrlen); - } while (so->s < 0 && errno == EINTR); - closesocket(s); - opt = 1; - setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); - opt = 1; - setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); - } - fd_nonblock(so->s); - - /* Append the telnet options now */ - if (so->so_m != 0 && do_pty == 1) { - sbappend(so, so->so_m); - so->so_m = 0; - } - - return 1; - } -} -#endif - -#ifndef HAVE_STRDUP -char *strdup(const char *str) -{ - char *bptr; - - bptr = (char *)malloc(strlen(str)+1); - strcpy(bptr, str); - - return bptr; -} -#endif - -#if 0 -void snooze_hup(int num) -{ - int s, ret; -#ifndef NO_UNIX_SOCKETS - struct sockaddr_un sock_un; -#endif - struct sockaddr_in sock_in; - char buff[256]; - - ret = -1; - if (slirp_socket_passwd) { - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) - slirp_exit(1); - sock_in.sin_family = AF_INET; - sock_in.sin_addr.s_addr = slirp_socket_addr; - sock_in.sin_port = htons(slirp_socket_port); - if (connect(s, (struct sockaddr *)&sock_in, sizeof(sock_in)) != 0) - slirp_exit(1); /* just exit...*/ - sprintf(buff, "kill %s:%d", slirp_socket_passwd, slirp_socket_unit); - write(s, buff, strlen(buff)+1); - } -#ifndef NO_UNIX_SOCKETS - else { - s = socket(AF_UNIX, SOCK_STREAM, 0); - if (s < 0) - slirp_exit(1); - sock_un.sun_family = AF_UNIX; - strcpy(sock_un.sun_path, socket_path); - if (connect(s, (struct sockaddr *)&sock_un, - sizeof(sock_un.sun_family) + sizeof(sock_un.sun_path)) != 0) - slirp_exit(1); - sprintf(buff, "kill none:%d", slirp_socket_unit); - write(s, buff, strlen(buff)+1); - } -#endif - slirp_exit(0); -} - - -void snooze() -{ - sigset_t s; - int i; - - /* Don't need our data anymore */ - /* XXX This makes SunOS barf */ -/* brk(0); */ - - /* Close all fd's */ - for (i = 255; i >= 0; i--) - close(i); - - signal(SIGQUIT, slirp_exit); - signal(SIGHUP, snooze_hup); - sigemptyset(&s); - - /* Wait for any signal */ - sigsuspend(&s); - - /* Just in case ... */ - exit(255); -} - -void relay(int s) -{ - char buf[8192]; - int n; - fd_set readfds; - struct ttys *ttyp; - - /* Don't need our data anymore */ - /* XXX This makes SunOS barf */ -/* brk(0); */ - - signal(SIGQUIT, slirp_exit); - signal(SIGHUP, slirp_exit); - signal(SIGINT, slirp_exit); - signal(SIGTERM, slirp_exit); - - /* Fudge to get term_raw and term_restore to work */ - if (NULL == (ttyp = tty_attach (0, slirp_tty))) { - lprint ("Error: tty_attach failed in misc.c:relay()\r\n"); - slirp_exit (1); - } - ttyp->fd = 0; - ttyp->flags |= TTY_CTTY; - term_raw(ttyp); - - while (1) { - FD_ZERO(&readfds); - - FD_SET(0, &readfds); - FD_SET(s, &readfds); - - n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0); - - if (n <= 0) - slirp_exit(0); - - if (FD_ISSET(0, &readfds)) { - n = read(0, buf, 8192); - if (n <= 0) - slirp_exit(0); - n = writen(s, buf, n); - if (n <= 0) - slirp_exit(0); - } - - if (FD_ISSET(s, &readfds)) { - n = read(s, buf, 8192); - if (n <= 0) - slirp_exit(0); - n = writen(0, buf, n); - if (n <= 0) - slirp_exit(0); - } - } - - /* Just in case.... */ - exit(1); -} -#endif - -int (*lprint_print)(void *, const char *, va_list); -char *lprint_ptr, *lprint_ptr2, **lprint_arg; - -void lprint(const char *format, ...) -{ - va_list args; - - va_start(args, format); -#if 0 - /* If we're printing to an sbuf, make sure there's enough room */ - /* XXX +100? */ - if (lprint_sb) { - if ((lprint_ptr - lprint_sb->sb_wptr) >= - (lprint_sb->sb_datalen - (strlen(format) + 100))) { - int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data; - int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data; - int deltap = lprint_ptr - lprint_sb->sb_data; - - lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data, - lprint_sb->sb_datalen + TCP_SNDSPACE); - - /* Adjust all values */ - lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw; - lprint_sb->sb_rptr = lprint_sb->sb_data + deltar; - lprint_ptr = lprint_sb->sb_data + deltap; - - lprint_sb->sb_datalen += TCP_SNDSPACE; - } - } -#endif - if (lprint_print) - lprint_ptr += (*lprint_print)(*lprint_arg, format, args); - - /* Check if they want output to be logged to file as well */ - if (lfd) { - /* - * Remove \r's - * otherwise you'll get ^M all over the file - */ - int len = strlen(format); - char *bptr1, *bptr2; - - bptr1 = bptr2 = strdup(format); - - while (len--) { - if (*bptr1 == '\r') - memcpy(bptr1, bptr1+1, len+1); - else - bptr1++; - } - vfprintf(lfd, bptr2, args); - free(bptr2); - } - va_end(args); -} - -void add_emu(char *buff) -{ - u_int lport, fport; - u_int8_t tos = 0, emu = 0; - char buff1[256], buff2[256], buff4[128]; - char *buff3 = buff4; - struct emu_t *emup; - struct socket *so; - - if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) { - lprint("Error: Bad arguments\r\n"); - return; - } - - if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) { - lport = 0; - if (sscanf(buff1, "%d", &fport) != 1) { - lprint("Error: Bad first argument\r\n"); - return; - } - } - - if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) { - buff3 = 0; - if (sscanf(buff2, "%256s", buff1) != 1) { - lprint("Error: Bad second argument\r\n"); - return; - } - } - - if (buff3) { - if (strcmp(buff3, "lowdelay") == 0) - tos = IPTOS_LOWDELAY; - else if (strcmp(buff3, "throughput") == 0) - tos = IPTOS_THROUGHPUT; - else { - lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n"); - return; - } - } - - if (strcmp(buff1, "ftp") == 0) - emu = EMU_FTP; - else if (strcmp(buff1, "irc") == 0) - emu = EMU_IRC; - else if (strcmp(buff1, "none") == 0) - emu = EMU_NONE; /* ie: no emulation */ - else { - lprint("Error: Unknown service\r\n"); - return; - } - - /* First, check that it isn't already emulated */ - for (emup = tcpemu; emup; emup = emup->next) { - if (emup->lport == lport && emup->fport == fport) { - lprint("Error: port already emulated\r\n"); - return; - } - } - - /* link it */ - emup = (struct emu_t *)malloc(sizeof (struct emu_t)); - emup->lport = (u_int16_t)lport; - emup->fport = (u_int16_t)fport; - emup->tos = tos; - emup->emu = emu; - emup->next = tcpemu; - tcpemu = emup; - - /* And finally, mark all current sessions, if any, as being emulated */ - for (so = tcb.so_next; so != &tcb; so = so->so_next) { - if ((lport && lport == ntohs(so->so_lport)) || - (fport && fport == ntohs(so->so_fport))) { - if (emu) - so->so_emu = emu; - if (tos) - so->so_iptos = tos; - } - } - - lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport); -} - -#ifdef BAD_SPRINTF - -#undef vsprintf -#undef sprintf - -/* - * Some BSD-derived systems have a sprintf which returns char * - */ - -int vsprintf_len(char *string, const char *format, va_list args) -{ - vsprintf(string, format, args); - return strlen(string); -} - -int sprintf_len(char *string, const char *format, ...) -{ - va_list args; - va_start(args, format); - vsprintf(string, format, args); - va_end(args); - return strlen(string); -} - -#endif - -void u_sleep(int usec) -{ - struct timeval t; - fd_set fdset; - - FD_ZERO(&fdset); - - t.tv_sec = 0; - t.tv_usec = usec * 1000; - - select(0, &fdset, &fdset, &fdset, &t); -} - -/* - * Set fd blocking and non-blocking - */ - -void fd_nonblock(int fd) -{ -#if defined USE_FIONBIO && defined FIONBIO - ioctlsockopt_t opt = 1; - - ioctlsocket(fd, FIONBIO, &opt); -#else - int opt; - - opt = fcntl(fd, F_GETFL, 0); - opt |= O_NONBLOCK; - fcntl(fd, F_SETFL, opt); -#endif -} - -void fd_block(int fd) -{ -#if defined USE_FIONBIO && defined FIONBIO - ioctlsockopt_t opt = 0; - - ioctlsocket(fd, FIONBIO, &opt); -#else - int opt; - - opt = fcntl(fd, F_GETFL, 0); - opt &= ~O_NONBLOCK; - fcntl(fd, F_SETFL, opt); -#endif -} - - -#if 0 -/* - * invoke RSH - */ -int rsh_exec(struct socket *so, struct socket *ns, - char *user, char *host, char *args) -{ - int fd[2]; - int fd0[2]; - int s; - char buff[256]; - - DEBUG_CALL("rsh_exec"); - DEBUG_ARG("so = %lx", (long)so); - - if (pipe(fd)<0) { - lprint("Error: pipe failed: %s\n", strerror(errno)); - return 0; - } -/* #ifdef HAVE_SOCKETPAIR */ -#if 1 - if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) { - close(fd[0]); - close(fd[1]); - lprint("Error: openpty failed: %s\n", strerror(errno)); - return 0; - } -#else - if (slirp_openpty(&fd0[0], &fd0[1]) == -1) { - close(fd[0]); - close(fd[1]); - lprint("Error: openpty failed: %s\n", strerror(errno)); - return 0; - } -#endif - - switch(fork()) { - case -1: - lprint("Error: fork failed: %s\n", strerror(errno)); - close(fd[0]); - close(fd[1]); - close(fd0[0]); - close(fd0[1]); - return 0; - - case 0: - close(fd[0]); - close(fd0[0]); - - /* Set the DISPLAY */ - if (x_port >= 0) { -#ifdef HAVE_SETENV - sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); - setenv("DISPLAY", buff, 1); -#else - sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); - putenv(buff); -#endif - } - - dup2(fd0[1], 0); - dup2(fd0[1], 1); - dup2(fd[1], 2); - for (s = 3; s <= 255; s++) - close(s); - - execlp("rsh","rsh","-l", user, host, args, NULL); - - /* Ooops, failed, let's tell the user why */ - - sprintf(buff, "Error: execlp of %s failed: %s\n", - "rsh", strerror(errno)); - write(2, buff, strlen(buff)+1); - close(0); close(1); close(2); /* XXX */ - exit(1); - - default: - close(fd[1]); - close(fd0[1]); - ns->s=fd[0]; - so->s=fd0[0]; - - return 1; - } -} -#endif diff --git a/BasiliskII/src/slirp/misc.h b/BasiliskII/src/slirp/misc.h deleted file mode 100644 index 381f5f3e..00000000 --- a/BasiliskII/src/slirp/misc.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#ifndef _MISC_H_ -#define _MISC_H_ - -struct ex_list { - int ex_pty; /* Do we want a pty? */ - int ex_addr; /* The last byte of the address */ - int ex_fport; /* Port to telnet to */ - char *ex_exec; /* Command line of what to exec */ - struct ex_list *ex_next; -}; - -extern struct ex_list *exec_list; -extern u_int curtime, time_fasttimo, last_slowtimo, detach_time, detach_wait; - -extern int (*lprint_print)(void *, const char *, va_list); -extern char *lprint_ptr, *lprint_ptr2, **lprint_arg; -extern struct sbuf *lprint_sb; - -#ifndef HAVE_STRDUP -char *strdup(const char *); -#endif - -void do_wait(int); - -#define EMU_NONE 0x0 - -/* TCP emulations */ -#define EMU_CTL 0x1 -#define EMU_FTP 0x2 -#define EMU_KSH 0x3 -#define EMU_IRC 0x4 -#define EMU_REALAUDIO 0x5 -#define EMU_RLOGIN 0x6 -#define EMU_IDENT 0x7 -#define EMU_RSH 0x8 - -#define EMU_NOCONNECT 0x10 /* Don't connect */ - -/* UDP emulations */ -#define EMU_TALK 0x1 -#define EMU_NTALK 0x2 -#define EMU_CUSEEME 0x3 - -struct tos_t { - u_int16_t lport; - u_int16_t fport; - u_int8_t tos; - u_int8_t emu; -}; - -struct emu_t { - u_int16_t lport; - u_int16_t fport; - u_int8_t tos; - u_int8_t emu; - struct emu_t *next; -}; - -extern struct emu_t *tcpemu; - -extern int x_port, x_server, x_display; - -int show_x(char *, struct socket *); -void redir_x(u_int32_t, int, int, int); -void getouraddr(void); -void slirp_insque(void *, void *); -void slirp_remque(void *); -int add_exec(struct ex_list **, int, char *, int, int); -int slirp_openpty(int *, int *); -int fork_exec(struct socket *, char *, int); -void snooze_hup(int); -void snooze(void); -void relay(int); -void add_emu(char *); -void u_sleep(int); -void fd_nonblock(int); -void fd_block(int); -int rsh_exec(struct socket *, struct socket *, char *, char *, char *); - -#endif diff --git a/BasiliskII/src/slirp/sbuf.c b/BasiliskII/src/slirp/sbuf.c deleted file mode 100644 index 6af075e7..00000000 --- a/BasiliskII/src/slirp/sbuf.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include -#include - -/* Done as a macro in socket.h */ -/* int - * sbspace(struct sockbuff *sb) - * { - * return SB_DATALEN - sb->sb_cc; - * } - */ - -void sbfree(struct sbuf *sb) -{ - free(sb->sb_data); -} - -void sbdrop(struct sbuf *sb, u_int num) -{ - /* - * We can only drop how much we have - * This should never succeed - */ - if(num > sb->sb_cc) - num = sb->sb_cc; - sb->sb_cc -= num; - sb->sb_rptr += num; - if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen) - sb->sb_rptr -= sb->sb_datalen; - -} - -void sbreserve(struct sbuf *sb, size_t size) -{ - if (sb->sb_data) { - /* Already alloced, realloc if necessary */ - if (sb->sb_datalen != size) { - sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)realloc(sb->sb_data, size); - sb->sb_cc = 0; - if (sb->sb_wptr) - sb->sb_datalen = size; - else - sb->sb_datalen = 0; - } - } else { - sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)malloc(size); - sb->sb_cc = 0; - if (sb->sb_wptr) - sb->sb_datalen = size; - else - sb->sb_datalen = 0; - } -} - -/* - * Try and write() to the socket, whatever doesn't get written - * append to the buffer... for a host with a fast net connection, - * this prevents an unnecessary copy of the data - * (the socket is non-blocking, so we won't hang) - */ -void sbappend(struct socket *so, struct mbuf *m) -{ - int ret = 0; - - DEBUG_CALL("sbappend"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("m->m_len = %d", m->m_len); - - /* Shouldn't happen, but... e.g. foreign host closes connection */ - if (m->m_len <= 0) { - m_free(m); - return; - } - - /* - * If there is urgent data, call sosendoob - * if not all was sent, sowrite will take care of the rest - * (The rest of this function is just an optimisation) - */ - if (so->so_urgc) { - sbappendsb(&so->so_rcv, m); - m_free(m); - sosendoob(so); - return; - } - - /* - * We only write if there's nothing in the buffer, - * ottherwise it'll arrive out of order, and hence corrupt - */ - if (!so->so_rcv.sb_cc) - ret = send(so->s, m->m_data, m->m_len, 0); - - if (ret <= 0) { - /* - * Nothing was written - * It's possible that the socket has closed, but - * we don't need to check because if it has closed, - * it will be detected in the normal way by soread() - */ - sbappendsb(&so->so_rcv, m); - } else if (ret != m->m_len) { - /* - * Something was written, but not everything.. - * sbappendsb the rest - */ - m->m_len -= ret; - m->m_data += ret; - sbappendsb(&so->so_rcv, m); - } /* else */ - /* Whatever happened, we free the mbuf */ - m_free(m); -} - -/* - * Copy the data from m into sb - * The caller is responsible to make sure there's enough room - */ -void sbappendsb(struct sbuf *sb, struct mbuf *m) -{ - int len, n, nn; - - len = m->m_len; - - if (sb->sb_wptr < sb->sb_rptr) { - n = sb->sb_rptr - sb->sb_wptr; - if (n > len) n = len; - memcpy(sb->sb_wptr, m->m_data, n); - } else { - /* Do the right edge first */ - n = sb->sb_data + sb->sb_datalen - sb->sb_wptr; - if (n > len) n = len; - memcpy(sb->sb_wptr, m->m_data, n); - len -= n; - if (len) { - /* Now the left edge */ - nn = sb->sb_rptr - sb->sb_data; - if (nn > len) nn = len; - memcpy(sb->sb_data,m->m_data+n,nn); - n += nn; - } - } - - sb->sb_cc += n; - sb->sb_wptr += n; - if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen) - sb->sb_wptr -= sb->sb_datalen; -} - -/* - * Copy data from sbuf to a normal, straight buffer - * Don't update the sbuf rptr, this will be - * done in sbdrop when the data is acked - */ -void sbcopy(struct sbuf *sb, u_int off, u_int len, char *to) -{ - char *from; - - from = sb->sb_rptr + off; - if (from >= sb->sb_data + sb->sb_datalen) - from -= sb->sb_datalen; - - if (from < sb->sb_wptr) { - if (len > sb->sb_cc) len = sb->sb_cc; - memcpy(to,from,len); - } else { - /* re-use off */ - off = (sb->sb_data + sb->sb_datalen) - from; - if (off > len) off = len; - memcpy(to,from,off); - len -= off; - if (len) - memcpy(to+off,sb->sb_data,len); - } -} - diff --git a/BasiliskII/src/slirp/sbuf.h b/BasiliskII/src/slirp/sbuf.h deleted file mode 100644 index 04f7981c..00000000 --- a/BasiliskII/src/slirp/sbuf.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#ifndef _SBUF_H_ -#define _SBUF_H_ - -#include - -#define sbflush(sb) sbdrop((sb),(sb)->sb_cc) -#define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc) - -struct sbuf { - u_int sb_cc; /* actual chars in buffer */ - u_int sb_datalen; /* Length of data */ - char *sb_wptr; /* write pointer. points to where the next - * bytes should be written in the sbuf */ - char *sb_rptr; /* read pointer. points to where the next - * byte should be read from the sbuf */ - char *sb_data; /* Actual data */ -}; - -void sbfree(struct sbuf *); -void sbdrop(struct sbuf *, u_int); -void sbreserve(struct sbuf *, size_t); -void sbappend(struct socket *, struct mbuf *); -void sbappendsb(struct sbuf *, struct mbuf *); -void sbcopy(struct sbuf *, u_int, u_int, char *); - -#endif diff --git a/BasiliskII/src/slirp/slirp.c b/BasiliskII/src/slirp/slirp.c deleted file mode 100644 index d8f2a954..00000000 --- a/BasiliskII/src/slirp/slirp.c +++ /dev/null @@ -1,676 +0,0 @@ -#include "slirp.h" - -/* host address */ -struct in_addr our_addr; -/* host dns address */ -struct in_addr dns_addr; -/* host loopback address */ -struct in_addr loopback_addr; - -/* address for slirp virtual addresses */ -struct in_addr special_addr; -/* virtual address alias for host */ -struct in_addr alias_addr; - -const uint8_t special_ethaddr[6] = { - 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 -}; - -uint8_t client_ethaddr[6]; - -int do_slowtimo; -int link_up; -struct timeval tt; -FILE *lfd; -struct ex_list *exec_list; - -/* XXX: suppress those select globals */ -fd_set *global_readfds, *global_writefds, *global_xfds; - -char slirp_hostname[33]; - -#ifdef _WIN32 - -static int get_dns_addr(struct in_addr *pdns_addr) -{ - FIXED_INFO *FixedInfo=NULL; - ULONG BufLen; - DWORD ret; - IP_ADDR_STRING *pIPAddr; - struct in_addr tmp_addr; - - FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO)); - BufLen = sizeof(FIXED_INFO); - - if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) { - if (FixedInfo) { - GlobalFree(FixedInfo); - FixedInfo = NULL; - } - FixedInfo = GlobalAlloc(GPTR, BufLen); - } - - if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) { - printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret ); - if (FixedInfo) { - GlobalFree(FixedInfo); - FixedInfo = NULL; - } - return -1; - } - - pIPAddr = &(FixedInfo->DnsServerList); - inet_aton(pIPAddr->IpAddress.String, &tmp_addr); - *pdns_addr = tmp_addr; -#if 0 - printf( "DNS Servers:\n" ); - printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String ); - - pIPAddr = FixedInfo -> DnsServerList.Next; - while ( pIPAddr ) { - printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String ); - pIPAddr = pIPAddr ->Next; - } -#endif - if (FixedInfo) { - GlobalFree(FixedInfo); - FixedInfo = NULL; - } - return 0; -} - -#else - -static int get_dns_addr(struct in_addr *pdns_addr) -{ - char buff[512]; - char buff2[256]; - FILE *f; - int found = 0; - struct in_addr tmp_addr; - - f = fopen("/etc/resolv.conf", "r"); - if (!f) - return -1; - - lprint("IP address of your DNS(s): "); - while (fgets(buff, 512, f) != NULL) { - if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) { - if (!inet_aton(buff2, &tmp_addr)) - continue; - if (tmp_addr.s_addr == loopback_addr.s_addr) - tmp_addr = our_addr; - /* If it's the first one, set it to dns_addr */ - if (!found) - *pdns_addr = tmp_addr; - else - lprint(", "); - if (++found > 3) { - lprint("(more)"); - break; - } else - lprint("%s", inet_ntoa(tmp_addr)); - } - } - fclose(f); - if (!found) - return -1; - return 0; -} - -#endif - -#ifdef _WIN32 -void slirp_cleanup(void) -{ - WSACleanup(); -} -#endif - -int slirp_init(void) -{ - // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); - -#ifdef _WIN32 - { - WSADATA Data; - WSAStartup(MAKEWORD(2,0), &Data); - atexit(slirp_cleanup); - } -#endif - - link_up = 1; - - if_init(); - ip_init(); - - /* Initialise mbufs *after* setting the MTU */ - m_init(); - - /* set default addresses */ - inet_aton("127.0.0.1", &loopback_addr); - - if (get_dns_addr(&dns_addr) < 0) - return -1; - - inet_aton(CTL_SPECIAL, &special_addr); - alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); - getouraddr(); - return 0; -} - -#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) -#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) -#define UPD_NFDS(x) if (nfds < (x)) nfds = (x) - -/* - * curtime kept to an accuracy of 1ms - */ -#ifdef _WIN32 -static void updtime(void) -{ - struct _timeb tb; - - _ftime(&tb); - curtime = (u_int)tb.time * (u_int)1000; - curtime += (u_int)tb.millitm; -} -#else -static void updtime(void) -{ - gettimeofday(&tt, 0); - - curtime = (u_int)tt.tv_sec * (u_int)1000; - curtime += (u_int)tt.tv_usec / (u_int)1000; - - if ((tt.tv_usec % 1000) >= 500) - curtime++; -} -#endif - -int slirp_select_fill(int *pnfds, - fd_set *readfds, fd_set *writefds, fd_set *xfds) -{ - struct socket *so, *so_next; - int nfds; - int timeout, tmp_time; - - /* fail safe */ - global_readfds = NULL; - global_writefds = NULL; - global_xfds = NULL; - - nfds = *pnfds; - /* - * First, TCP sockets - */ - do_slowtimo = 0; - if (link_up) { - /* - * *_slowtimo needs calling if there are IP fragments - * in the fragment queue, or there are TCP connections active - */ - do_slowtimo = ((tcb.so_next != &tcb) || - ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next)); - - for (so = tcb.so_next; so != &tcb; so = so_next) { - so_next = so->so_next; - - /* - * See if we need a tcp_fasttimo - */ - if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK) - time_fasttimo = curtime; /* Flag when we want a fasttimo */ - - /* - * NOFDREF can include still connecting to local-host, - * newly socreated() sockets etc. Don't want to select these. - */ - if (so->so_state & SS_NOFDREF || so->s == -1) - continue; - - /* - * Set for reading sockets which are accepting - */ - if (so->so_state & SS_FACCEPTCONN) { - FD_SET(so->s, readfds); - UPD_NFDS(so->s); - continue; - } - - /* - * Set for writing sockets which are connecting - */ - if (so->so_state & SS_ISFCONNECTING) { - FD_SET(so->s, writefds); - UPD_NFDS(so->s); - continue; - } - - /* - * Set for writing if we are connected, can send more, and - * we have something to send - */ - if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) { - FD_SET(so->s, writefds); - UPD_NFDS(so->s); - } - - /* - * Set for reading (and urgent data) if we are connected, can - * receive more, and we have room for it XXX /2 ? - */ - if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) { - FD_SET(so->s, readfds); - FD_SET(so->s, xfds); - UPD_NFDS(so->s); - } - } - - /* - * UDP sockets - */ - for (so = udb.so_next; so != &udb; so = so_next) { - so_next = so->so_next; - - /* - * See if it's timed out - */ - if (so->so_expire) { - if (so->so_expire <= curtime) { - udp_detach(so); - continue; - } else - do_slowtimo = 1; /* Let socket expire */ - } - - /* - * When UDP packets are received from over the - * link, they're sendto()'d straight away, so - * no need for setting for writing - * Limit the number of packets queued by this session - * to 4. Note that even though we try and limit this - * to 4 packets, the session could have more queued - * if the packets needed to be fragmented - * (XXX <= 4 ?) - */ - if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) { - FD_SET(so->s, readfds); - UPD_NFDS(so->s); - } - } - } - - /* - * Setup timeout to use minimum CPU usage, especially when idle - */ - - timeout = -1; - - /* - * If a slowtimo is needed, set timeout to 5ms from the last - * slow timeout. If a fast timeout is needed, set timeout within - * 2ms of when it was requested. - */ -# define SLOW_TIMO 5 -# define FAST_TIMO 2 - if (do_slowtimo) { - timeout = (SLOW_TIMO - (curtime - last_slowtimo)) * 1000; - if (timeout < 0) - timeout = 0; - else if (timeout > (SLOW_TIMO * 1000)) - timeout = SLOW_TIMO * 1000; - - /* Can only fasttimo if we also slowtimo */ - if (time_fasttimo) { - tmp_time = (FAST_TIMO - (curtime - time_fasttimo)) * 1000; - if (tmp_time < 0) - tmp_time = 0; - - /* Choose the smallest of the 2 */ - if (tmp_time < timeout) - timeout = tmp_time; - } - } - *pnfds = nfds; - - /* - * Adjust the timeout to make the minimum timeout - * 2ms (XXX?) to lessen the CPU load - */ - if (timeout < (FAST_TIMO * 1000)) - timeout = FAST_TIMO * 1000; - - return timeout; -} - -void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) -{ - struct socket *so, *so_next; - int ret; - - global_readfds = readfds; - global_writefds = writefds; - global_xfds = xfds; - - /* Update time */ - updtime(); - - /* - * See if anything has timed out - */ - if (link_up) { - if (time_fasttimo && ((curtime - time_fasttimo) >= FAST_TIMO)) { - tcp_fasttimo(); - time_fasttimo = 0; - } - if (do_slowtimo && ((curtime - last_slowtimo) >= SLOW_TIMO)) { - ip_slowtimo(); - tcp_slowtimo(); - last_slowtimo = curtime; - } - } - - /* - * Check sockets - */ - if (link_up) { - /* - * Check TCP sockets - */ - for (so = tcb.so_next; so != &tcb; so = so_next) { - so_next = so->so_next; - - /* - * FD_ISSET is meaningless on these sockets - * (and they can crash the program) - */ - if (so->so_state & SS_NOFDREF || so->s == -1) - continue; - - /* - * Check for URG data - * This will soread as well, so no need to - * test for readfds below if this succeeds - */ - if (FD_ISSET(so->s, xfds)) - sorecvoob(so); - /* - * Check sockets for reading - */ - else if (FD_ISSET(so->s, readfds)) { - /* - * Check for incoming connections - */ - if (so->so_state & SS_FACCEPTCONN) { - tcp_connect(so); - continue; - } /* else */ - ret = soread(so); - - /* Output it if we read something */ - if (ret > 0) - tcp_output(sototcpcb(so)); - } - - /* - * Check sockets for writing - */ - if (FD_ISSET(so->s, writefds)) { - /* - * Check for non-blocking, still-connecting sockets - */ - if (so->so_state & SS_ISFCONNECTING) { - /* Connected */ - so->so_state &= ~SS_ISFCONNECTING; - - ret = send(so->s, (char*)&ret, 0, 0); - if (ret < 0) { - /* XXXXX Must fix, zero bytes is a NOP */ - int error = WSAGetLastError(); - if (error == EAGAIN || error == WSAEWOULDBLOCK || - error == WSAEINPROGRESS || error == WSAENOTCONN) - continue; - - /* else failed */ - so->so_state = SS_NOFDREF; - } - /* else so->so_state &= ~SS_ISFCONNECTING; */ - - /* - * Continue tcp_input - */ - tcp_input((struct mbuf *)NULL, sizeof(struct ip), so); - /* continue; */ - } - else - ret = sowrite(so); - /* - * XXXXX If we wrote something (a lot), there - * could be a need for a window update. - * In the worst case, the remote will send - * a window probe to get things going again - */ - } - - /* - * Probe a still-connecting, non-blocking socket - * to check if it's still alive - */ -#ifdef PROBE_CONN - if (so->so_state & SS_ISFCONNECTING) { - ret = recv(so->s, (char *)&ret, 0, 0); - - if (ret < 0) { - /* XXX */ - int error = WSAGetLastError(); - if (error == EAGAIN || error == WSAEWOULDBLOCK || - error == WSAEINPROGRESS || error == WSAENOTCONN) - continue; /* Still connecting, continue */ - - /* else failed */ - so->so_state = SS_NOFDREF; - - /* tcp_input will take care of it */ - } - else { - ret = send(so->s, &ret, 0, 0); - if (ret < 0) { - /* XXX */ - int error = WSAGetLastError(); - if (error == EAGAIN || error == WSAEWOULDBLOCK || - error == WSAEINPROGRESS || error == WSAENOTCONN) - continue; - /* else failed */ - so->so_state = SS_NOFDREF; - } - else - so->so_state &= ~SS_ISFCONNECTING; - - } - tcp_input((struct mbuf *)NULL, sizeof(struct ip), so); - } /* SS_ISFCONNECTING */ -#endif - } - - /* - * Now UDP sockets. - * Incoming packets are sent straight away, they're not buffered. - * Incoming UDP data isn't buffered either. - */ - for (so = udb.so_next; so != &udb; so = so_next) { - so_next = so->so_next; - - if (so->s != -1 && FD_ISSET(so->s, readfds)) { - sorecvfrom(so); - } - } -} - - /* - * See if we can start outputting - */ - if (if_queued && link_up) - if_start(); - - /* clear global file descriptor sets. - * these reside on the stack in vl.c - * so they're unusable if we're not in - * slirp_select_fill or slirp_select_poll. - */ - global_readfds = NULL; - global_writefds = NULL; - global_xfds = NULL; -} - -#define ETH_ALEN 6 -#define ETH_HLEN 14 - -#define ETH_P_IP 0x0800 /* Internet Protocol packet */ -#define ETH_P_ARP 0x0806 /* Address Resolution packet */ - -#define ARPOP_REQUEST 1 /* ARP request */ -#define ARPOP_REPLY 2 /* ARP reply */ - -struct ethhdr -{ - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - unsigned short h_proto; /* packet type ID field */ -}; - -struct arphdr -{ - unsigned short ar_hrd; /* format of hardware address */ - unsigned short ar_pro; /* format of protocol address */ - unsigned char ar_hln; /* length of hardware address */ - unsigned char ar_pln; /* length of protocol address */ - unsigned short ar_op; /* ARP opcode (command) */ - - /* - * Ethernet looks like this : This bit is variable sized however... - */ - unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ - unsigned char ar_sip[4]; /* sender IP address */ - unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ - unsigned char ar_tip[4]; /* target IP address */ -}; - -void arp_input(const uint8_t *pkt, int pkt_len) -{ - struct ethhdr *eh = (struct ethhdr *)pkt; - struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN); - uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)]; - struct ethhdr *reh = (struct ethhdr *)arp_reply; - struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN); - int ar_op; - struct ex_list *ex_ptr; - - ar_op = ntohs(ah->ar_op); - switch(ar_op) { - case ARPOP_REQUEST: - if (!memcmp(ah->ar_tip, &special_addr, 3)) { - if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS) - goto arp_ok; - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->ex_addr == ah->ar_tip[3]) - goto arp_ok; - } - return; - arp_ok: - /* XXX: make an ARP request to have the client address */ - memcpy(client_ethaddr, eh->h_source, ETH_ALEN); - - /* ARP request for alias/dns mac address */ - memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN); - memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1); - reh->h_source[5] = ah->ar_tip[3]; - reh->h_proto = htons(ETH_P_ARP); - - rah->ar_hrd = htons(1); - rah->ar_pro = htons(ETH_P_IP); - rah->ar_hln = ETH_ALEN; - rah->ar_pln = 4; - rah->ar_op = htons(ARPOP_REPLY); - memcpy(rah->ar_sha, reh->h_source, ETH_ALEN); - memcpy(rah->ar_sip, ah->ar_tip, 4); - memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN); - memcpy(rah->ar_tip, ah->ar_sip, 4); - slirp_output(arp_reply, sizeof(arp_reply)); - } - break; - default: - break; - } -} - -void slirp_input(const uint8_t *pkt, int pkt_len) -{ - struct mbuf *m; - int proto; - - if (pkt_len < ETH_HLEN) - return; - - proto = (pkt[12] << 8) | pkt[13]; - switch(proto) { - case ETH_P_ARP: - arp_input(pkt, pkt_len); - break; - case ETH_P_IP: - m = m_get(); - if (!m) - return; - /* Note: we add to align the IP header */ - m->m_len = pkt_len + 2; - memcpy(m->m_data + 2, pkt, pkt_len); - - m->m_data += 2 + ETH_HLEN; - m->m_len -= 2 + ETH_HLEN; - - ip_input(m); - break; - default: - break; - } -} - -/* output the IP packet to the ethernet device */ -void if_encap(const uint8_t *ip_data, int ip_data_len) -{ - uint8_t buf[1600]; - struct ethhdr *eh = (struct ethhdr *)buf; - - if (ip_data_len + ETH_HLEN > sizeof(buf)) - return; - - memcpy(eh->h_dest, client_ethaddr, ETH_ALEN); - memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1); - /* XXX: not correct */ - eh->h_source[5] = CTL_ALIAS; - eh->h_proto = htons(ETH_P_IP); - memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len); - slirp_output(buf, ip_data_len + ETH_HLEN); -} - -int slirp_redir(int is_udp, int host_port, - struct in_addr guest_addr, int guest_port) -{ - if (is_udp) { - if (!udp_listen(htons(host_port), guest_addr.s_addr, - htons(guest_port), 0)) - return -1; - } else { - if (!solisten(htons(host_port), guest_addr.s_addr, - htons(guest_port), 0)) - return -1; - } - return 0; -} - -int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, - int guest_port) -{ - return add_exec(&exec_list, do_pty, (char *)args, - addr_low_byte, htons(guest_port)); -} diff --git a/BasiliskII/src/slirp/slirp.h b/BasiliskII/src/slirp/slirp.h deleted file mode 100644 index b845caa7..00000000 --- a/BasiliskII/src/slirp/slirp.h +++ /dev/null @@ -1,358 +0,0 @@ -#ifndef __COMMON_H__ -#define __COMMON_H__ - -#define CONFIG_QEMU - -#define DEBUG 1 - -#ifndef CONFIG_QEMU -#include "version.h" -#endif -#include "config.h" -#include "slirp_config.h" - -#ifdef _WIN32 -# include - -typedef uint8_t u_int8_t; -typedef uint16_t u_int16_t; -typedef uint32_t u_int32_t; -typedef uint64_t u_int64_t; -typedef char *caddr_t; -typedef int socklen_t; -typedef unsigned long ioctlsockopt_t; - -# include -# include -# include -# include - -# define USE_FIONBIO 1 - -/* Basilisk II Router defines those */ -# define udp_read_completion slirp_udp_read_completion -# define write_udp slirp_write_udp -# define init_udp slirp_init_udp -# define final_udp slirp_final_udp -#else -# define WSAGetLastError() (int)(errno) -# define WSASetLastError(e) (void)(errno = (e)) -# define WSAEWOULDBLOCK EWOULDBLOCK -# define WSAEINPROGRESS EINPROGRESS -# define WSAENOTCONN ENOTCONN -# define WSAEHOSTUNREACH EHOSTUNREACH -# define WSAENETUNREACH ENETUNREACH -# define WSAECONNREFUSED ECONNREFUSED -typedef int ioctlsockopt_t; -# define ioctlsocket ioctl -# define closesocket(s) close(s) -# define O_BINARY 0 -#endif - -#include -#ifdef HAVE_SYS_BITYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif - -#ifndef _WIN32 -#include -#endif - -#ifdef NEED_TYPEDEFS -typedef char int8_t; -typedef unsigned char u_int8_t; - -# if SIZEOF_SHORT == 2 - typedef short int16_t; - typedef unsigned short u_int16_t; -# else -# if SIZEOF_INT == 2 - typedef int int16_t; - typedef unsigned int u_int16_t; -# else - #error Cannot find a type with sizeof() == 2 -# endif -# endif - -# if SIZEOF_SHORT == 4 - typedef short int32_t; - typedef unsigned short u_int32_t; -# else -# if SIZEOF_INT == 4 - typedef int int32_t; - typedef unsigned int u_int32_t; -# else - #error Cannot find a type with sizeof() == 4 -# endif -# endif -#endif /* NEED_TYPEDEFS */ - -/* Basilisk II types glue */ -typedef u_int8_t uint8; -typedef u_int16_t uint16; -typedef u_int32_t uint32; - -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef HAVE_STDLIB_H -# include -#endif - -#include -#include - -#ifndef HAVE_MEMMOVE -#define memmove(x, y, z) bcopy(y, x, z) -#endif - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#ifdef HAVE_STRING_H -# include -#else -# include -#endif - -#ifndef _WIN32 -#include -#include -#include -#endif - -#ifdef GETTIMEOFDAY_ONE_ARG -#define gettimeofday(x, y) gettimeofday(x) -#endif - -/* Systems lacking strdup() definition in . */ -#if defined(ultrix) -char *strdup(const char *); -#endif - -/* Systems lacking malloc() definition in . */ -#if defined(ultrix) || defined(hcx) -void *malloc(size_t arg); -void free(void *ptr); -#endif - -#ifndef HAVE_INET_ATON -int inet_aton(const char *cp, struct in_addr *ia); -#endif - -#include -#ifdef _WIN32 -#include -#endif -#ifndef NO_UNIX_SOCKETS -#include -#endif -#include -#ifdef HAVE_SYS_SIGNAL_H -# include -#endif -#ifndef _WIN32 -#include -#endif - -#if defined(HAVE_SYS_IOCTL_H) -# include -#endif - -#ifdef HAVE_SYS_SELECT_H -# include -#endif - -#ifdef HAVE_SYS_WAIT_H -# include -#endif - -#ifdef HAVE_SYS_FILIO_H -# include -#endif - -#ifdef USE_PPP -#include -#endif - -#include - -#include - -/* Avoid conflicting with the libc insque() and remque(), which - have different prototypes. */ -#define insque slirp_insque -#define remque slirp_remque - -#ifdef HAVE_SYS_STROPTS_H -#include -#endif - -#include "debug.h" - -#if defined __GNUC__ -#define PACKED__ __attribute__ ((packed)) -#elif defined _MSC_VER -#define PRAGMA_PACK_SUPPORTED 1 -#define PACK_RESET -#define PACKED__ -#elif defined __sgi -#define PRAGMA_PACK_SUPPORTED 1 -#define PACK_RESET 0 -#define PACKED__ -#else -#error "Packed attribute or pragma shall be supported" -#endif - -#include "ip.h" -#include "tcp.h" -#include "tcp_timer.h" -#include "tcp_var.h" -#include "tcpip.h" -#include "udp.h" -#include "icmp_var.h" -#include "mbuf.h" -#include "sbuf.h" -#include "socket.h" -#include "if.h" -#include "main.h" -#include "misc.h" -#include "ctl.h" -#ifdef USE_PPP -#include "ppp/pppd.h" -#include "ppp/ppp.h" -#endif - -#include "bootp.h" -#include "tftp.h" -#include "libslirp.h" - -extern struct ttys *ttys_unit[MAX_INTERFACES]; - -#ifndef NULL -#define NULL (void *)0 -#endif - -#ifndef FULL_BOLT -void if_start(void); -#else -void if_start(struct ttys *); -#endif - -#ifdef BAD_SPRINTF -# define vsprintf vsprintf_len -# define sprintf sprintf_len - extern int vsprintf_len(char *, const char *, va_list); - extern int sprintf_len(char *, const char *, ...); -#endif - -#ifdef DECLARE_SPRINTF -# ifndef BAD_SPRINTF - extern int vsprintf(char *, const char *, va_list); -# endif - extern int vfprintf(FILE *, const char *, va_list); -#endif - -#ifndef HAVE_STRERROR - extern char *strerror(int error); -#endif - -#ifndef HAVE_INDEX - char *index(const char *, int); -#endif - -#ifndef HAVE_GETHOSTID - long gethostid(void); -#endif - -void lprint(const char *, ...); - -extern int do_echo; - -#if SIZEOF_CHAR_P == 4 -# define insque_32 insque -# define remque_32 remque -#else - extern inline void insque_32(void *, void *); - extern inline void remque_32(void *); -#endif - -#ifndef _WIN32 -#include -#endif - -#define DEFAULT_BAUD 115200 - -/* cksum.c */ -int cksum(struct mbuf *m, int len); - -/* if.c */ -void if_init(void); -void if_output(struct socket *, struct mbuf *); - -/* ip_input.c */ -void ip_init(void); -void ip_input(struct mbuf *); -struct ip * ip_reass(register struct ipasfrag *, register struct ipq *); -void ip_freef(struct ipq *); -void ip_enq(register struct ipasfrag *, register struct ipasfrag *); -void ip_deq(register struct ipasfrag *); -void ip_slowtimo(void); -void ip_stripoptions(register struct mbuf *, struct mbuf *); - -/* ip_output.c */ -int ip_output(struct socket *, struct mbuf *); - -/* tcp_input.c */ -int tcp_reass(register struct tcpcb *, register struct tcpiphdr *, struct mbuf *); -void tcp_input(register struct mbuf *, int, struct socket *); -void tcp_dooptions(struct tcpcb *, u_char *, int, struct tcpiphdr *); -void tcp_xmit_timer(register struct tcpcb *, int); -u_int tcp_mss(register struct tcpcb *, u_int); - -/* tcp_output.c */ -int tcp_output(register struct tcpcb *); -void tcp_setpersist(register struct tcpcb *); - -/* tcp_subr.c */ -void tcp_init(void); -void tcp_template(struct tcpcb *); -void tcp_respond(struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int); -struct tcpcb * tcp_newtcpcb(struct socket *); -struct tcpcb * tcp_close(register struct tcpcb *); -void tcp_drain(void); -void tcp_sockclosed(struct tcpcb *); -int tcp_fconnect(struct socket *); -void tcp_connect(struct socket *); -int tcp_attach(struct socket *); -u_int8_t tcp_tos(struct socket *); -int tcp_emu(struct socket *, struct mbuf *); -int tcp_ctl(struct socket *); -struct tcpcb *tcp_drop(struct tcpcb *tp, int err); - -#ifdef USE_PPP -#define MIN_MRU MINMRU -#define MAX_MRU MAXMRU -#else -#define MIN_MRU 128 -#define MAX_MRU 16384 -#endif - -#ifndef _WIN32 -#define min(x,y) ((x) < (y) ? (x) : (y)) -#define max(x,y) ((x) > (y) ? (x) : (y)) -#endif - -#endif diff --git a/BasiliskII/src/slirp/slirp_config.h b/BasiliskII/src/slirp/slirp_config.h deleted file mode 100644 index 237268fa..00000000 --- a/BasiliskII/src/slirp/slirp_config.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * User definable configuration options - */ - -/* Undefine if you don't want talk emulation */ -#undef EMULATE_TALK - -/* Define if you want the connection to be probed */ -/* XXX Not working yet, so ignore this for now */ -#undef PROBE_CONN - -/* Define to 1 if you want KEEPALIVE timers */ -#define DO_KEEPALIVE 0 - -/* Define to MAX interfaces you expect to use at once */ -/* MAX_INTERFACES determines the max. TOTAL number of interfaces (SLIP and PPP) */ -/* MAX_PPP_INTERFACES determines max. number of PPP interfaces */ -#define MAX_INTERFACES 1 -#define MAX_PPP_INTERFACES 1 - -/* Define if you want slirp's socket in /tmp */ -/* XXXXXX Do this in ./configure */ -#undef USE_TMPSOCKET - -/* Define if you want slirp to use cfsetXspeed() on the terminal */ -#undef DO_CFSETSPEED - -/* Define this if you want slirp to write to the tty as fast as it can */ -/* This should only be set if you are using load-balancing, slirp does a */ -/* pretty good job on single modems already, and seting this will make */ -/* interactive sessions less responsive */ -/* XXXXX Talk about having fast modem as unit 0 */ -#undef FULL_BOLT - -/* - * Define if you want slirp to use less CPU - * You will notice a small lag in interactive sessions, but it's not that bad - * Things like Netscape/ftp/etc. are completely unaffected - * This is mainly for sysadmins who have many slirp users - */ -#undef USE_LOWCPU - -/*********************************************************/ -/* - * Autoconf defined configuration options - * You shouldn't need to touch any of these - */ - -/* Ignore this */ -#undef DUMMY_PPP - -/* XXX: Define according to how time.h should be included */ -#undef TIME_WITH_SYS_TIME -#define TIME_WITH_SYS_TIME 0 -#undef HAVE_SYS_TIME_H - -/* Define if your sprintf returns char * instead of int */ -#undef BAD_SPRINTF - -/* Define if you have readv */ -#undef HAVE_READV - -/* Define if iovec needs to be declared */ -#undef DECLARE_IOVEC -#ifdef _WIN32 -#define DECLARE_IOVEC -#endif - -/* Define if a declaration of sprintf/fprintf is needed */ -#undef DECLARE_SPRINTF - -/* Define if you have sys/stropts.h */ -#undef HAVE_SYS_STROPTS_H - -/* Define if you don't have u_int32_t etc. typedef'd */ -#undef NEED_TYPEDEFS -#ifdef __sun__ -#define NEED_TYPEDEFS -#endif - -/* Define to sizeof(char *) */ -#define SIZEOF_CHAR_P SIZEOF_VOID_P - -/* Define if you have random() */ -#undef HAVE_RANDOM - -/* Define if you have srandom() */ -#undef HAVE_SRANDOM - -/* Define if you have setenv */ -#undef HAVE_SETENV - -/* Define if you have index() */ -#undef HAVE_INDEX - -/* Define if you have bcmp() */ -#undef HAVE_BCMP - -/* Define if you have drand48 */ -#undef HAVE_DRAND48 - -/* Define if you have memmove */ -#define HAVE_MEMMOVE - -/* Define if you have gethostid */ -#undef HAVE_GETHOSTID - -/* Define if you DON'T have unix-domain sockets */ -#undef NO_UNIX_SOCKETS -#ifdef _WIN32 -#define NO_UNIX_SOCKETS -#endif - -/* Define if gettimeofday only takes one argument */ -#undef GETTIMEOFDAY_ONE_ARG - -/* Define if you have revoke() */ -#undef HAVE_REVOKE - -/* Define if you have the sysv method of opening pty's (/dev/ptmx, etc.) */ -#undef HAVE_GRANTPT - -/* Define if you have fchmod */ -#undef HAVE_FCHMOD - -/* Define if you have */ -#undef HAVE_SYS_TYPES32_H diff --git a/BasiliskII/src/slirp/socket.c b/BasiliskII/src/slirp/socket.c deleted file mode 100644 index 2c0e067e..00000000 --- a/BasiliskII/src/slirp/socket.c +++ /dev/null @@ -1,733 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#define WANT_SYS_IOCTL_H -#include -#include -#include "ip_icmp.h" -#include "main.h" -#ifdef __sun__ -#include -#endif - -#ifdef _WIN32 -#define IS_EAGAIN(e) ((e) == WSAEINTR || (e) == EAGAIN) -#else -#define IS_EAGAIN(e) ((e) == EAGAIN) -#endif - -void -so_init() -{ - /* Nothing yet */ -} - - -struct socket * -solookup(head, laddr, lport, faddr, fport) - struct socket *head; - struct in_addr laddr; - u_int lport; - struct in_addr faddr; - u_int fport; -{ - struct socket *so; - - for (so = head->so_next; so != head; so = so->so_next) { - if (so->so_lport == lport && - so->so_laddr.s_addr == laddr.s_addr && - so->so_faddr.s_addr == faddr.s_addr && - so->so_fport == fport) - break; - } - - if (so == head) - return (struct socket *)NULL; - return so; - -} - -/* - * Create a new socket, initialise the fields - * It is the responsibility of the caller to - * insque() it into the correct linked-list - */ -struct socket * -socreate() -{ - struct socket *so; - - so = (struct socket *)malloc(sizeof(struct socket)); - if(so) { - memset(so, 0, sizeof(struct socket)); - so->so_state = SS_NOFDREF; - so->s = -1; - } - return(so); -} - -/* - * remque and free a socket, clobber cache - */ -void -sofree(so) - struct socket *so; -{ - if (so->so_emu==EMU_RSH && so->extra) { - sofree(so->extra); - so->extra=NULL; - } - if (so == tcp_last_so) - tcp_last_so = &tcb; - else if (so == udp_last_so) - udp_last_so = &udb; - - m_free(so->so_m); - - if(so->so_next && so->so_prev) - remque(so); /* crashes if so is not in a queue */ - - free(so); -} - -/* - * Read from so's socket into sb_snd, updating all relevant sbuf fields - * NOTE: This will only be called if it is select()ed for reading, so - * a read() of 0 (or less) means it's disconnected - */ -int -soread(so) - struct socket *so; -{ - int n, nn; - u_int lss, total; - struct sbuf *sb = &so->so_snd; - u_int len = sb->sb_datalen - sb->sb_cc; - struct iovec iov[2]; - u_int mss = so->so_tcpcb->t_maxseg; - - DEBUG_CALL("soread"); - DEBUG_ARG("so = %lx", (long )so); - - /* - * No need to check if there's enough room to read. - * soread wouldn't have been called if there weren't - */ - - len = sb->sb_datalen - sb->sb_cc; - - iov[0].iov_base = sb->sb_wptr; - if (sb->sb_wptr < sb->sb_rptr) { - iov[0].iov_len = sb->sb_rptr - sb->sb_wptr; - /* Should never succeed, but... */ - if (iov[0].iov_len > len) - iov[0].iov_len = len; - if (iov[0].iov_len > mss) - iov[0].iov_len -= iov[0].iov_len%mss; - n = 1; - } else { - iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr; - /* Should never succeed, but... */ - if (iov[0].iov_len > len) iov[0].iov_len = len; - len -= iov[0].iov_len; - if (len) { - iov[1].iov_base = sb->sb_data; - iov[1].iov_len = sb->sb_rptr - sb->sb_data; - if(iov[1].iov_len > len) - iov[1].iov_len = len; - total = iov[0].iov_len + iov[1].iov_len; - if (total > mss) { - lss = total%mss; - if (iov[1].iov_len > lss) { - iov[1].iov_len -= lss; - n = 2; - } else { - lss -= iov[1].iov_len; - iov[0].iov_len -= lss; - n = 1; - } - } else - n = 2; - } else { - if (iov[0].iov_len > mss) - iov[0].iov_len -= iov[0].iov_len%mss; - n = 1; - } - } - -#ifdef HAVE_READV - nn = readv(so->s, (struct iovec *)iov, n); - DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); -#else - nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0); -#endif - if (nn <= 0) { - int error = WSAGetLastError(); - if (nn < 0 && IS_EAGAIN(error)) - return 0; - else { - DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno))); - sofcantrcvmore(so); - tcp_sockclosed(sototcpcb(so)); - return -1; - } - } - -#ifndef HAVE_READV - /* - * If there was no error, try and read the second time round - * We read again if n = 2 (ie, there's another part of the buffer) - * and we read as much as we could in the first read - * We don't test for <= 0 this time, because there legitimately - * might not be any more data (since the socket is non-blocking), - * a close will be detected on next iteration. - * A return of -1 wont (shouldn't) happen, since it didn't happen above - */ - if (n == 2 && nn == iov[0].iov_len) { - int ret; - ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0); - if (ret > 0) - nn += ret; - } - - DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); -#endif - - /* Update fields */ - sb->sb_cc += nn; - sb->sb_wptr += nn; - if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen)) - sb->sb_wptr -= sb->sb_datalen; - return nn; -} - -/* - * Get urgent data - * - * When the socket is created, we set it SO_OOBINLINE, - * so when OOB data arrives, we soread() it and everything - * in the send buffer is sent as urgent data - */ -void -sorecvoob(so) - struct socket *so; -{ - struct tcpcb *tp = sototcpcb(so); - - DEBUG_CALL("sorecvoob"); - DEBUG_ARG("so = %lx", (long)so); - - /* - * We take a guess at how much urgent data has arrived. - * In most situations, when urgent data arrives, the next - * read() should get all the urgent data. This guess will - * be wrong however if more data arrives just after the - * urgent data, or the read() doesn't return all the - * urgent data. - */ - soread(so); - tp->snd_up = tp->snd_una + so->so_snd.sb_cc; - tp->t_force = 1; - tcp_output(tp); - tp->t_force = 0; -} - -/* - * Send urgent data - * There's a lot duplicated code here, but... - */ -int -sosendoob(so) - struct socket *so; -{ - struct sbuf *sb = &so->so_rcv; - char buff[2048]; /* XXX Shouldn't be sending more oob data than this */ - - int n, len; - - DEBUG_CALL("sosendoob"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc); - - if (so->so_urgc > 2048) - so->so_urgc = 2048; /* XXXX */ - - if (sb->sb_rptr < sb->sb_wptr) { - /* We can send it directly */ - n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */ - so->so_urgc -= n; - - DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc)); - } else { - /* - * Since there's no sendv or sendtov like writev, - * we must copy all data to a linear buffer then - * send it all - */ - len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr; - if (len > so->so_urgc) len = so->so_urgc; - memcpy(buff, sb->sb_rptr, len); - so->so_urgc -= len; - if (so->so_urgc) { - n = sb->sb_wptr - sb->sb_data; - if (n > so->so_urgc) n = so->so_urgc; - memcpy((buff + len), sb->sb_data, n); - so->so_urgc -= n; - len += n; - } - n = send(so->s, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */ -#ifdef DEBUG - if (n != len) - DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n")); -#endif - DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc)); - } - - sb->sb_cc -= n; - sb->sb_rptr += n; - if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) - sb->sb_rptr -= sb->sb_datalen; - - return n; -} - -/* - * Write data from so_rcv to so's socket, - * updating all sbuf field as necessary - */ -int -sowrite(so) - struct socket *so; -{ - int n,nn; - struct sbuf *sb = &so->so_rcv; - u_int len = sb->sb_cc; - struct iovec iov[2]; - - DEBUG_CALL("sowrite"); - DEBUG_ARG("so = %lx", (long)so); - - if (so->so_urgc) { - sosendoob(so); - if (sb->sb_cc == 0) - return 0; - } - - /* - * No need to check if there's something to write, - * sowrite wouldn't have been called otherwise - */ - - len = sb->sb_cc; - - iov[0].iov_base = sb->sb_rptr; - if (sb->sb_rptr < sb->sb_wptr) { - iov[0].iov_len = sb->sb_wptr - sb->sb_rptr; - /* Should never succeed, but... */ - if (iov[0].iov_len > len) iov[0].iov_len = len; - n = 1; - } else { - iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr; - if (iov[0].iov_len > len) iov[0].iov_len = len; - len -= iov[0].iov_len; - if (len) { - iov[1].iov_base = sb->sb_data; - iov[1].iov_len = sb->sb_wptr - sb->sb_data; - if (iov[1].iov_len > len) iov[1].iov_len = len; - n = 2; - } else - n = 1; - } - /* Check if there's urgent data to send, and if so, send it */ - -#ifdef HAVE_READV - nn = writev(so->s, (const struct iovec *)iov, n); - - DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); -#else - nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0); -#endif - /* This should never happen, but people tell me it does *shrug* */ - if (nn < 0) { - int error = WSAGetLastError(); - if (IS_EAGAIN(error)) - return 0; - } - - if (nn <= 0) { - DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n", - so->so_state, errno)); - sofcantsendmore(so); - tcp_sockclosed(sototcpcb(so)); - return -1; - } - -#ifndef HAVE_READV - if (n == 2 && nn == iov[0].iov_len) { - int ret; - ret = send(so->s, iov[1].iov_base, iov[1].iov_len,0); - if (ret > 0) - nn += ret; - } - DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); -#endif - - /* Update sbuf */ - sb->sb_cc -= nn; - sb->sb_rptr += nn; - if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) - sb->sb_rptr -= sb->sb_datalen; - - /* - * If in DRAIN mode, and there's no more data, set - * it CANTSENDMORE - */ - if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0) - sofcantsendmore(so); - - return nn; -} - -/* - * recvfrom() a UDP socket - */ -void -sorecvfrom(so) - struct socket *so; -{ - struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr_in); - - DEBUG_CALL("sorecvfrom"); - DEBUG_ARG("so = %lx", (long)so); - - if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */ - char buff[256]; - int len; - - len = recvfrom(so->s, buff, 256, 0, - (struct sockaddr *)&addr, &addrlen); - /* XXX Check if reply is "correct"? */ - - if(len == -1 || len == 0) { - u_char code=ICMP_UNREACH_PORT; - - int error = WSAGetLastError(); - if(error == WSAEHOSTUNREACH) code=ICMP_UNREACH_HOST; - else if(error == WSAENETUNREACH) code=ICMP_UNREACH_NET; - - DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n", - errno,strerror(errno))); - icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); - } else { - icmp_reflect(so->so_m); - so->so_m = 0; /* Don't m_free() it again! */ - } - /* No need for this socket anymore, udp_detach it */ - udp_detach(so); - } else { /* A "normal" UDP packet */ - struct mbuf *m; - u_int len; - ioctlsockopt_t n; - - if (!(m = m_get())) return; - m->m_data += if_maxlinkhdr; - - /* - * XXX Shouldn't FIONREAD packets destined for port 53, - * but I don't know the max packet size for DNS lookups - */ - len = M_FREEROOM(m); - /* if (so->so_fport != htons(53)) { */ - ioctlsocket(so->s, FIONREAD, &n); - - if (n > len) { - n = (m->m_data - m->m_dat) + m->m_len + n + 1; - m_inc(m, n); - len = M_FREEROOM(m); - } - /* } */ - - m->m_len = recvfrom(so->s, m->m_data, len, 0, - (struct sockaddr *)&addr, &addrlen); - DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n", - m->m_len, errno,strerror(errno))); - if(m->m_len<0) { - u_char code=ICMP_UNREACH_PORT; - - int error = WSAGetLastError(); - if(error == WSAEHOSTUNREACH) code=ICMP_UNREACH_HOST; - else if(error == WSAENETUNREACH) code=ICMP_UNREACH_NET; - - DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code)); - icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); - m_free(m); - } else { - /* - * Hack: domain name lookup will be used the most for UDP, - * and since they'll only be used once there's no need - * for the 4 minute (or whatever) timeout... So we time them - * out much quicker (10 seconds for now...) - */ - if (so->so_expire) { - if (so->so_fport == htons(53)) - so->so_expire = curtime + SO_EXPIREFAST; - else - so->so_expire = curtime + SO_EXPIRE; - } - - /* if (m->m_len == len) { - * m_inc(m, MINCSIZE); - * m->m_len = 0; - * } - */ - - /* - * If this packet was destined for CTL_ADDR, - * make it look like that's where it came from, done by udp_output - */ - udp_output(so, m, &addr); - } /* rx error */ - } /* if ping packet */ -} - -/* - * sendto() a socket - */ -int -sosendto(so, m) - struct socket *so; - struct mbuf *m; -{ - int ret; - struct sockaddr_in addr; - - DEBUG_CALL("sosendto"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("m = %lx", (long)m); - - addr.sin_family = AF_INET; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { - /* It's an alias */ - switch(ntohl(so->so_faddr.s_addr) & 0xff) { - case CTL_DNS: - addr.sin_addr = dns_addr; - break; - case CTL_ALIAS: - default: - addr.sin_addr = loopback_addr; - break; - } - } else - addr.sin_addr = so->so_faddr; - addr.sin_port = so->so_fport; - - char addrstr[INET_ADDRSTRLEN]; - DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", - ntohs(addr.sin_port), inet_ntop(AF_INET, &addr.sin_addr, addrstr, sizeof(addrstr)))); - - /* Don't care what port we get */ - ret = sendto(so->s, m->m_data, m->m_len, 0, - (struct sockaddr *)&addr, sizeof (struct sockaddr)); - if (ret < 0) - return -1; - - /* - * Kill the socket if there's no reply in 4 minutes, - * but only if it's an expirable socket - */ - if (so->so_expire) - so->so_expire = curtime + SO_EXPIRE; - so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */ - return 0; -} - -/* - * XXX This should really be tcp_listen - */ -struct socket * -solisten(port, laddr, lport, flags) - u_int port; - u_int32_t laddr; - u_int lport; - int flags; -{ - struct sockaddr_in addr; - struct socket *so; - int s; - socklen_t addrlen = sizeof(addr); - int opt = 1; - - DEBUG_CALL("solisten"); - DEBUG_ARG("port = %d", port); - DEBUG_ARG("laddr = %x", laddr); - DEBUG_ARG("lport = %d", lport); - DEBUG_ARG("flags = %x", flags); - - if ((so = socreate()) == NULL) { - /* free(so); Not sofree() ??? free(NULL) == NOP */ - return NULL; - } - - /* Don't tcp_attach... we don't need so_snd nor so_rcv */ - if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) { - free(so); - return NULL; - } - insque(so,&tcb); - - /* - * SS_FACCEPTONCE sockets must time out. - */ - if (flags & SS_FACCEPTONCE) - so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2; - - so->so_state = (SS_FACCEPTCONN|flags); - so->so_lport = lport; /* Kept in network format */ - so->so_laddr.s_addr = laddr; /* Ditto */ - - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = port; - - if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) || - (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || - (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) || - (listen(s,1) < 0)) { - int error = WSAGetLastError(); /* Don't clobber the real reason we failed */ - - close(s); - sofree(so); - /* Restore the real errno */ - WSASetLastError(error); - return NULL; - } - setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); - - getsockname(s,(struct sockaddr *)&addr,&addrlen); - so->so_fport = addr.sin_port; - if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) - so->so_faddr = alias_addr; - else - so->so_faddr = addr.sin_addr; - - so->s = s; - return so; -} - -/* - * Data is available in so_rcv - * Just write() the data to the socket - * XXX not yet... - */ -void -sorwakeup(so) - struct socket *so; -{ -/* sowrite(so); */ -/* FD_CLR(so->s,&writefds); */ -} - -/* - * Data has been freed in so_snd - * We have room for a read() if we want to - * For now, don't read, it'll be done in the main loop - */ -void -sowwakeup(so) - struct socket *so; -{ - /* Nothing, yet */ -} - -/* - * Various session state calls - * XXX Should be #define's - * The socket state stuff needs work, these often get call 2 or 3 - * times each when only 1 was needed - */ -void -soisfconnecting(so) - register struct socket *so; -{ - so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE| - SS_FCANTSENDMORE|SS_FWDRAIN); - so->so_state |= SS_ISFCONNECTING; /* Clobber other states */ -} - -void -soisfconnected(so) - register struct socket *so; -{ - so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF); - so->so_state |= SS_ISFCONNECTED; /* Clobber other states */ -} - -void -sofcantrcvmore(so) - struct socket *so; -{ - if ((so->so_state & SS_NOFDREF) == 0) { - shutdown(so->s,0); - if(global_writefds) { - FD_CLR(so->s,global_writefds); - } - } - so->so_state &= ~(SS_ISFCONNECTING); - if (so->so_state & SS_FCANTSENDMORE) - so->so_state = SS_NOFDREF; /* Don't select it */ /* XXX close() here as well? */ - else - so->so_state |= SS_FCANTRCVMORE; -} - -void -sofcantsendmore(so) - struct socket *so; -{ - if ((so->so_state & SS_NOFDREF) == 0) { - shutdown(so->s,1); /* send FIN to fhost */ - if (global_readfds) { - FD_CLR(so->s,global_readfds); - } - if (global_xfds) { - FD_CLR(so->s,global_xfds); - } - } - so->so_state &= ~(SS_ISFCONNECTING); - if (so->so_state & SS_FCANTRCVMORE) - so->so_state = SS_NOFDREF; /* as above */ - else - so->so_state |= SS_FCANTSENDMORE; -} - -void -soisfdisconnected(so) - struct socket *so; -{ -/* so->so_state &= ~(SS_ISFCONNECTING|SS_ISFCONNECTED); */ -/* close(so->s); */ -/* so->so_state = SS_ISFDISCONNECTED; */ - /* - * XXX Do nothing ... ? - */ -} - -/* - * Set write drain mode - * Set CANTSENDMORE once all data has been write()n - */ -void -sofwdrain(so) - struct socket *so; -{ - if (so->so_rcv.sb_cc) - so->so_state |= SS_FWDRAIN; - else - sofcantsendmore(so); -} - diff --git a/BasiliskII/src/slirp/socket.h b/BasiliskII/src/slirp/socket.h deleted file mode 100644 index 3b0fee16..00000000 --- a/BasiliskII/src/slirp/socket.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -/* MINE */ - -#ifndef _SLIRP_SOCKET_H_ -#define _SLIRP_SOCKET_H_ - -#define SO_EXPIRE 240000 -#define SO_EXPIREFAST 10000 - -/* - * Our socket structure - */ - -struct socket { - struct socket *so_next,*so_prev; /* For a linked list of sockets */ - - int s; /* The actual socket */ - - /* XXX union these with not-yet-used sbuf params */ - struct mbuf *so_m; /* Pointer to the original SYN packet, - * for non-blocking connect()'s, and - * PING reply's */ - struct tcpiphdr *so_ti; /* Pointer to the original ti within - * so_mconn, for non-blocking connections */ - int so_urgc; - struct in_addr so_faddr; /* foreign host table entry */ - struct in_addr so_laddr; /* local host table entry */ - u_int16_t so_fport; /* foreign port */ - u_int16_t so_lport; /* local port */ - - u_int8_t so_iptos; /* Type of service */ - u_int8_t so_emu; /* Is the socket emulated? */ - - u_char so_type; /* Type of socket, UDP or TCP */ - int so_state; /* internal state flags SS_*, below */ - - struct tcpcb *so_tcpcb; /* pointer to TCP protocol control block */ - u_int so_expire; /* When the socket will expire */ - - int so_queued; /* Number of packets queued from this socket */ - int so_nqueued; /* Number of packets queued in a row - * Used to determine when to "downgrade" a session - * from fastq to batchq */ - - struct sbuf so_rcv; /* Receive buffer */ - struct sbuf so_snd; /* Send buffer */ - void * extra; /* Extra pointer */ -}; - - -/* - * Socket state bits. (peer means the host on the Internet, - * local host means the host on the other end of the modem) - */ -#define SS_NOFDREF 0x001 /* No fd reference */ - -#define SS_ISFCONNECTING 0x002 /* Socket is connecting to peer (non-blocking connect()'s) */ -#define SS_ISFCONNECTED 0x004 /* Socket is connected to peer */ -#define SS_FCANTRCVMORE 0x008 /* Socket can't receive more from peer (for half-closes) */ -#define SS_FCANTSENDMORE 0x010 /* Socket can't send more to peer (for half-closes) */ -/* #define SS_ISFDISCONNECTED 0x020*/ /* Socket has disconnected from peer, in 2MSL state */ -#define SS_FWDRAIN 0x040 /* We received a FIN, drain data and set SS_FCANTSENDMORE */ - -#define SS_CTL 0x080 -#define SS_FACCEPTCONN 0x100 /* Socket is accepting connections from a host on the internet */ -#define SS_FACCEPTONCE 0x200 /* If set, the SS_FACCEPTCONN socket will die after one accept */ - -extern struct socket tcb; - - -#if defined(DECLARE_IOVEC) && !defined(HAVE_READV) -struct iovec { - char *iov_base; - size_t iov_len; -}; -#endif - -void so_init(void); -struct socket * solookup(struct socket *, struct in_addr, u_int, struct in_addr, u_int); -struct socket * socreate(void); -void sofree(struct socket *); -int soread(struct socket *); -void sorecvoob(struct socket *); -int sosendoob(struct socket *); -int sowrite(struct socket *); -void sorecvfrom(struct socket *); -int sosendto(struct socket *, struct mbuf *); -struct socket * solisten(u_int, u_int32_t, u_int, int); -void sorwakeup(struct socket *); -void sowwakeup(struct socket *); -void soisfconnecting(register struct socket *); -void soisfconnected(register struct socket *); -void sofcantrcvmore(struct socket *); -void sofcantsendmore(struct socket *); -void soisfdisconnected(struct socket *); -void sofwdrain(struct socket *); - -#endif /* _SOCKET_H_ */ diff --git a/BasiliskII/src/slirp/tcp.h b/BasiliskII/src/slirp/tcp.h deleted file mode 100644 index 24e7914a..00000000 --- a/BasiliskII/src/slirp/tcp.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)tcp.h 8.1 (Berkeley) 6/10/93 - * tcp.h,v 1.3 1994/08/21 05:27:34 paul Exp - */ - -#ifndef _TCP_H_ -#define _TCP_H_ - -typedef u_int32_t tcp_seq; - -#define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */ -#define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */ - -extern size_t tcp_rcvspace; -extern size_t tcp_sndspace; -extern struct socket *tcp_last_so; - -#define TCP_SNDSPACE 8192 -#define TCP_RCVSPACE 8192 - -/* - * TCP header. - * Per RFC 793, September, 1981. - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct tcphdr { - u_int16_t th_sport; /* source port */ - u_int16_t th_dport; /* destination port */ - tcp_seq th_seq; /* sequence number */ - tcp_seq th_ack; /* acknowledgement number */ -#ifdef WORDS_BIGENDIAN - u_char th_off:4, /* data offset */ - th_x2:4; /* (unused) */ -#else - u_char th_x2:4, /* (unused) */ - th_off:4; /* data offset */ -#endif - u_int8_t th_flags; -#define TH_FIN 0x01 -#define TH_SYN 0x02 -#define TH_RST 0x04 -#define TH_PUSH 0x08 -#define TH_ACK 0x10 -#define TH_URG 0x20 - u_int16_t th_win; /* window */ - u_int16_t th_sum; /* checksum */ - u_int16_t th_urp; /* urgent pointer */ -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) -#endif - -#include "tcp_var.h" - -#define TCPOPT_EOL 0 -#define TCPOPT_NOP 1 -#define TCPOPT_MAXSEG 2 -#define TCPOLEN_MAXSEG 4 -#define TCPOPT_WINDOW 3 -#define TCPOLEN_WINDOW 3 -#define TCPOPT_SACK_PERMITTED 4 /* Experimental */ -#define TCPOLEN_SACK_PERMITTED 2 -#define TCPOPT_SACK 5 /* Experimental */ -#define TCPOPT_TIMESTAMP 8 -#define TCPOLEN_TIMESTAMP 10 -#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ - -#define TCPOPT_TSTAMP_HDR \ - (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) - -/* - * Default maximum segment size for TCP. - * With an IP MSS of 576, this is 536, - * but 512 is probably more convenient. - * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)). - * - * We make this 1460 because we only care about Ethernet in the qemu context. - */ -#define TCP_MSS 1460 - -#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ - -#define TCP_MAX_WINSHIFT 14 /* maximum window shift */ - -/* - * User-settable options (used with setsockopt). - * - * We don't use the system headers on unix because we have conflicting - * local structures. We can't avoid the system definitions on Windows, - * so we undefine them. - */ -#undef TCP_NODELAY -#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ -#undef TCP_MAXSEG -/* #define TCP_MAXSEG 0x02 */ /* set maximum segment size */ - -/* - * TCP FSM state definitions. - * Per RFC793, September, 1981. - */ - -#define TCP_NSTATES 11 - -#define TCPS_CLOSED 0 /* closed */ -#define TCPS_LISTEN 1 /* listening for connection */ -#define TCPS_SYN_SENT 2 /* active, have sent syn */ -#define TCPS_SYN_RECEIVED 3 /* have send and received syn */ -/* states < TCPS_ESTABLISHED are those where connections not established */ -#define TCPS_ESTABLISHED 4 /* established */ -#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */ -/* states > TCPS_CLOSE_WAIT are those where user has closed */ -#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */ -#define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */ -#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */ -/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */ -#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */ -#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */ - -#define TCPS_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED) -#define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED) -#define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT) - -/* - * TCP sequence numbers are 32 bit integers operated - * on with modular arithmetic. These macros can be - * used to compare such integers. - */ -#define SEQ_LT(a,b) ((int)((a)-(b)) < 0) -#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) -#define SEQ_GT(a,b) ((int)((a)-(b)) > 0) -#define SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0) - -/* - * Macros to initialize tcp sequence numbers for - * send and receive from initial send and receive - * sequence numbers. - */ -#define tcp_rcvseqinit(tp) \ - (tp)->rcv_adv = (tp)->rcv_nxt = (tp)->irs + 1 - -#define tcp_sendseqinit(tp) \ - (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = (tp)->iss - -#define TCP_ISSINCR (125*1024) /* increment for tcp_iss each second */ - -extern tcp_seq tcp_iss; /* tcp initial send seq # */ - -extern char *tcpstates[]; - -#endif diff --git a/BasiliskII/src/slirp/tcp_input.c b/BasiliskII/src/slirp/tcp_input.c deleted file mode 100644 index 032e5378..00000000 --- a/BasiliskII/src/slirp/tcp_input.c +++ /dev/null @@ -1,1724 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)tcp_input.c 8.5 (Berkeley) 4/10/94 - * tcp_input.c,v 1.10 1994/10/13 18:36:32 wollman Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include -#include -#include "ip_icmp.h" - -struct socket tcb; - -int tcprexmtthresh = 3; -struct socket *tcp_last_so = &tcb; - -tcp_seq tcp_iss; /* tcp initial send seq # */ - -#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ) - -/* for modulo comparisons of timestamps */ -#define TSTMP_LT(a,b) ((int)((a)-(b)) < 0) -#define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0) - -/* - * Insert segment ti into reassembly queue of tcp with - * control block tp. Return TH_FIN if reassembly now includes - * a segment with FIN. The macro form does the common case inline - * (segment is the next to be received on an established connection, - * and the queue is empty), avoiding linkage into and removal - * from the queue and repetition of various conversions. - * Set DELACK for segments received in order, but ack immediately - * when segments are out of order (so fast retransmit can work). - */ -#ifdef TCP_ACK_HACK -#define TCP_REASS(tp, ti, m, so, flags) {\ - if ((ti)->ti_seq == (tp)->rcv_nxt && \ - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ - (tp)->t_state == TCPS_ESTABLISHED) {\ - if (ti->ti_flags & TH_PUSH) \ - tp->t_flags |= TF_ACKNOW; \ - else \ - tp->t_flags |= TF_DELACK; \ - (tp)->rcv_nxt += (ti)->ti_len; \ - flags = (ti)->ti_flags & TH_FIN; \ - tcpstat.tcps_rcvpack++;\ - tcpstat.tcps_rcvbyte += (ti)->ti_len;\ - if (so->so_emu) { \ - if (tcp_emu((so),(m))) sbappend((so), (m)); \ - } else \ - sbappend((so), (m)); \ -/* sorwakeup(so); */ \ - } else {\ - (flags) = tcp_reass((tp), (ti), (m)); \ - tp->t_flags |= TF_ACKNOW; \ - } \ -} -#else -#define TCP_REASS(tp, ti, m, so, flags) { \ - if ((ti)->ti_seq == (tp)->rcv_nxt && \ - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ - (tp)->t_state == TCPS_ESTABLISHED) { \ - tp->t_flags |= TF_DELACK; \ - (tp)->rcv_nxt += (ti)->ti_len; \ - flags = (ti)->ti_flags & TH_FIN; \ - tcpstat.tcps_rcvpack++;\ - tcpstat.tcps_rcvbyte += (ti)->ti_len;\ - if (so->so_emu) { \ - if (tcp_emu((so),(m))) sbappend(so, (m)); \ - } else \ - sbappend((so), (m)); \ -/* sorwakeup(so); */ \ - } else { \ - (flags) = tcp_reass((tp), (ti), (m)); \ - tp->t_flags |= TF_ACKNOW; \ - } \ -} -#endif - -int -tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf *m) -{ - register struct tcpiphdr *q; - struct socket *so = tp->t_socket; - int flags; - - /* - * Call with ti==0 after become established to - * force pre-ESTABLISHED data up to user socket. - */ - if (ti == 0) - goto present; - - /* - * Find a segment which begins after this one does. - */ - for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp; - q = (struct tcpiphdr *)q->ti_next) - if (SEQ_GT(q->ti_seq, ti->ti_seq)) - break; - - /* - * If there is a preceding segment, it may provide some of - * our data already. If so, drop the data from the incoming - * segment. If it provides all of our data, drop us. - */ - if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { - register int i; - q = (struct tcpiphdr *)q->ti_prev; - /* conversion to int (in i) handles seq wraparound */ - i = q->ti_seq + q->ti_len - ti->ti_seq; - if (i > 0) { - if (i >= ti->ti_len) { - tcpstat.tcps_rcvduppack++; - tcpstat.tcps_rcvdupbyte += ti->ti_len; - m_freem(m); - /* - * Try to present any queued data - * at the left window edge to the user. - * This is needed after the 3-WHS - * completes. - */ - goto present; /* ??? */ - } - m_adj(m, i); - ti->ti_len -= i; - ti->ti_seq += i; - } - q = (struct tcpiphdr *)(q->ti_next); - } - tcpstat.tcps_rcvoopack++; - tcpstat.tcps_rcvoobyte += ti->ti_len; - REASS_MBUF(ti) = (mbufp_32) m; /* XXX */ - - /* - * While we overlap succeeding segments trim them or, - * if they are completely covered, dequeue them. - */ - while (q != (struct tcpiphdr *)tp) { - register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; - if (i <= 0) - break; - if (i < q->ti_len) { - q->ti_seq += i; - q->ti_len -= i; - m_adj((struct mbuf *) REASS_MBUF(q), i); - break; - } - q = (struct tcpiphdr *)q->ti_next; - m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)q->ti_prev); - remque_32((void *)(q->ti_prev)); - m_freem(m); - } - - /* - * Stick new segment in its place. - */ - insque_32(ti, (void *)(q->ti_prev)); - -present: - /* - * Present data to user, advancing rcv_nxt through - * completed sequence space. - */ - if (!TCPS_HAVEESTABLISHED(tp->t_state)) - return (0); - ti = (struct tcpiphdr *) tp->seg_next; - if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt) - return (0); - if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len) - return (0); - do { - tp->rcv_nxt += ti->ti_len; - flags = ti->ti_flags & TH_FIN; - remque_32(ti); - m = (struct mbuf *) REASS_MBUF(ti); /* XXX */ - ti = (struct tcpiphdr *)ti->ti_next; -/* if (so->so_state & SS_FCANTRCVMORE) */ - if (so->so_state & SS_FCANTSENDMORE) - m_freem(m); - else { - if (so->so_emu) { - if (tcp_emu(so,m)) sbappend(so, m); - } else - sbappend(so, m); - } - } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt); -/* sorwakeup(so); */ - return (flags); -} - -/* - * TCP input routine, follows pages 65-76 of the - * protocol specification dated September, 1981 very closely. - */ -void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso) -{ - struct ip save_ip, *ip; - register struct tcpiphdr *ti; - caddr_t optp = NULL; - int optlen = 0; - int len, tlen, off; - register struct tcpcb *tp = 0; - register int tiflags; - struct socket *so = 0; - int todrop; - u_int acked; - int ourfinisacked, needoutput = 0; - /* int dropsocket = 0; */ - int iss = 0; - u_long tiwin; - int ret; - /* int ts_present = 0; */ - - DEBUG_CALL("tcp_input"); - DEBUG_ARGS((dfd, " m = %8lx iphlen = %2d inso = %lx\n", - (long)m, iphlen, (long)inso)); - - /* - * If called with m == 0, then we're continuing the connect - */ - if (m == NULL) { - so = inso; - - /* Re-set a few variables */ - tp = sototcpcb(so); - m = so->so_m; - so->so_m = 0; - ti = so->so_ti; - tiwin = ti->ti_win; - tiflags = ti->ti_flags; - - goto cont_conn; - } - - - tcpstat.tcps_rcvtotal++; - /* - * Get IP and TCP header together in first mbuf. - * Note: IP leaves IP header in first mbuf. - */ - ti = mtod(m, struct tcpiphdr *); - if (iphlen > sizeof(struct ip)) { - ip_stripoptions(m, (struct mbuf *)0); - iphlen = sizeof(struct ip); - } - /* XXX Check if too short */ - - - /* - * Save a copy of the IP header in case we want restore it - * for sending an ICMP error message in response. - */ - ip = mtod(m, struct ip *); - save_ip = *ip; - save_ip.ip_len += iphlen; - - /* - * Checksum extended TCP header and data. - */ - tlen = ((struct ip *)ti)->ip_len; - ti->ti_next = ti->ti_prev = 0; - ti->ti_x1 = 0; - ti->ti_len = htons((u_int16_t)tlen); - len = sizeof(struct ip) + tlen; - /* keep checksum for ICMP reply - * ti->ti_sum = cksum(m, len); - * if (ti->ti_sum) { */ - if (cksum(m, len)) { - tcpstat.tcps_rcvbadsum++; - goto drop; - } - - /* - * Check that TCP offset makes sense, - * pull out TCP options and adjust length. XXX - */ - off = ti->ti_off << 2; - if (off < sizeof(struct tcphdr) || off > tlen) { - tcpstat.tcps_rcvbadoff++; - goto drop; - } - tlen -= off; - ti->ti_len = tlen; - if (off > sizeof(struct tcphdr)) { - optlen = off - sizeof(struct tcphdr); - optp = mtod(m, caddr_t) + sizeof(struct tcpiphdr); - - /* - * Do quick retrieval of timestamp options ("options - * prediction?"). If timestamp is the only option and it's - * formatted as recommended in RFC 1323 appendix A, we - * quickly get the values now and not bother calling - * tcp_dooptions(), etc. - */ - /* if ((optlen == TCPOLEN_TSTAMP_APPA || - * (optlen > TCPOLEN_TSTAMP_APPA && - * optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && - * *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) && - * (ti->ti_flags & TH_SYN) == 0) { - * ts_present = 1; - * ts_val = ntohl(*(u_int32_t *)(optp + 4)); - * ts_ecr = ntohl(*(u_int32_t *)(optp + 8)); - * optp = NULL; / * we've parsed the options * / - * } - */ - } - tiflags = ti->ti_flags; - - /* - * Convert TCP protocol specific fields to host format. - */ - NTOHL(ti->ti_seq); - NTOHL(ti->ti_ack); - NTOHS(ti->ti_win); - NTOHS(ti->ti_urp); - - /* - * Drop TCP, IP headers and TCP options. - */ - m->m_data += sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - m->m_len -= sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - - /* - * Locate pcb for segment. - */ -findso: - so = tcp_last_so; - if (so->so_fport != ti->ti_dport || - so->so_lport != ti->ti_sport || - so->so_laddr.s_addr != ti->ti_src.s_addr || - so->so_faddr.s_addr != ti->ti_dst.s_addr) { - so = solookup(&tcb, ti->ti_src, ti->ti_sport, - ti->ti_dst, ti->ti_dport); - if (so) - tcp_last_so = so; - ++tcpstat.tcps_socachemiss; - } - - /* - * If the state is CLOSED (i.e., TCB does not exist) then - * all data in the incoming segment is discarded. - * If the TCB exists but is in CLOSED state, it is embryonic, - * but should either do a listen or a connect soon. - * - * state == CLOSED means we've done socreate() but haven't - * attached it to a protocol yet... - * - * XXX If a TCB does not exist, and the TH_SYN flag is - * the only flag set, then create a session, mark it - * as if it was LISTENING, and continue... - */ - if (so == 0) { - if ((tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) != TH_SYN) - goto dropwithreset; - - if ((so = socreate()) == NULL) - goto dropwithreset; - if (tcp_attach(so) < 0) { - free(so); /* Not sofree (if it failed, it's not insqued) */ - goto dropwithreset; - } - - sbreserve(&so->so_snd, tcp_sndspace); - sbreserve(&so->so_rcv, tcp_rcvspace); - - /* tcp_last_so = so; */ /* XXX ? */ - /* tp = sototcpcb(so); */ - - so->so_laddr = ti->ti_src; - so->so_lport = ti->ti_sport; - so->so_faddr = ti->ti_dst; - so->so_fport = ti->ti_dport; - - if ((so->so_iptos = tcp_tos(so)) == 0) - so->so_iptos = ((struct ip *)ti)->ip_tos; - - tp = sototcpcb(so); - tp->t_state = TCPS_LISTEN; - } - - /* - * If this is a still-connecting socket, this probably - * a retransmit of the SYN. Whether it's a retransmit SYN - * or something else, we nuke it. - */ - if (so->so_state & SS_ISFCONNECTING) - goto drop; - - tp = sototcpcb(so); - - /* XXX Should never fail */ - if (tp == 0) - goto dropwithreset; - if (tp->t_state == TCPS_CLOSED) - goto drop; - - /* Unscale the window into a 32-bit value. */ -/* if ((tiflags & TH_SYN) == 0) - * tiwin = ti->ti_win << tp->snd_scale; - * else - */ - tiwin = ti->ti_win; - - /* - * Segment received on connection. - * Reset idle time and keep-alive timer. - */ - tp->t_idle = 0; - if (so_options) - tp->t_timer[TCPT_KEEP] = tcp_keepintvl; - else - tp->t_timer[TCPT_KEEP] = tcp_keepidle; - - /* - * Process options if not in LISTEN state, - * else do it below (after getting remote address). - */ - if (optp && tp->t_state != TCPS_LISTEN) - tcp_dooptions(tp, (u_char *)optp, optlen, ti); - /* , */ - /* &ts_present, &ts_val, &ts_ecr); */ - - /* - * Header prediction: check for the two common cases - * of a uni-directional data xfer. If the packet has - * no control flags, is in-sequence, the window didn't - * change and we're not retransmitting, it's a - * candidate. If the length is zero and the ack moved - * forward, we're the sender side of the xfer. Just - * free the data acked & wake any higher level process - * that was blocked waiting for space. If the length - * is non-zero and the ack didn't move, we're the - * receiver side. If we're getting packets in-order - * (the reassembly queue is empty), add the data to - * the socket buffer and note that we need a delayed ack. - * - * XXX Some of these tests are not needed - * eg: the tiwin == tp->snd_wnd prevents many more - * predictions.. with no *real* advantage.. - */ - if (tp->t_state == TCPS_ESTABLISHED && - (tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) == TH_ACK && - /* (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && */ - ti->ti_seq == tp->rcv_nxt && - tiwin && tiwin == tp->snd_wnd && - tp->snd_nxt == tp->snd_max) { - /* - * If last ACK falls within this segment's sequence numbers, - * record the timestamp. - */ - /* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && - * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) { - * tp->ts_recent_age = tcp_now; - * tp->ts_recent = ts_val; - * } - */ - if (ti->ti_len == 0) { - if (SEQ_GT(ti->ti_ack, tp->snd_una) && - SEQ_LEQ(ti->ti_ack, tp->snd_max) && - tp->snd_cwnd >= tp->snd_wnd) { - /* - * this is a pure ack for outstanding data. - */ - ++tcpstat.tcps_predack; - /* if (ts_present) - * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); - * else - */ if (tp->t_rtt && -SEQ_GT(ti->ti_ack, tp->t_rtseq)) - tcp_xmit_timer(tp, tp->t_rtt); - acked = ti->ti_ack - tp->snd_una; - tcpstat.tcps_rcvackpack++; - tcpstat.tcps_rcvackbyte += acked; - sbdrop(&so->so_snd, acked); - tp->snd_una = ti->ti_ack; - m_freem(m); - - /* - * If all outstanding data are acked, stop - * retransmit timer, otherwise restart timer - * using current (possibly backed-off) value. - * If process is waiting for space, - * wakeup/selwakeup/signal. If data - * are ready to send, let tcp_output - * decide between more output or persist. - */ - if (tp->snd_una == tp->snd_max) - tp->t_timer[TCPT_REXMT] = 0; - else if (tp->t_timer[TCPT_PERSIST] == 0) - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - - /* - * There's room in so_snd, sowwakup will read() - * from the socket if we can - */ - /* if (so->so_snd.sb_flags & SB_NOTIFY) - * sowwakeup(so); - */ - /* - * This is called because sowwakeup might have - * put data into so_snd. Since we don't so sowwakeup, - * we don't need this.. XXX??? - */ - if (so->so_snd.sb_cc) - (void) tcp_output(tp); - - return; - } - } - else if (ti->ti_ack == tp->snd_una && - tp->seg_next == (tcpiphdrp_32)tp && - ti->ti_len <= sbspace(&so->so_rcv)) { - /* - * this is a pure, in-sequence data packet - * with nothing on the reassembly queue and - * we have enough buffer space to take it. - */ - ++tcpstat.tcps_preddat; - tp->rcv_nxt += ti->ti_len; - tcpstat.tcps_rcvpack++; - tcpstat.tcps_rcvbyte += ti->ti_len; - /* - * Add data to socket buffer. - */ - if (so->so_emu) { - if (tcp_emu(so, m)) sbappend(so, m); - } - else - sbappend(so, m); - - /* - * XXX This is called when data arrives. Later, check - * if we can actually write() to the socket - * XXX Need to check? It's be NON_BLOCKING - */ - /* sorwakeup(so); */ - - /* - * If this is a short packet, then ACK now - with Nagel - * congestion avoidance sender won't send more until - * he gets an ACK. - * - * It is better to not delay acks at all to maximize - * TCP throughput. See RFC 2581. - */ - tp->t_flags |= TF_ACKNOW; - tcp_output(tp); - return; - } - } /* header prediction */ - /* - * Calculate amount of space in receive window, - * and then do TCP input processing. - * Receive window is amount of space in rcv queue, - * but not less than advertised window. - */ - { int win; - win = sbspace(&so->so_rcv); - if (win < 0) - win = 0; - tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt)); - } - - switch (tp->t_state) { - - /* - * If the state is LISTEN then ignore segment if it contains an RST. - * If the segment contains an ACK then it is bad and send a RST. - * If it does not contain a SYN then it is not interesting; drop it. - * Don't bother responding if the destination was a broadcast. - * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial - * tp->iss, and send a segment: - * - * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. - * Fill in remote peer address fields if not previously specified. - * Enter SYN_RECEIVED state, and process any other fields of this - * segment in this state. - */ - case TCPS_LISTEN: { - - if (tiflags & TH_RST) - goto drop; - if (tiflags & TH_ACK) - goto dropwithreset; - if ((tiflags & TH_SYN) == 0) - goto drop; - - /* - * This has way too many gotos... - * But a bit of spaghetti code never hurt anybody :) - */ - - /* - * If this is destined for the control address, then flag to - * tcp_ctl once connected, otherwise connect - */ - if ((so->so_faddr.s_addr&htonl(0xffffff00)) == special_addr.s_addr) { - int lastbyte = ntohl(so->so_faddr.s_addr) & 0xff; - if (lastbyte != CTL_ALIAS && lastbyte != CTL_DNS) { -#if 0 - if (lastbyte == CTL_CMD || lastbyte == CTL_EXEC) { - /* Command or exec adress */ - so->so_state |= SS_CTL; - } - else -#endif - { - /* May be an add exec */ - struct ex_list *ex_ptr; - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->ex_fport == so->so_fport && - lastbyte == ex_ptr->ex_addr) { - so->so_state |= SS_CTL; - break; - } - } - } - if (so->so_state & SS_CTL) goto cont_input; - } - /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */ - } - - if (so->so_emu & EMU_NOCONNECT) { - so->so_emu &= ~EMU_NOCONNECT; - goto cont_input; - } - - if (tcp_fconnect(so) == -1) { - int error = WSAGetLastError(); - if ((error != WSAEINPROGRESS) && (error != WSAEWOULDBLOCK)) { - u_char code = ICMP_UNREACH_NET; - DEBUG_MISC((dfd, " tcp fconnect errno = %d-%s\n", - errno, strerror(errno))); - if (error == WSAECONNREFUSED) { - /* ACK the SYN, send RST to refuse the connection */ - tcp_respond(tp, ti, m, ti->ti_seq + 1, (tcp_seq)0, - TH_RST | TH_ACK); - } - else { - if (error == WSAEHOSTUNREACH) code = ICMP_UNREACH_HOST; - HTONL(ti->ti_seq); /* restore tcp header */ - HTONL(ti->ti_ack); - HTONS(ti->ti_win); - HTONS(ti->ti_urp); - m->m_data -= sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - m->m_len += sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - *ip = save_ip; - icmp_error(m, ICMP_UNREACH, code, 0, strerror(errno)); - } - tp = tcp_close(tp); - m_free(m); - return; - } - } - - /* - * Haven't connected yet, save the current mbuf - * and ti, and return - * XXX Some OS's don't tell us whether the connect() - * succeeded or not. So we must time it out. - */ - so->so_m = m; - so->so_ti = ti; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->t_state = TCPS_SYN_RECEIVED; - return; - - cont_conn: - /* m==NULL - * Check if the connect succeeded - */ - if (so->so_state & SS_NOFDREF) { - tp = tcp_close(tp); - goto dropwithreset; - } - cont_input: - tcp_template(tp); - - if (optp) - tcp_dooptions(tp, (u_char *)optp, optlen, ti); - /* , */ - /* &ts_present, &ts_val, &ts_ecr); */ - - if (iss) - tp->iss = iss; - else - tp->iss = tcp_iss; - tcp_iss += TCP_ISSINCR / 2; - tp->irs = ti->ti_seq; - tcp_sendseqinit(tp); - tcp_rcvseqinit(tp); - tp->t_flags |= TF_ACKNOW; - tp->t_state = TCPS_SYN_RECEIVED; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tcpstat.tcps_accepts++; - goto trimthenstep6; - } /* case TCPS_LISTEN */ - - /* - * If the state is SYN_SENT: - * if seg contains an ACK, but not for our SYN, drop the input. - * if seg contains a RST, then drop the connection. - * if seg does not contain SYN, then drop it. - * Otherwise this is an acceptable SYN segment - * initialize tp->rcv_nxt and tp->irs - * if seg contains ack then advance tp->snd_una - * if SYN has been acked change to ESTABLISHED else SYN_RCVD state - * arrange for segment to be acked (eventually) - * continue processing rest of data/controls, beginning with URG - */ - case TCPS_SYN_SENT: - if ((tiflags & TH_ACK) && - (SEQ_LEQ(ti->ti_ack, tp->iss) || - SEQ_GT(ti->ti_ack, tp->snd_max))) - goto dropwithreset; - - if (tiflags & TH_RST) { - if (tiflags & TH_ACK) - tp = tcp_drop(tp, 0); /* XXX Check t_softerror! */ - goto drop; - } - - if ((tiflags & TH_SYN) == 0) - goto drop; - if (tiflags & TH_ACK) { - tp->snd_una = ti->ti_ack; - if (SEQ_LT(tp->snd_nxt, tp->snd_una)) - tp->snd_nxt = tp->snd_una; - } - - tp->t_timer[TCPT_REXMT] = 0; - tp->irs = ti->ti_seq; - tcp_rcvseqinit(tp); - tp->t_flags |= TF_ACKNOW; - if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) { - tcpstat.tcps_connects++; - soisfconnected(so); - tp->t_state = TCPS_ESTABLISHED; - - /* Do window scaling on this connection? */ -/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == - * (TF_RCVD_SCALE|TF_REQ_SCALE)) { - * tp->snd_scale = tp->requested_s_scale; - * tp->rcv_scale = tp->request_r_scale; - * } - */ - (void)tcp_reass(tp, (struct tcpiphdr *)0, - (struct mbuf *)0); - /* - * if we didn't have to retransmit the SYN, - * use its rtt as our initial srtt & rtt var. - */ - if (tp->t_rtt) - tcp_xmit_timer(tp, tp->t_rtt); - } - else - tp->t_state = TCPS_SYN_RECEIVED; - - trimthenstep6: - /* - * Advance ti->ti_seq to correspond to first data byte. - * If data, trim to stay within window, - * dropping FIN if necessary. - */ - ti->ti_seq++; - if (ti->ti_len > tp->rcv_wnd) { - todrop = ti->ti_len - tp->rcv_wnd; - m_adj(m, -todrop); - ti->ti_len = tp->rcv_wnd; - tiflags &= ~TH_FIN; - tcpstat.tcps_rcvpackafterwin++; - tcpstat.tcps_rcvbyteafterwin += todrop; - } - tp->snd_wl1 = ti->ti_seq - 1; - tp->rcv_up = ti->ti_seq; - goto step6; - } /* switch tp->t_state */ - /* - * States other than LISTEN or SYN_SENT. - * First check timestamp, if present. - * Then check that at least some bytes of segment are within - * receive window. If segment begins before rcv_nxt, - * drop leading data (and SYN); if nothing left, just ack. - * - * RFC 1323 PAWS: If we have a timestamp reply on this segment - * and it's less than ts_recent, drop it. - */ - /* if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent && - * TSTMP_LT(ts_val, tp->ts_recent)) { - * - */ /* Check to see if ts_recent is over 24 days old. */ - /* if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) { - */ /* - * * Invalidate ts_recent. If this segment updates - * * ts_recent, the age will be reset later and ts_recent - * * will get a valid value. If it does not, setting - * * ts_recent to zero will at least satisfy the - * * requirement that zero be placed in the timestamp - * * echo reply when ts_recent isn't valid. The - * * age isn't reset until we get a valid ts_recent - * * because we don't want out-of-order segments to be - * * dropped when ts_recent is old. - * */ - /* tp->ts_recent = 0; - * } else { - * tcpstat.tcps_rcvduppack++; - * tcpstat.tcps_rcvdupbyte += ti->ti_len; - * tcpstat.tcps_pawsdrop++; - * goto dropafterack; - * } - * } - */ - - todrop = tp->rcv_nxt - ti->ti_seq; - if (todrop > 0) { - if (tiflags & TH_SYN) { - tiflags &= ~TH_SYN; - ti->ti_seq++; - if (ti->ti_urp > 1) - ti->ti_urp--; - else - tiflags &= ~TH_URG; - todrop--; - } - /* - * Following if statement from Stevens, vol. 2, p. 960. - */ - if (todrop > ti->ti_len - || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) { - /* - * Any valid FIN must be to the left of the window. - * At this point the FIN must be a duplicate or out - * of sequence; drop it. - */ - tiflags &= ~TH_FIN; - - /* - * Send an ACK to resynchronize and drop any data. - * But keep on processing for RST or ACK. - */ - tp->t_flags |= TF_ACKNOW; - todrop = ti->ti_len; - tcpstat.tcps_rcvduppack++; - tcpstat.tcps_rcvdupbyte += todrop; - } - else { - tcpstat.tcps_rcvpartduppack++; - tcpstat.tcps_rcvpartdupbyte += todrop; - } - m_adj(m, todrop); - ti->ti_seq += todrop; - ti->ti_len -= todrop; - if (ti->ti_urp > todrop) - ti->ti_urp -= todrop; - else { - tiflags &= ~TH_URG; - ti->ti_urp = 0; - } - } - /* - * If new data are received on a connection after the - * user processes are gone, then RST the other end. - */ - if ((so->so_state & SS_NOFDREF) && - tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) { - tp = tcp_close(tp); - tcpstat.tcps_rcvafterclose++; - goto dropwithreset; - } - - /* - * If segment ends after window, drop trailing data - * (and PUSH and FIN); if nothing left, just ACK. - */ - todrop = (ti->ti_seq + ti->ti_len) - (tp->rcv_nxt + tp->rcv_wnd); - if (todrop > 0) { - tcpstat.tcps_rcvpackafterwin++; - if (todrop >= ti->ti_len) { - tcpstat.tcps_rcvbyteafterwin += ti->ti_len; - /* - * If a new connection request is received - * while in TIME_WAIT, drop the old connection - * and start over if the sequence numbers - * are above the previous ones. - */ - if (tiflags & TH_SYN && - tp->t_state == TCPS_TIME_WAIT && - SEQ_GT(ti->ti_seq, tp->rcv_nxt)) { - iss = tp->rcv_nxt + TCP_ISSINCR; - tp = tcp_close(tp); - goto findso; - } - /* - * If window is closed can only take segments at - * window edge, and have to drop data and PUSH from - * incoming segments. Continue processing, but - * remember to ack. Otherwise, drop segment - * and ack. - */ - if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) { - tp->t_flags |= TF_ACKNOW; - tcpstat.tcps_rcvwinprobe++; - } - else - goto dropafterack; - } - else - tcpstat.tcps_rcvbyteafterwin += todrop; - m_adj(m, -todrop); - ti->ti_len -= todrop; - tiflags &= ~(TH_PUSH | TH_FIN); - } - - /* - * If last ACK falls within this segment's sequence numbers, - * record its timestamp. - */ - /* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && - * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len + - * ((tiflags & (TH_SYN|TH_FIN)) != 0))) { - * tp->ts_recent_age = tcp_now; - * tp->ts_recent = ts_val; - * } - */ - - /* - * If the RST bit is set examine the state: - * SYN_RECEIVED STATE: - * If passive open, return to LISTEN state. - * If active open, inform user that connection was refused. - * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: - * Inform user that connection was reset, and close tcb. - * CLOSING, LAST_ACK, TIME_WAIT STATES - * Close the tcb. - */ - if (tiflags&TH_RST) switch (tp->t_state) { - - case TCPS_SYN_RECEIVED: - /* so->so_error = ECONNREFUSED; */ - goto close; - - case TCPS_ESTABLISHED: - case TCPS_FIN_WAIT_1: - case TCPS_FIN_WAIT_2: - case TCPS_CLOSE_WAIT: - /* so->so_error = ECONNRESET; */ - close: - tp->t_state = TCPS_CLOSED; - tcpstat.tcps_drops++; - tp = tcp_close(tp); - goto drop; - - case TCPS_CLOSING: - case TCPS_LAST_ACK: - case TCPS_TIME_WAIT: - tp = tcp_close(tp); - goto drop; - } - - /* - * If a SYN is in the window, then this is an - * error and we send an RST and drop the connection. - */ - if (tiflags & TH_SYN) { - tp = tcp_drop(tp, 0); - goto dropwithreset; - } - - /* - * If the ACK bit is off we drop the segment and return. - */ - if ((tiflags & TH_ACK) == 0) goto drop; - - /* - * Ack processing. - */ - switch (tp->t_state) { - /* - * In SYN_RECEIVED state if the ack ACKs our SYN then enter - * ESTABLISHED state and continue processing, otherwise - * send an RST. una<=ack<=max - */ - case TCPS_SYN_RECEIVED: - - if (SEQ_GT(tp->snd_una, ti->ti_ack) || - SEQ_GT(ti->ti_ack, tp->snd_max)) - goto dropwithreset; - tcpstat.tcps_connects++; - tp->t_state = TCPS_ESTABLISHED; - /* - * The sent SYN is ack'ed with our sequence number +1 - * The first data byte already in the buffer will get - * lost if no correction is made. This is only needed for - * SS_CTL since the buffer is empty otherwise. - * tp->snd_una++; or: - */ - tp->snd_una = ti->ti_ack; - if (so->so_state & SS_CTL) { - /* So tcp_ctl reports the right state */ - ret = tcp_ctl(so); - if (ret == 1) { - soisfconnected(so); - so->so_state &= ~SS_CTL; /* success XXX */ - } - else if (ret == 2) { - so->so_state = SS_NOFDREF; /* CTL_CMD */ - } - else { - needoutput = 1; - tp->t_state = TCPS_FIN_WAIT_1; - } - } - else { - soisfconnected(so); - } - - /* Do window scaling? */ -/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == - * (TF_RCVD_SCALE|TF_REQ_SCALE)) { - * tp->snd_scale = tp->requested_s_scale; - * tp->rcv_scale = tp->request_r_scale; - * } - */ - (void)tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); - tp->snd_wl1 = ti->ti_seq - 1; - /* Avoid ack processing; snd_una==ti_ack => dup ack */ - goto synrx_to_est; - /* fall into ... */ - - /* - * In ESTABLISHED state: drop duplicate ACKs; ACK out of range - * ACKs. If the ack is in the range - * tp->snd_una < ti->ti_ack <= tp->snd_max - * then advance tp->snd_una to ti->ti_ack and drop - * data from the retransmission queue. If this ACK reflects - * more up to date window information we update our window information. - */ - case TCPS_ESTABLISHED: - case TCPS_FIN_WAIT_1: - case TCPS_FIN_WAIT_2: - case TCPS_CLOSE_WAIT: - case TCPS_CLOSING: - case TCPS_LAST_ACK: - case TCPS_TIME_WAIT: - - if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { - if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { - tcpstat.tcps_rcvdupack++; - DEBUG_MISC((dfd, " dup ack m = %lx so = %lx \n", - (long)m, (long)so)); - /* - * If we have outstanding data (other than - * a window probe), this is a completely - * duplicate ack (ie, window info didn't - * change), the ack is the biggest we've - * seen and we've seen exactly our rexmt - * threshold of them, assume a packet - * has been dropped and retransmit it. - * Kludge snd_nxt & the congestion - * window so we send only this one - * packet. - * - * We know we're losing at the current - * window size so do congestion avoidance - * (set ssthresh to half the current window - * and pull our congestion window back to - * the new ssthresh). - * - * Dup acks mean that packets have left the - * network (they're now cached at the receiver) - * so bump cwnd by the amount in the receiver - * to keep a constant cwnd packets in the - * network. - */ - if (tp->t_timer[TCPT_REXMT] == 0 || - ti->ti_ack != tp->snd_una) - tp->t_dupacks = 0; - else if (++tp->t_dupacks == tcprexmtthresh) { - tcp_seq onxt = tp->snd_nxt; - u_int win = - min(tp->snd_wnd, tp->snd_cwnd) / 2 / - tp->t_maxseg; - - if (win < 2) - win = 2; - tp->snd_ssthresh = win * tp->t_maxseg; - tp->t_timer[TCPT_REXMT] = 0; - tp->t_rtt = 0; - tp->snd_nxt = ti->ti_ack; - tp->snd_cwnd = tp->t_maxseg; - (void)tcp_output(tp); - tp->snd_cwnd = tp->snd_ssthresh + - tp->t_maxseg * tp->t_dupacks; - if (SEQ_GT(onxt, tp->snd_nxt)) - tp->snd_nxt = onxt; - goto drop; - } - else if (tp->t_dupacks > tcprexmtthresh) { - tp->snd_cwnd += tp->t_maxseg; - (void)tcp_output(tp); - goto drop; - } - } - else - tp->t_dupacks = 0; - break; - } - synrx_to_est: - /* - * If the congestion window was inflated to account - * for the other side's cached packets, retract it. - */ - if (tp->t_dupacks > tcprexmtthresh && - tp->snd_cwnd > tp->snd_ssthresh) - tp->snd_cwnd = tp->snd_ssthresh; - tp->t_dupacks = 0; - if (SEQ_GT(ti->ti_ack, tp->snd_max)) { - tcpstat.tcps_rcvacktoomuch++; - goto dropafterack; - } - acked = ti->ti_ack - tp->snd_una; - tcpstat.tcps_rcvackpack++; - tcpstat.tcps_rcvackbyte += acked; - - /* - * If we have a timestamp reply, update smoothed - * round trip time. If no timestamp is present but - * transmit timer is running and timed sequence - * number was acked, update smoothed round trip time. - * Since we now have an rtt measurement, cancel the - * timer backoff (cf., Phil Karn's retransmit alg.). - * Recompute the initial retransmit timer. - */ - /* if (ts_present) - * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); - * else - */ - if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) - tcp_xmit_timer(tp, tp->t_rtt); - - /* - * If all outstanding data is acked, stop retransmit - * timer and remember to restart (more output or persist). - * If there is more data to be acked, restart retransmit - * timer, using current (possibly backed-off) value. - */ - if (ti->ti_ack == tp->snd_max) { - tp->t_timer[TCPT_REXMT] = 0; - needoutput = 1; - } - else if (tp->t_timer[TCPT_PERSIST] == 0) - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - /* - * When new data is acked, open the congestion window. - * If the window gives us less than ssthresh packets - * in flight, open exponentially (maxseg per packet). - * Otherwise open linearly: maxseg per window - * (maxseg^2 / cwnd per packet). - */ - { - register u_int cw = tp->snd_cwnd; - register u_int incr = tp->t_maxseg; - - if (cw > tp->snd_ssthresh) - incr = incr * incr / cw; - tp->snd_cwnd = min(cw + incr, (u_int32_t) (TCP_MAXWIN << tp->snd_scale)); - } - if (acked > so->so_snd.sb_cc) { - tp->snd_wnd -= so->so_snd.sb_cc; - sbdrop(&so->so_snd, so->so_snd.sb_cc); - ourfinisacked = 1; - } - else { - sbdrop(&so->so_snd, acked); - tp->snd_wnd -= acked; - ourfinisacked = 0; - } - /* - * XXX sowwakup is called when data is acked and there's room for - * for more data... it should read() the socket - */ - /* if (so->so_snd.sb_flags & SB_NOTIFY) - * sowwakeup(so); - */ - tp->snd_una = ti->ti_ack; - if (SEQ_LT(tp->snd_nxt, tp->snd_una)) - tp->snd_nxt = tp->snd_una; - - switch (tp->t_state) { - - /* - * In FIN_WAIT_1 STATE in addition to the processing - * for the ESTABLISHED state if our FIN is now acknowledged - * then enter FIN_WAIT_2. - */ - case TCPS_FIN_WAIT_1: - if (ourfinisacked) { - /* - * If we can't receive any more - * data, then closing user can proceed. - * Starting the timer is contrary to the - * specification, but if we don't get a FIN - * we'll hang forever. - */ - if (so->so_state & SS_FCANTRCVMORE) { - soisfdisconnected(so); - tp->t_timer[TCPT_2MSL] = tcp_maxidle; - } - tp->t_state = TCPS_FIN_WAIT_2; - } - break; - - /* - * In CLOSING STATE in addition to the processing for - * the ESTABLISHED state if the ACK acknowledges our FIN - * then enter the TIME-WAIT state, otherwise ignore - * the segment. - */ - case TCPS_CLOSING: - if (ourfinisacked) { - tp->t_state = TCPS_TIME_WAIT; - tcp_canceltimers(tp); - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - soisfdisconnected(so); - } - break; - - /* - * In LAST_ACK, we may still be waiting for data to drain - * and/or to be acked, as well as for the ack of our FIN. - * If our FIN is now acknowledged, delete the TCB, - * enter the closed state and return. - */ - case TCPS_LAST_ACK: - if (ourfinisacked) { - tp = tcp_close(tp); - goto drop; - } - break; - - /* - * In TIME_WAIT state the only thing that should arrive - * is a retransmission of the remote FIN. Acknowledge - * it and restart the finack timer. - */ - case TCPS_TIME_WAIT: - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - goto dropafterack; - } - } /* switch(tp->t_state) */ - -step6: - /* - * Update window information. - * Don't look at window if no ACK: TAC's send garbage on first SYN. - */ - if ((tiflags & TH_ACK) && - (SEQ_LT(tp->snd_wl1, ti->ti_seq) || - (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) || - (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) { - /* keep track of pure window updates */ - if (ti->ti_len == 0 && - tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) - tcpstat.tcps_rcvwinupd++; - tp->snd_wnd = tiwin; - tp->snd_wl1 = ti->ti_seq; - tp->snd_wl2 = ti->ti_ack; - if (tp->snd_wnd > tp->max_sndwnd) - tp->max_sndwnd = tp->snd_wnd; - needoutput = 1; - } - - /* - * Process segments with URG. - */ - if ((tiflags & TH_URG) && ti->ti_urp && - TCPS_HAVERCVDFIN(tp->t_state) == 0) { - /* - * This is a kludge, but if we receive and accept - * random urgent pointers, we'll crash in - * soreceive. It's hard to imagine someone - * actually wanting to send this much urgent data. - */ - if (ti->ti_urp + so->so_rcv.sb_cc > so->so_rcv.sb_datalen) { - ti->ti_urp = 0; - tiflags &= ~TH_URG; - goto dodata; - } - /* - * If this segment advances the known urgent pointer, - * then mark the data stream. This should not happen - * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since - * a FIN has been received from the remote side. - * In these states we ignore the URG. - * - * According to RFC961 (Assigned Protocols), - * the urgent pointer points to the last octet - * of urgent data. We continue, however, - * to consider it to indicate the first octet - * of data past the urgent section as the original - * spec states (in one of two places). - */ - if (SEQ_GT(ti->ti_seq + ti->ti_urp, tp->rcv_up)) { - tp->rcv_up = ti->ti_seq + ti->ti_urp; - so->so_urgc = so->so_rcv.sb_cc + - (tp->rcv_up - tp->rcv_nxt); /* -1; */ - tp->rcv_up = ti->ti_seq + ti->ti_urp; - - } - } - else - /* - * If no out of band data is expected, - * pull receive urgent pointer along - * with the receive window. - */ - if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) - tp->rcv_up = tp->rcv_nxt; -dodata: - - /* - * Process the segment text, merging it into the TCP sequencing queue, - * and arranging for acknowledgment of receipt if necessary. - * This process logically involves adjusting tp->rcv_wnd as data - * is presented to the user (this happens in tcp_usrreq.c, - * case PRU_RCVD). If a FIN has already been received on this - * connection then we just ignore the text. - */ - if ((ti->ti_len || (tiflags&TH_FIN)) && - TCPS_HAVERCVDFIN(tp->t_state) == 0) { - TCP_REASS(tp, ti, m, so, tiflags); - /* - * Note the amount of data that peer has sent into - * our window, in order to estimate the sender's - * buffer size. - */ - len = so->so_rcv.sb_datalen - (tp->rcv_adv - tp->rcv_nxt); - } - else { - m_free(m); - tiflags &= ~TH_FIN; - } - - /* - * If FIN is received ACK the FIN and let the user know - * that the connection is closing. - */ - if (tiflags & TH_FIN) { - if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { - /* - * If we receive a FIN we can't send more data, - * set it SS_FDRAIN - * Shutdown the socket if there is no rx data in the - * buffer. - * soread() is called on completion of shutdown() and - * will got to TCPS_LAST_ACK, and use tcp_output() - * to send the FIN. - */ - /* sofcantrcvmore(so); */ - sofwdrain(so); - - tp->t_flags |= TF_ACKNOW; - tp->rcv_nxt++; - } - switch (tp->t_state) { - - /* - * In SYN_RECEIVED and ESTABLISHED STATES - * enter the CLOSE_WAIT state. - */ - case TCPS_SYN_RECEIVED: - case TCPS_ESTABLISHED: - if (so->so_emu == EMU_CTL) /* no shutdown on socket */ - tp->t_state = TCPS_LAST_ACK; - else - tp->t_state = TCPS_CLOSE_WAIT; - break; - - /* - * If still in FIN_WAIT_1 STATE FIN has not been acked so - * enter the CLOSING state. - */ - case TCPS_FIN_WAIT_1: - tp->t_state = TCPS_CLOSING; - break; - - /* - * In FIN_WAIT_2 state enter the TIME_WAIT state, - * starting the time-wait timer, turning off the other - * standard timers. - */ - case TCPS_FIN_WAIT_2: - tp->t_state = TCPS_TIME_WAIT; - tcp_canceltimers(tp); - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - soisfdisconnected(so); - break; - - /* - * In TIME_WAIT state restart the 2 MSL time_wait timer. - */ - case TCPS_TIME_WAIT: - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - break; - } - } - - /* - * If this is a small packet, then ACK now - with Nagel - * congestion avoidance sender won't send more until - * he gets an ACK. - * - * See above. - */ - /* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) { - */ - /* if ((ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg && - * (so->so_iptos & IPTOS_LOWDELAY) == 0) || - * ((so->so_iptos & IPTOS_LOWDELAY) && - * ((struct tcpiphdr_2 *)ti)->first_char == (char)27)) { - */ - if (ti->ti_len && (unsigned)ti->ti_len <= 5 && - ((struct tcpiphdr_2 *)ti)->first_char == (char)27) { - tp->t_flags |= TF_ACKNOW; - } - - /* - * Return any desired output. - */ - if (needoutput || (tp->t_flags & TF_ACKNOW)) { - (void)tcp_output(tp); - } - return; - -dropafterack: - /* - * Generate an ACK dropping incoming segment if it occupies - * sequence space, where the ACK reflects our state. - */ - if (tiflags & TH_RST) - goto drop; - m_freem(m); - tp->t_flags |= TF_ACKNOW; - (void)tcp_output(tp); - return; - -dropwithreset: - /* reuses m if m!=NULL, m_free() unnecessary */ - if (tiflags & TH_ACK) - tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST); - else { - if (tiflags & TH_SYN) ti->ti_len++; - tcp_respond(tp, ti, m, ti->ti_seq + ti->ti_len, (tcp_seq)0, - TH_RST | TH_ACK); - } - - return; - -drop: - /* - * Drop space held by incoming segment and return. - */ - m_free(m); - - return; -} - - /* , ts_present, ts_val, ts_ecr) */ -/* int *ts_present; - * u_int32_t *ts_val, *ts_ecr; - */ -void -tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti) -{ - u_int16_t mss; - int opt, optlen; - - DEBUG_CALL("tcp_dooptions"); - DEBUG_ARGS((dfd," tp = %lx cnt=%i \n", (long )tp, cnt)); - - for (; cnt > 0; cnt -= optlen, cp += optlen) { - opt = cp[0]; - if (opt == TCPOPT_EOL) - break; - if (opt == TCPOPT_NOP) - optlen = 1; - else { - optlen = cp[1]; - if (optlen <= 0) - break; - } - switch (opt) { - - default: - continue; - - case TCPOPT_MAXSEG: - if (optlen != TCPOLEN_MAXSEG) - continue; - if (!(ti->ti_flags & TH_SYN)) - continue; - memcpy((char *) &mss, (char *) cp + 2, sizeof(mss)); - NTOHS(mss); - tcp_mss(tp, mss); /* sets t_maxseg */ - break; - -/* case TCPOPT_WINDOW: - * if (optlen != TCPOLEN_WINDOW) - * continue; - * if (!(ti->ti_flags & TH_SYN)) - * continue; - * tp->t_flags |= TF_RCVD_SCALE; - * tp->requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT); - * break; - */ -/* case TCPOPT_TIMESTAMP: - * if (optlen != TCPOLEN_TIMESTAMP) - * continue; - * *ts_present = 1; - * memcpy((char *) ts_val, (char *)cp + 2, sizeof(*ts_val)); - * NTOHL(*ts_val); - * memcpy((char *) ts_ecr, (char *)cp + 6, sizeof(*ts_ecr)); - * NTOHL(*ts_ecr); - * - */ /* - * * A timestamp received in a SYN makes - * * it ok to send timestamp requests and replies. - * */ -/* if (ti->ti_flags & TH_SYN) { - * tp->t_flags |= TF_RCVD_TSTMP; - * tp->ts_recent = *ts_val; - * tp->ts_recent_age = tcp_now; - * } - */ break; - } - } -} - - -/* - * Pull out of band byte out of a segment so - * it doesn't appear in the user's data queue. - * It is still reflected in the segment length for - * sequencing purposes. - */ - -#ifdef notdef - -void tcp_pulloutofband(struct socket *so, struct tcpiphdr *ti, register struct mbuf *m) -{ - int cnt = ti->ti_urp - 1; - - while (cnt >= 0) { - if (m->m_len > cnt) { - char *cp = mtod(m, caddr_t) + cnt; - struct tcpcb *tp = sototcpcb(so); - - tp->t_iobc = *cp; - tp->t_oobflags |= TCPOOB_HAVEDATA; - memcpy(sp, cp+1, (unsigned)(m->m_len - cnt - 1)); - m->m_len--; - return; - } - cnt -= m->m_len; - m = m->m_next; /* XXX WRONG! Fix it! */ - if (m == 0) - break; - } - panic("tcp_pulloutofband"); -} - -#endif /* notdef */ - -/* - * Collect new round-trip time estimate - * and update averages and current timeout. - */ - -void tcp_xmit_timer(register struct tcpcb *tp, int rtt) -{ - register short delta; - - DEBUG_CALL("tcp_xmit_timer"); - DEBUG_ARG("tp = %lx", (long)tp); - DEBUG_ARG("rtt = %d", rtt); - - tcpstat.tcps_rttupdated++; - if (tp->t_srtt != 0) { - /* - * srtt is stored as fixed point with 3 bits after the - * binary point (i.e., scaled by 8). The following magic - * is equivalent to the smoothing algorithm in rfc793 with - * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed - * point). Adjust rtt to origin 0. - */ - delta = rtt - 1 - (tp->t_srtt >> TCP_RTT_SHIFT); - if ((tp->t_srtt += delta) <= 0) - tp->t_srtt = 1; - /* - * We accumulate a smoothed rtt variance (actually, a - * smoothed mean difference), then set the retransmit - * timer to smoothed rtt + 4 times the smoothed variance. - * rttvar is stored as fixed point with 2 bits after the - * binary point (scaled by 4). The following is - * equivalent to rfc793 smoothing with an alpha of .75 - * (rttvar = rttvar*3/4 + |delta| / 4). This replaces - * rfc793's wired-in beta. - */ - if (delta < 0) - delta = -delta; - delta -= (tp->t_rttvar >> TCP_RTTVAR_SHIFT); - if ((tp->t_rttvar += delta) <= 0) - tp->t_rttvar = 1; - } else { - /* - * No rtt measurement yet - use the unsmoothed rtt. - * Set the variance to half the rtt (so our first - * retransmit happens at 3*rtt). - */ - tp->t_srtt = rtt << TCP_RTT_SHIFT; - tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); - } - tp->t_rtt = 0; - tp->t_rxtshift = 0; - - /* - * the retransmit should happen at rtt + 4 * rttvar. - * Because of the way we do the smoothing, srtt and rttvar - * will each average +1/2 tick of bias. When we compute - * the retransmit timer, we want 1/2 tick of rounding and - * 1 extra tick because of +-1/2 tick uncertainty in the - * firing of the timer. The bias will give us exactly the - * 1.5 tick we need. But, because the bias is - * statistical, we have to test that we don't drop below - * the minimum feasible timer (which is 2 ticks). - */ - TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), - (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */ - - /* - * We received an ack for a packet that wasn't retransmitted; - * it is probably safe to discard any error indications we've - * received recently. This isn't quite right, but close enough - * for now (a route might have failed after we sent a segment, - * and the return path might not be symmetrical). - */ - tp->t_softerror = 0; -} - -/* - * Determine a reasonable value for maxseg size. - * If the route is known, check route for mtu. - * If none, use an mss that can be handled on the outgoing - * interface without forcing IP to fragment; if bigger than - * an mbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES - * to utilize large mbufs. If no route is found, route has no mtu, - * or the destination isn't local, use a default, hopefully conservative - * size (usually 512 or the default IP max size, but no more than the mtu - * of the interface), as we can't discover anything about intervening - * gateways or networks. We also initialize the congestion/slow start - * window to be a single segment if the destination isn't local. - * While looking at the routing entry, we also initialize other path-dependent - * parameters from pre-set or cached values in the routing entry. - */ - -u_int tcp_mss(register struct tcpcb *tp, u_int offer) -{ - struct socket *so = tp->t_socket; - u_int mss; - - DEBUG_CALL("tcp_mss"); - DEBUG_ARG("tp = %lx", (long)tp); - DEBUG_ARG("offer = %d", offer); - - mss = min(if_mtu, if_mru) - sizeof(struct tcpiphdr); - if (offer) - mss = min(mss, offer); - mss = max(mss, 32); - if (mss < tp->t_maxseg || offer != 0) - tp->t_maxseg = mss; - - tp->snd_cwnd = mss; - - sbreserve(&so->so_snd, tcp_sndspace+((tcp_sndspace%mss)?(mss-(tcp_sndspace%mss)):0)); - sbreserve(&so->so_rcv, tcp_rcvspace+((tcp_rcvspace%mss)?(mss-(tcp_rcvspace%mss)):0)); - - DEBUG_MISC((dfd, " returning mss = %d\n", mss)); - - return mss; -} diff --git a/BasiliskII/src/slirp/tcp_output.c b/BasiliskII/src/slirp/tcp_output.c deleted file mode 100644 index 0d5c0ce5..00000000 --- a/BasiliskII/src/slirp/tcp_output.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)tcp_output.c 8.3 (Berkeley) 12/30/93 - * tcp_output.c,v 1.3 1994/09/15 10:36:55 davidg Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include - -/* - * Since this is only used in "stats socket", we give meaning - * names instead of the REAL names - */ -char *tcpstates[] = { -/* "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", */ - "REDIRECT", "LISTEN", "SYN_SENT", "SYN_RCVD", - "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING", - "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT", -}; - -u_char tcp_outflags[TCP_NSTATES] = { - TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK, - TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, - TH_FIN|TH_ACK, TH_ACK, TH_ACK, -}; - - -#define MAX_TCPOPTLEN 32 /* max # bytes that go in options */ - -/* - * Tcp output routine: figure out what should be sent and send it. - */ -int tcp_output(register struct tcpcb *tp) -{ - register struct socket *so = tp->t_socket; - register u_long len, win; - int off, flags, error; - register struct mbuf *m; - register struct tcpiphdr *ti; - u_char opt[MAX_TCPOPTLEN]; - unsigned optlen, hdrlen; - int idle, sendalot; - - DEBUG_CALL("tcp_output"); - DEBUG_ARG("tp = %lx", (long )tp); - - /* - * Determine length of data that should be transmitted, - * and flags that will be used. - * If there is some data or critical controls (SYN, RST) - * to send, then transmit; otherwise, investigate further. - */ - idle = (tp->snd_max == tp->snd_una); - if (idle && tp->t_idle >= tp->t_rxtcur) - /* - * We have been idle for "a while" and no acks are - * expected to clock out any data we send -- - * slow start to get ack "clock" running again. - */ - tp->snd_cwnd = tp->t_maxseg; -again: - sendalot = 0; - off = tp->snd_nxt - tp->snd_una; - win = min(tp->snd_wnd, tp->snd_cwnd); - - flags = tcp_outflags[tp->t_state]; - - DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags)); - - /* - * If in persist timeout with window of 0, send 1 byte. - * Otherwise, if window is small but nonzero - * and timer expired, we will send what we can - * and go to transmit state. - */ - if (tp->t_force) { - if (win == 0) { - /* - * If we still have some data to send, then - * clear the FIN bit. Usually this would - * happen below when it realizes that we - * aren't sending all the data. However, - * if we have exactly 1 byte of unset data, - * then it won't clear the FIN bit below, - * and if we are in persist state, we wind - * up sending the packet without recording - * that we sent the FIN bit. - * - * We can't just blindly clear the FIN bit, - * because if we don't have any more data - * to send then the probe will be the FIN - * itself. - */ - if (off < (int)so->so_snd.sb_cc) - flags &= ~TH_FIN; - win = 1; - } else { - tp->t_timer[TCPT_PERSIST] = 0; - tp->t_rxtshift = 0; - } - } - - len = min(so->so_snd.sb_cc, win) - off; - - if (len < 0) { - /* - * If FIN has been sent but not acked, - * but we haven't been called to retransmit, - * len will be -1. Otherwise, window shrank - * after we sent into it. If window shrank to 0, - * cancel pending retransmit and pull snd_nxt - * back to (closed) window. We will enter persist - * state below. If the window didn't close completely, - * just wait for an ACK. - */ - len = 0; - if (win == 0) { - tp->t_timer[TCPT_REXMT] = 0; - tp->snd_nxt = tp->snd_una; - } - } - - if (len > tp->t_maxseg) { - len = tp->t_maxseg; - sendalot = 1; - } - if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc)) - flags &= ~TH_FIN; - - win = sbspace(&so->so_rcv); - - /* - * Sender silly window avoidance. If connection is idle - * and can send all data, a maximum segment, - * at least a maximum default-size segment do it, - * or are forced, do it; otherwise don't bother. - * If peer's buffer is tiny, then send - * when window is at least half open. - * If retransmitting (possibly after persist timer forced us - * to send into a small window), then must resend. - */ - if (len) { - if (len == tp->t_maxseg) - goto send; - if ((1 || idle || tp->t_flags & TF_NODELAY) && - len + off >= so->so_snd.sb_cc) - goto send; - if (tp->t_force) - goto send; - if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0) - goto send; - if (SEQ_LT(tp->snd_nxt, tp->snd_max)) - goto send; - } - - /* - * Compare available window to amount of window - * known to peer (as advertised window less - * next expected input). If the difference is at least two - * max size segments, or at least 50% of the maximum possible - * window, then want to send a window update to peer. - */ - if (win > 0) { - /* - * "adv" is the amount we can increase the window, - * taking into account that we are limited by - * TCP_MAXWIN << tp->rcv_scale. - */ - u_int adv = min(win, (u_int)TCP_MAXWIN << tp->rcv_scale) - - (tp->rcv_adv - tp->rcv_nxt); - - if (adv >= (u_int)(2 * tp->t_maxseg)) - goto send; - if (2 * adv >= so->so_rcv.sb_datalen) - goto send; - } - - /* - * Send if we owe peer an ACK. - */ - if (tp->t_flags & TF_ACKNOW) - goto send; - if (flags & (TH_SYN|TH_RST)) - goto send; - if (SEQ_GT(tp->snd_up, tp->snd_una)) - goto send; - /* - * If our state indicates that FIN should be sent - * and we have not yet done so, or we're retransmitting the FIN, - * then we need to send. - */ - if (flags & TH_FIN && - ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una)) - goto send; - - /* - * TCP window updates are not reliable, rather a polling protocol - * using ``persist'' packets is used to insure receipt of window - * updates. The three ``states'' for the output side are: - * idle not doing retransmits or persists - * persisting to move a small or zero window - * (re)transmitting and thereby not persisting - * - * tp->t_timer[TCPT_PERSIST] - * is set when we are in persist state. - * tp->t_force - * is set when we are called to send a persist packet. - * tp->t_timer[TCPT_REXMT] - * is set when we are retransmitting - * The output side is idle when both timers are zero. - * - * If send window is too small, there is data to transmit, and no - * retransmit or persist is pending, then go to persist state. - * If nothing happens soon, send when timer expires: - * if window is nonzero, transmit what we can, - * otherwise force out a byte. - */ - if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 && - tp->t_timer[TCPT_PERSIST] == 0) { - tp->t_rxtshift = 0; - tcp_setpersist(tp); - } - - /* - * No reason to send a segment, just return. - */ - tcpstat.tcps_didnuttin++; - - return (0); - -send: - /* - * Before ESTABLISHED, force sending of initial options - * unless TCP set not to do any options. - * NOTE: we assume that the IP/TCP header plus TCP options - * always fit in a single mbuf, leaving room for a maximum - * link header, i.e. - * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN - */ - optlen = 0; - hdrlen = sizeof (struct tcpiphdr); - if (flags & TH_SYN) { - tp->snd_nxt = tp->iss; - if ((tp->t_flags & TF_NOOPT) == 0) { - u_int16_t mss; - - opt[0] = TCPOPT_MAXSEG; - opt[1] = 4; - mss = htons((u_int16_t) tcp_mss(tp, 0)); - memcpy((caddr_t)(opt + 2), (caddr_t)&mss, sizeof(mss)); - optlen = 4; - -/* if ((tp->t_flags & TF_REQ_SCALE) && - * ((flags & TH_ACK) == 0 || - * (tp->t_flags & TF_RCVD_SCALE))) { - * *((u_int32_t *) (opt + optlen)) = htonl( - * TCPOPT_NOP << 24 | - * TCPOPT_WINDOW << 16 | - * TCPOLEN_WINDOW << 8 | - * tp->request_r_scale); - * optlen += 4; - * } - */ - } - } - - /* - * Send a timestamp and echo-reply if this is a SYN and our side - * wants to use timestamps (TF_REQ_TSTMP is set) or both our side - * and our peer have sent timestamps in our SYN's. - */ -/* if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP && - * (flags & TH_RST) == 0 && - * ((flags & (TH_SYN|TH_ACK)) == TH_SYN || - * (tp->t_flags & TF_RCVD_TSTMP))) { - * u_int32_t *lp = (u_int32_t *)(opt + optlen); - * - * / * Form timestamp option as shown in appendix A of RFC 1323. * / - * *lp++ = htonl(TCPOPT_TSTAMP_HDR); - * *lp++ = htonl(tcp_now); - * *lp = htonl(tp->ts_recent); - * optlen += TCPOLEN_TSTAMP_APPA; - * } - */ - hdrlen += optlen; - - /* - * Adjust data length if insertion of options will - * bump the packet length beyond the t_maxseg length. - */ - if (len > tp->t_maxseg - optlen) { - len = tp->t_maxseg - optlen; - sendalot = 1; - } - - /* - * Grab a header mbuf, attaching a copy of data to - * be transmitted, and initialize the header from - * the template for sends on this connection. - */ - if (len) { - if (tp->t_force && len == 1) - tcpstat.tcps_sndprobe++; - else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { - tcpstat.tcps_sndrexmitpack++; - tcpstat.tcps_sndrexmitbyte += len; - } else { - tcpstat.tcps_sndpack++; - tcpstat.tcps_sndbyte += len; - } - - m = m_get(); - if (m == NULL) { -/* error = ENOBUFS; */ - error = 1; - goto out; - } - m->m_data += if_maxlinkhdr; - m->m_len = hdrlen; - - /* - * This will always succeed, since we make sure our mbufs - * are big enough to hold one MSS packet + header + ... etc. - */ -/* if (len <= MHLEN - hdrlen - max_linkhdr) { */ - - sbcopy(&so->so_snd, off, len, mtod(m, caddr_t) + hdrlen); - m->m_len += len; - -/* } else { - * m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len); - * if (m->m_next == 0) - * len = 0; - * } - */ - /* - * If we're sending everything we've got, set PUSH. - * (This will keep happy those implementations which only - * give data to the user when a buffer fills or - * a PUSH comes in.) - */ - if (off + len == so->so_snd.sb_cc) - flags |= TH_PUSH; - } else { - if (tp->t_flags & TF_ACKNOW) - tcpstat.tcps_sndacks++; - else if (flags & (TH_SYN|TH_FIN|TH_RST)) - tcpstat.tcps_sndctrl++; - else if (SEQ_GT(tp->snd_up, tp->snd_una)) - tcpstat.tcps_sndurg++; - else - tcpstat.tcps_sndwinup++; - - m = m_get(); - if (m == NULL) { -/* error = ENOBUFS; */ - error = 1; - goto out; - } - m->m_data += if_maxlinkhdr; - m->m_len = hdrlen; - } - - ti = mtod(m, struct tcpiphdr *); - - memcpy((caddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr)); - - /* - * Fill in fields, remembering maximum advertised - * window for use in delaying messages about window sizes. - * If resending a FIN, be sure not to use a new sequence number. - */ - if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && - tp->snd_nxt == tp->snd_max) - tp->snd_nxt--; - /* - * If we are doing retransmissions, then snd_nxt will - * not reflect the first unsent octet. For ACK only - * packets, we do not want the sequence number of the - * retransmitted packet, we want the sequence number - * of the next unsent octet. So, if there is no data - * (and no SYN or FIN), use snd_max instead of snd_nxt - * when filling in ti_seq. But if we are in persist - * state, snd_max might reflect one byte beyond the - * right edge of the window, so use snd_nxt in that - * case, since we know we aren't doing a retransmission. - * (retransmit and persist are mutually exclusive...) - */ - if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST]) - ti->ti_seq = htonl(tp->snd_nxt); - else - ti->ti_seq = htonl(tp->snd_max); - ti->ti_ack = htonl(tp->rcv_nxt); - if (optlen) { - memcpy((caddr_t)(ti + 1), (caddr_t)opt, optlen); - ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2; - } - ti->ti_flags = flags; - /* - * Calculate receive window. Don't shrink window, - * but avoid silly window syndrome. - */ - if (win < (so->so_rcv.sb_datalen / 4) && win < tp->t_maxseg) - win = 0; - if (win > (u_long) (TCP_MAXWIN << tp->rcv_scale)) - win = (u_long) (TCP_MAXWIN << tp->rcv_scale); - if (win < (tp->rcv_adv - tp->rcv_nxt)) - win = (tp->rcv_adv - tp->rcv_nxt); - ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale)); - - if (SEQ_GT(tp->snd_up, tp->snd_una)) { - ti->ti_urp = htons((u_int16_t)(tp->snd_up - ntohl(ti->ti_seq))); -#ifdef notdef - if (SEQ_GT(tp->snd_up, tp->snd_nxt)) { - ti->ti_urp = htons((u_int16_t)(tp->snd_up - tp->snd_nxt)); -#endif - ti->ti_flags |= TH_URG; - } else - /* - * If no urgent pointer to send, then we pull - * the urgent pointer to the left edge of the send window - * so that it doesn't drift into the send window on sequence - * number wraparound. - */ - tp->snd_up = tp->snd_una; /* drag it along */ - - /* - * Put TCP length in extended header, and then - * checksum extended header and data. - */ - if (len + optlen) - ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) + - optlen + len)); - ti->ti_sum = cksum(m, (int)(hdrlen + len)); - - /* - * In transmit state, time the transmission and arrange for - * the retransmit. In persist state, just set snd_max. - */ - if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) { - tcp_seq startseq = tp->snd_nxt; - - /* - * Advance snd_nxt over sequence space of this segment. - */ - if (flags & (TH_SYN|TH_FIN)) { - if (flags & TH_SYN) - tp->snd_nxt++; - if (flags & TH_FIN) { - tp->snd_nxt++; - tp->t_flags |= TF_SENTFIN; - } - } - tp->snd_nxt += len; - if (SEQ_GT(tp->snd_nxt, tp->snd_max)) { - tp->snd_max = tp->snd_nxt; - /* - * Time this transmission if not a retransmission and - * not currently timing anything. - */ - if (tp->t_rtt == 0) { - tp->t_rtt = 1; - tp->t_rtseq = startseq; - tcpstat.tcps_segstimed++; - } - } - - /* - * Set retransmit timer if not currently set, - * and not doing an ack or a keep-alive probe. - * Initial value for retransmit timer is smoothed - * round-trip time + 2 * round-trip time variance. - * Initialize shift counter which is used for backoff - * of retransmit time. - */ - if (tp->t_timer[TCPT_REXMT] == 0 && - tp->snd_nxt != tp->snd_una) { - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - if (tp->t_timer[TCPT_PERSIST]) { - tp->t_timer[TCPT_PERSIST] = 0; - tp->t_rxtshift = 0; - } - } - } else - if (SEQ_GT(tp->snd_nxt + len, tp->snd_max)) - tp->snd_max = tp->snd_nxt + len; - - /* - * Fill in IP length and desired time to live and - * send to IP level. There should be a better way - * to handle ttl and tos; we could keep them in - * the template, but need a way to checksum without them. - */ - m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */ - - { - - ((struct ip *)ti)->ip_len = (u_int16_t) m->m_len; - - ((struct ip *)ti)->ip_ttl = ip_defttl; - ((struct ip *)ti)->ip_tos = so->so_iptos; - -/* #if BSD >= 43 */ - /* Don't do IP options... */ -/* error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, - * so->so_options & SO_DONTROUTE, 0); - */ - error = ip_output(so, m); - -/* #else - * error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route, - * so->so_options & SO_DONTROUTE); - * #endif - */ - } - if (error) { -out: -/* if (error == ENOBUFS) { - * tcp_quench(tp->t_inpcb, 0); - * return (0); - * } - */ -/* if ((error == EHOSTUNREACH || error == ENETDOWN) - * && TCPS_HAVERCVDSYN(tp->t_state)) { - * tp->t_softerror = error; - * return (0); - * } - */ - return (error); - } - tcpstat.tcps_sndtotal++; - - /* - * Data sent (as far as we can tell). - * If this advertises a larger window than any other segment, - * then remember the size of the advertised window. - * Any pending ACK has now been sent. - */ - if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv)) - tp->rcv_adv = tp->rcv_nxt + win; - tp->last_ack_sent = tp->rcv_nxt; - tp->t_flags &= ~(TF_ACKNOW|TF_DELACK); - if (sendalot) - goto again; - - return (0); -} - -void tcp_setpersist(register struct tcpcb *tp) -{ - int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1; - -/* if (tp->t_timer[TCPT_REXMT]) - * panic("tcp_output REXMT"); - */ - /* - * Start/restart persistence timer. - */ - TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], - t * tcp_backoff[tp->t_rxtshift], - TCPTV_PERSMIN, TCPTV_PERSMAX); - if (tp->t_rxtshift < TCP_MAXRXTSHIFT) - tp->t_rxtshift++; -} diff --git a/BasiliskII/src/slirp/tcp_subr.c b/BasiliskII/src/slirp/tcp_subr.c deleted file mode 100644 index 70e04b5e..00000000 --- a/BasiliskII/src/slirp/tcp_subr.c +++ /dev/null @@ -1,1296 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)tcp_subr.c 8.1 (Berkeley) 6/10/93 - * tcp_subr.c,v 1.5 1994/10/08 22:39:58 phk Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#define WANT_SYS_IOCTL_H -#include -#include - -/* patchable/settable parameters for tcp */ -int tcp_mssdflt = TCP_MSS; -int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ; -int tcp_do_rfc1323 = 0; /* Don't do rfc1323 performance enhancements */ -size_t tcp_rcvspace; /* You may want to change this */ -size_t tcp_sndspace; /* Keep small if you have an error prone link */ - -/* - * Tcp initialization - */ -void tcp_init() -{ - tcp_iss = 1; /* wrong */ - tcb.so_next = tcb.so_prev = &tcb; - - /* tcp_rcvspace = our Window we advertise to the remote */ - tcp_rcvspace = TCP_RCVSPACE; - tcp_sndspace = TCP_SNDSPACE; - - /* Make sure tcp_sndspace is at least 2*MSS */ - if (tcp_sndspace < 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr))) - tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)); -} - -/* - * Create template to be used to send tcp packets on a connection. - * Call after host entry created, fills - * in a skeletal tcp/ip header, minimizing the amount of work - * necessary when the connection is used. - */ -/* struct tcpiphdr * */ -void tcp_template(struct tcpcb *tp) -{ - struct socket *so = tp->t_socket; - register struct tcpiphdr *n = &tp->t_template; - - n->ti_next = n->ti_prev = 0; - n->ti_x1 = 0; - n->ti_pr = IPPROTO_TCP; - n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); - n->ti_src = so->so_faddr; - n->ti_dst = so->so_laddr; - n->ti_sport = so->so_fport; - n->ti_dport = so->so_lport; - - n->ti_seq = 0; - n->ti_ack = 0; - n->ti_x2 = 0; - n->ti_off = 5; - n->ti_flags = 0; - n->ti_win = 0; - n->ti_sum = 0; - n->ti_urp = 0; -} - -/* - * Send a single message to the TCP at address specified by - * the given TCP/IP header. If m == 0, then we make a copy - * of the tcpiphdr at ti and send directly to the addressed host. - * This is used to force keep alive messages out using the TCP - * template for a connection tp->t_template. If flags are given - * then we send a message back to the TCP which originated the - * segment ti, and discard the mbuf containing it and any other - * attached mbufs. - * - * In any case the ack and sequence number of the transmitted - * segment are as specified by the parameters. - */ -void tcp_respond(struct tcpcb *tp, register struct tcpiphdr *ti, - register struct mbuf *m, tcp_seq ack, tcp_seq seq, int flags) -{ - register int tlen; - int win = 0; - - DEBUG_CALL("tcp_respond"); - DEBUG_ARG("tp = %lx", (long)tp); - DEBUG_ARG("ti = %lx", (long)ti); - DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("ack = %u", ack); - DEBUG_ARG("seq = %u", seq); - DEBUG_ARG("flags = %x", flags); - - if (tp) - win = sbspace(&tp->t_socket->so_rcv); - if (m == 0) { - if ((m = m_get()) == NULL) - return; -#ifdef TCP_COMPAT_42 - tlen = 1; -#else - tlen = 0; -#endif - m->m_data += if_maxlinkhdr; - *mtod(m, struct tcpiphdr *) = *ti; - ti = mtod(m, struct tcpiphdr *); - flags = TH_ACK; - } else { - /* - * ti points into m so the next line is just making - * the mbuf point to ti - */ - m->m_data = (caddr_t)ti; - - m->m_len = sizeof (struct tcpiphdr); - tlen = 0; -#define xchg(a,b,type) { type t; t=a; a=b; b=t; } - xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t); - xchg(ti->ti_dport, ti->ti_sport, u_int16_t); -#undef xchg - } - ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen)); - tlen += sizeof (struct tcpiphdr); - m->m_len = tlen; - - ti->ti_next = ti->ti_prev = 0; - ti->ti_x1 = 0; - ti->ti_seq = htonl(seq); - ti->ti_ack = htonl(ack); - ti->ti_x2 = 0; - ti->ti_off = sizeof (struct tcphdr) >> 2; - ti->ti_flags = flags; - if (tp) - ti->ti_win = htons((u_int16_t) (win >> tp->rcv_scale)); - else - ti->ti_win = htons((u_int16_t)win); - ti->ti_urp = 0; - ti->ti_sum = 0; - ti->ti_sum = cksum(m, tlen); - ((struct ip *)ti)->ip_len = tlen; - - if(flags & TH_RST) - ((struct ip *)ti)->ip_ttl = MAXTTL; - else - ((struct ip *)ti)->ip_ttl = ip_defttl; - - (void) ip_output((struct socket *)0, m); -} - -/* - * Create a new TCP control block, making an - * empty reassembly queue and hooking it to the argument - * protocol control block. - */ -struct tcpcb *tcp_newtcpcb(struct socket *so) -{ - register struct tcpcb *tp; - - tp = (struct tcpcb *)malloc(sizeof(*tp)); - if (tp == NULL) - return ((struct tcpcb *)0); - - memset((char *) tp, 0, sizeof(struct tcpcb)); - tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp; - tp->t_maxseg = tcp_mssdflt; - - tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; - tp->t_socket = so; - - /* - * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no - * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives - * reasonable initial retransmit time. - */ - tp->t_srtt = TCPTV_SRTTBASE; - tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2; - tp->t_rttmin = TCPTV_MIN; - - TCPT_RANGESET(tp->t_rxtcur, - ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1, - TCPTV_MIN, TCPTV_REXMTMAX); - - tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; - tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; - tp->t_state = TCPS_CLOSED; - - so->so_tcpcb = tp; - - return (tp); -} - -/* - * Drop a TCP connection, reporting - * the specified error. If connection is synchronized, - * then send a RST to peer. - */ -struct tcpcb *tcp_drop(struct tcpcb *tp, int err) -{ -/* tcp_drop(tp, errno) - register struct tcpcb *tp; - int errno; -{ -*/ - - DEBUG_CALL("tcp_drop"); - DEBUG_ARG("tp = %lx", (long)tp); - DEBUG_ARG("errno = %d", errno); - - if (TCPS_HAVERCVDSYN(tp->t_state)) { - tp->t_state = TCPS_CLOSED; - (void) tcp_output(tp); - tcpstat.tcps_drops++; - } else - tcpstat.tcps_conndrops++; -/* if (errno == ETIMEDOUT && tp->t_softerror) - * errno = tp->t_softerror; - */ -/* so->so_error = errno; */ - return (tcp_close(tp)); -} - -/* - * Close a TCP control block: - * discard all space held by the tcp - * discard internet protocol block - * wake up any sleepers - */ -struct tcpcb *tcp_close(register struct tcpcb *tp) -{ - register struct tcpiphdr *t; - struct socket *so = tp->t_socket; - register struct mbuf *m; - - DEBUG_CALL("tcp_close"); - DEBUG_ARG("tp = %lx", (long )tp); - - /* free the reassembly queue, if any */ - t = (struct tcpiphdr *) tp->seg_next; - while (t != (struct tcpiphdr *)tp) { - t = (struct tcpiphdr *)t->ti_next; - m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)t->ti_prev); - remque_32((struct tcpiphdr *) t->ti_prev); - m_freem(m); - } - /* It's static */ -/* if (tp->t_template) - * (void) m_free(dtom(tp->t_template)); - */ -/* free(tp, M_PCB); */ - free(tp); - so->so_tcpcb = 0; - soisfdisconnected(so); - /* clobber input socket cache if we're closing the cached connection */ - if (so == tcp_last_so) - tcp_last_so = &tcb; - closesocket(so->s); - sbfree(&so->so_rcv); - sbfree(&so->so_snd); - sofree(so); - tcpstat.tcps_closed++; - return ((struct tcpcb *)0); -} - -void tcp_drain() -{ - /* XXX */ -} - -/* - * When a source quench is received, close congestion window - * to one segment. We will gradually open it again as we proceed. - */ - -#ifdef notdef - -void tcp_quench(int i, int errno) -{ - struct tcpcb *tp = intotcpcb(inp); - - if (tp) - tp->snd_cwnd = tp->t_maxseg; -} - -#endif /* notdef */ - -/* - * TCP protocol interface to socket abstraction. - */ - -/* - * User issued close, and wish to trail through shutdown states: - * if never received SYN, just forget it. If got a SYN from peer, - * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. - * If already got a FIN from peer, then almost done; go to LAST_ACK - * state. In all other cases, have already sent FIN to peer (e.g. - * after PRU_SHUTDOWN), and just have to play tedious game waiting - * for peer to send FIN or not respond to keep-alives, etc. - * We can let the user exit from the close as soon as the FIN is acked. - */ -void tcp_sockclosed(struct tcpcb *tp) -{ - - DEBUG_CALL("tcp_sockclosed"); - DEBUG_ARG("tp = %lx", (long)tp); - - switch (tp->t_state) { - - case TCPS_CLOSED: - case TCPS_LISTEN: - case TCPS_SYN_SENT: - tp->t_state = TCPS_CLOSED; - tp = tcp_close(tp); - break; - - case TCPS_SYN_RECEIVED: - case TCPS_ESTABLISHED: - tp->t_state = TCPS_FIN_WAIT_1; - break; - - case TCPS_CLOSE_WAIT: - tp->t_state = TCPS_LAST_ACK; - break; - } -/* soisfdisconnecting(tp->t_socket); */ - if (tp && tp->t_state >= TCPS_FIN_WAIT_2) - soisfdisconnected(tp->t_socket); - if (tp) - tcp_output(tp); -} - -/* - * Connect to a host on the Internet - * Called by tcp_input - * Only do a connect, the tcp fields will be set in tcp_input - * return 0 if there's a result of the connect, - * else return -1 means we're still connecting - * The return value is almost always -1 since the socket is - * nonblocking. Connect returns after the SYN is sent, and does - * not wait for ACK+SYN. - */ -int tcp_fconnect(struct socket *so) -{ - int ret=0; - - DEBUG_CALL("tcp_fconnect"); - DEBUG_ARG("so = %lx", (long )so); - - if( (ret=so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0) { - int opt, s=so->s; - struct sockaddr_in addr; - memset(&addr, 0, sizeof(struct sockaddr_in)); - - fd_nonblock(s); - opt = 1; - setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt )); - opt = 1; - setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt )); - - addr.sin_family = AF_INET; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { - /* It's an alias */ - switch(ntohl(so->so_faddr.s_addr) & 0xff) { - case CTL_DNS: - addr.sin_addr = dns_addr; - break; - case CTL_ALIAS: - default: - addr.sin_addr = loopback_addr; - break; - } - } else - addr.sin_addr = so->so_faddr; - addr.sin_port = so->so_fport; - - char addrstr[INET_ADDRSTRLEN]; - DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, " - "addr.sin_addr.s_addr=%.16s\n", - ntohs(addr.sin_port), inet_ntop(AF_INET, &addr.sin_addr, - addrstr, sizeof(addrstr)))); - /* We don't care what port we get */ - ret = connect(s,(struct sockaddr *)&addr,sizeof (addr)); - - /* - * If it's not in progress, it failed, so we just return 0, - * without clearing SS_NOFDREF - */ - soisfconnecting(so); - } - - return(ret); -} - -/* - * Accept the socket and connect to the local-host - * - * We have a problem. The correct thing to do would be - * to first connect to the local-host, and only if the - * connection is accepted, then do an accept() here. - * But, a) we need to know who's trying to connect - * to the socket to be able to SYN the local-host, and - * b) we are already connected to the foreign host by - * the time it gets to accept(), so... We simply accept - * here and SYN the local-host. - */ -void tcp_connect(struct socket *inso) -{ - struct socket *so; - struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr_in); - struct tcpcb *tp; - int s, opt; - - DEBUG_CALL("tcp_connect"); - DEBUG_ARG("inso = %lx", (long)inso); - - /* - * If it's an SS_ACCEPTONCE socket, no need to socreate() - * another socket, just use the accept() socket. - */ - if (inso->so_state & SS_FACCEPTONCE) { - /* FACCEPTONCE already have a tcpcb */ - so = inso; - } else { - if ((so = socreate()) == NULL) { - /* If it failed, get rid of the pending connection */ - closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen)); - return; - } - if (tcp_attach(so) < 0) { - free(so); /* NOT sofree */ - return; - } - so->so_laddr = inso->so_laddr; - so->so_lport = inso->so_lport; - } - - tcp_mss(sototcpcb(so), 0); - - if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) { - tcp_close(sototcpcb(so)); /* This will sofree() as well */ - return; - } - fd_nonblock(s); - opt = 1; - setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); - opt = 1; - setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); - opt = 1; - setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int)); - - so->so_fport = addr.sin_port; - so->so_faddr = addr.sin_addr; - /* Translate connections from localhost to the real hostname */ - if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) - so->so_faddr = alias_addr; - - /* Close the accept() socket, set right state */ - if (inso->so_state & SS_FACCEPTONCE) { - closesocket(so->s); /* If we only accept once, close the accept() socket */ - so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */ - /* if it's not FACCEPTONCE, it's already NOFDREF */ - } - so->s = s; - - so->so_iptos = tcp_tos(so); - tp = sototcpcb(so); - - tcp_template(tp); - - /* Compute window scaling to request. */ -/* while (tp->request_r_scale < TCP_MAX_WINSHIFT && - * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) - * tp->request_r_scale++; - */ - -/* soisconnecting(so); */ /* NOFDREF used instead */ - tcpstat.tcps_connattempt++; - - tp->t_state = TCPS_SYN_SENT; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->iss = tcp_iss; - tcp_iss += TCP_ISSINCR/2; - tcp_sendseqinit(tp); - tcp_output(tp); -} - -/* - * Attach a TCPCB to a socket. - */ -int tcp_attach(struct socket *so) -{ - if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) - return -1; - - insque(so, &tcb); - - return 0; -} - -/* - * Set the socket's type of service field - */ -struct tos_t tcptos[] = { - {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */ - {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */ - {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */ - {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */ - {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */ - {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */ - {0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */ - {0, 543, IPTOS_LOWDELAY, 0}, /* klogin */ - {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */ - {0, 6668, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC undernet */ - {0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */ - {0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */ - {0, 0, 0, 0} -}; - -struct emu_t *tcpemu = 0; - -/* - * Return TOS according to the above table - */ -u_int8_t tcp_tos(struct socket *so) -{ - int i = 0; - struct emu_t *emup; - - while(tcptos[i].tos) { - if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) || - (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) { - so->so_emu = tcptos[i].emu; - return tcptos[i].tos; - } - i++; - } - - /* Nope, lets see if there's a user-added one */ - for (emup = tcpemu; emup; emup = emup->next) { - if ((emup->fport && (ntohs(so->so_fport) == emup->fport)) || - (emup->lport && (ntohs(so->so_lport) == emup->lport))) { - so->so_emu = emup->emu; - return emup->tos; - } - } - - return 0; -} - -int do_echo = -1; - -/* - * Emulate programs that try and connect to us - * This includes ftp (the data connection is - * initiated by the server) and IRC (DCC CHAT and - * DCC SEND) for now - * - * NOTE: It's possible to crash SLiRP by sending it - * unstandard strings to emulate... if this is a problem, - * more checks are needed here - * - * XXX Assumes the whole command came in one packet - * - * XXX Some ftp clients will have their TOS set to - * LOWDELAY and so Nagel will kick in. Because of this, - * we'll get the first letter, followed by the rest, so - * we simply scan for ORT instead of PORT... - * DCC doesn't have this problem because there's other stuff - * in the packet before the DCC command. - * - * Return 1 if the mbuf m is still valid and should be - * sbappend()ed - * - * NOTE: if you return 0 you MUST m_free() the mbuf! - */ -int tcp_emu(struct socket *so, struct mbuf *m) -{ - u_int n1, n2, n3, n4, n5, n6; - char buff[256]; - u_int32_t laddr; - u_int lport; - char *bptr; - - DEBUG_CALL("tcp_emu"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("m = %lx", (long)m); - - switch(so->so_emu) { - int x, i; - - case EMU_IDENT: - /* - * Identification protocol as per rfc-1413 - */ - - { - struct socket *tmpso; - struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr_in); - struct sbuf *so_rcv = &so->so_rcv; - - memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); - so_rcv->sb_wptr += m->m_len; - so_rcv->sb_rptr += m->m_len; - m->m_data[m->m_len] = 0; /* NULL terminate */ - if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { - if (sscanf(so_rcv->sb_data, "%d%*[ ,]%d", &n1, &n2) == 2) { - HTONS(n1); - HTONS(n2); - /* n2 is the one on our host */ - for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { - if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr && - tmpso->so_lport == n2 && - tmpso->so_faddr.s_addr == so->so_faddr.s_addr && - tmpso->so_fport == n1) { - if (getsockname(tmpso->s, - (struct sockaddr *)&addr, &addrlen) == 0) - n2 = ntohs(addr.sin_port); - break; - } - } - } - so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2); - so_rcv->sb_rptr = so_rcv->sb_data; - so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; - } - m_free(m); - return 0; - } - -#if 0 - case EMU_RLOGIN: - /* - * Rlogin emulation - * First we accumulate all the initial option negotiation, - * then fork_exec() rlogin according to the options - */ - { - int i, i2, n; - char *ptr; - char args[100]; - char term[100]; - struct sbuf *so_snd = &so->so_snd; - struct sbuf *so_rcv = &so->so_rcv; - - /* First check if they have a priveladged port, or too much data has arrived */ - if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || - (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { - memcpy(so_snd->sb_wptr, "Permission denied\n", 18); - so_snd->sb_wptr += 18; - so_snd->sb_cc += 18; - tcp_sockclosed(sototcpcb(so)); - m_free(m); - return 0; - } - - /* Append the current data */ - memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); - so_rcv->sb_wptr += m->m_len; - so_rcv->sb_rptr += m->m_len; - m_free(m); - - /* - * Check if we have all the initial options, - * and build argument list to rlogin while we're here - */ - n = 0; - ptr = so_rcv->sb_data; - args[0] = 0; - term[0] = 0; - while (ptr < so_rcv->sb_wptr) { - if (*ptr++ == 0) { - n++; - if (n == 2) { - sprintf(args, "rlogin -l %s %s", - ptr, inet_ntoa(so->so_faddr)); - } else if (n == 3) { - i2 = so_rcv->sb_wptr - ptr; - for (i = 0; i < i2; i++) { - if (ptr[i] == '/') { - ptr[i] = 0; -#ifdef HAVE_SETENV - sprintf(term, "%s", ptr); -#else - sprintf(term, "TERM=%s", ptr); -#endif - ptr[i] = '/'; - break; - } - } - } - } - } - - if (n != 4) - return 0; - - /* We have it, set our term variable and fork_exec() */ -#ifdef HAVE_SETENV - setenv("TERM", term, 1); -#else - putenv(term); -#endif - fork_exec(so, args, 2); - term[0] = 0; - so->so_emu = 0; - - /* And finally, send the client a 0 character */ - so_snd->sb_wptr[0] = 0; - so_snd->sb_wptr++; - so_snd->sb_cc++; - - return 0; - } - - case EMU_RSH: - /* - * rsh emulation - * First we accumulate all the initial option negotiation, - * then rsh_exec() rsh according to the options - */ - { - int n; - char *ptr; - char *user; - char *args; - struct sbuf *so_snd = &so->so_snd; - struct sbuf *so_rcv = &so->so_rcv; - - /* First check if they have a priveladged port, or too much data has arrived */ - if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || - (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { - memcpy(so_snd->sb_wptr, "Permission denied\n", 18); - so_snd->sb_wptr += 18; - so_snd->sb_cc += 18; - tcp_sockclosed(sototcpcb(so)); - m_free(m); - return 0; - } - - /* Append the current data */ - memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); - so_rcv->sb_wptr += m->m_len; - so_rcv->sb_rptr += m->m_len; - m_free(m); - - /* - * Check if we have all the initial options, - * and build argument list to rlogin while we're here - */ - n = 0; - ptr = so_rcv->sb_data; - user=""; - args=""; - if (so->extra==NULL) { - struct socket *ns; - struct tcpcb* tp; - int port=atoi(ptr); - if (port <= 0) return 0; - if (port > 1023 || port < 512) { - memcpy(so_snd->sb_wptr, "Permission denied\n", 18); - so_snd->sb_wptr += 18; - so_snd->sb_cc += 18; - tcp_sockclosed(sototcpcb(so)); - return 0; - } - if ((ns=socreate()) == NULL) - return 0; - if (tcp_attach(ns)<0) { - free(ns); - return 0; - } - - ns->so_laddr=so->so_laddr; - ns->so_lport=htons(port); - - tcp_mss(sototcpcb(ns), 0); - - ns->so_faddr=so->so_faddr; - ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */ - - if (ns->so_faddr.s_addr == 0 || - ns->so_faddr.s_addr == loopback_addr.s_addr) - ns->so_faddr = alias_addr; - - ns->so_iptos = tcp_tos(ns); - tp = sototcpcb(ns); - - tcp_template(tp); - - /* Compute window scaling to request. */ - /* while (tp->request_r_scale < TCP_MAX_WINSHIFT && - * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) - * tp->request_r_scale++; - */ - - /*soisfconnecting(ns);*/ - - tcpstat.tcps_connattempt++; - - tp->t_state = TCPS_SYN_SENT; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->iss = tcp_iss; - tcp_iss += TCP_ISSINCR/2; - tcp_sendseqinit(tp); - tcp_output(tp); - so->extra=ns; - } - while (ptr < so_rcv->sb_wptr) { - if (*ptr++ == 0) { - n++; - if (n == 2) { - user=ptr; - } else if (n == 3) { - args=ptr; - } - } - } - - if (n != 4) - return 0; - - rsh_exec(so,so->extra, user, inet_ntoa(so->so_faddr), args); - so->so_emu = 0; - so->extra=NULL; - - /* And finally, send the client a 0 character */ - so_snd->sb_wptr[0] = 0; - so_snd->sb_wptr++; - so_snd->sb_cc++; - - return 0; - } - - case EMU_CTL: - { - int num; - struct sbuf *so_snd = &so->so_snd; - struct sbuf *so_rcv = &so->so_rcv; - - /* - * If there is binary data here, we save it in so->so_m - */ - if (!so->so_m) { - int rxlen; - char *rxdata; - rxdata=mtod(m, char *); - for (rxlen=m->m_len; rxlen; rxlen--) { - if (*rxdata++ & 0x80) { - so->so_m = m; - return 0; - } - } - } /* if(so->so_m==NULL) */ - - /* - * Append the line - */ - sbappendsb(so_rcv, m); - - /* To avoid going over the edge of the buffer, we reset it */ - if (so_snd->sb_cc == 0) - so_snd->sb_wptr = so_snd->sb_rptr = so_snd->sb_data; - - /* - * A bit of a hack: - * If the first packet we get here is 1 byte long, then it - * was done in telnet character mode, therefore we must echo - * the characters as they come. Otherwise, we echo nothing, - * because in linemode, the line is already echoed - * XXX two or more control connections won't work - */ - if (do_echo == -1) { - if (m->m_len == 1) do_echo = 1; - else do_echo = 0; - } - if (do_echo) { - sbappendsb(so_snd, m); - m_free(m); - tcp_output(sototcpcb(so)); /* XXX */ - } else - m_free(m); - - num = 0; - while (num < so->so_rcv.sb_cc) { - if (*(so->so_rcv.sb_rptr + num) == '\n' || - *(so->so_rcv.sb_rptr + num) == '\r') { - int n; - - *(so_rcv->sb_rptr + num) = 0; - if (ctl_password && !ctl_password_ok) { - /* Need a password */ - if (sscanf(so_rcv->sb_rptr, "pass %256s", buff) == 1) { - if (strcmp(buff, ctl_password) == 0) { - ctl_password_ok = 1; - n = sprintf(so_snd->sb_wptr, - "Password OK.\r\n"); - goto do_prompt; - } - } - n = sprintf(so_snd->sb_wptr, - "Error: Password required, log on with \"pass PASSWORD\"\r\n"); - goto do_prompt; - } - cfg_quitting = 0; - n = do_config(so_rcv->sb_rptr, so, PRN_SPRINTF); - if (!cfg_quitting) { - /* Register the printed data */ -do_prompt: - so_snd->sb_cc += n; - so_snd->sb_wptr += n; - /* Add prompt */ - n = sprintf(so_snd->sb_wptr, "Slirp> "); - so_snd->sb_cc += n; - so_snd->sb_wptr += n; - } - /* Drop so_rcv data */ - so_rcv->sb_cc = 0; - so_rcv->sb_wptr = so_rcv->sb_rptr = so_rcv->sb_data; - tcp_output(sototcpcb(so)); /* Send the reply */ - } - num++; - } - return 0; - } -#endif - case EMU_FTP: /* ftp */ - *(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */ - if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) { - /* - * Need to emulate the PORT command - */ - x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]", - &n1, &n2, &n3, &n4, &n5, &n6, buff); - if (x < 6) - return 1; - - laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); - lport = htons((n5 << 8) | (n6)); - - if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) - return 1; - - n6 = ntohs(so->so_fport); - - n5 = (n6 >> 8) & 0xff; - n6 &= 0xff; - - laddr = ntohl(so->so_faddr.s_addr); - - n1 = ((laddr >> 24) & 0xff); - n2 = ((laddr >> 16) & 0xff); - n3 = ((laddr >> 8) & 0xff); - n4 = (laddr & 0xff); - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s", - n1, n2, n3, n4, n5, n6, x==7?buff:""); - return 1; - } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { - /* - * Need to emulate the PASV response - */ - x = sscanf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%256[^\177]", - &n1, &n2, &n3, &n4, &n5, &n6, buff); - if (x < 6) - return 1; - - laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); - lport = htons((n5 << 8) | (n6)); - - if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) - return 1; - - n6 = ntohs(so->so_fport); - - n5 = (n6 >> 8) & 0xff; - n6 &= 0xff; - - laddr = ntohl(so->so_faddr.s_addr); - - n1 = ((laddr >> 24) & 0xff); - n2 = ((laddr >> 16) & 0xff); - n3 = ((laddr >> 8) & 0xff); - n4 = (laddr & 0xff); - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", - n1, n2, n3, n4, n5, n6, x==7?buff:""); - - return 1; - } - - return 1; - - case EMU_KSH: - /* - * The kshell (Kerberos rsh) and shell services both pass - * a local port port number to carry signals to the server - * and stderr to the client. It is passed at the beginning - * of the connection as a NUL-terminated decimal ASCII string. - */ - so->so_emu = 0; - for (lport = 0, i = 0; i < (int) (m->m_len-1); ++i) { - if (m->m_data[i] < '0' || m->m_data[i] > '9') - return 1; /* invalid number */ - lport *= 10; - lport += m->m_data[i] - '0'; - } - if (m->m_data[m->m_len-1] == '\0' && lport != 0 && - (so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL) - m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1; - return 1; - - case EMU_IRC: - /* - * Need to emulate DCC CHAT, DCC SEND and DCC MOVE - */ - *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */ - if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) - return 1; - - /* The %256s is for the broken mIRC */ - if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) { - if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) - return 1; - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n", - (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), 1); - } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { - if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) - return 1; - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n", - buff, (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), n1, 1); - } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { - if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) - return 1; - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n", - buff, (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), n1, 1); - } - return 1; - - case EMU_REALAUDIO: - /* - * RealAudio emulation - JP. We must try to parse the incoming - * data and try to find the two characters that contain the - * port number. Then we redirect an udp port and replace the - * number with the real port we got. - * - * The 1.0 beta versions of the player are not supported - * any more. - * - * A typical packet for player version 1.0 (release version): - * - * 0000:50 4E 41 00 05 - * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....×..gælÜc..P - * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH - * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v - * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB - * - * Now the port number 0x1BD7 is found at offset 0x04 of the - * Now the port number 0x1BD7 is found at offset 0x04 of the - * second packet. This time we received five bytes first and - * then the rest. You never know how many bytes you get. - * - * A typical packet for player version 2.0 (beta): - * - * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........Á. - * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxõc..Win2.0.0 - * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ - * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas - * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B - * - * Port number 0x1BC1 is found at offset 0x0d. - * - * This is just a horrible switch statement. Variable ra tells - * us where we're going. - */ - - bptr = m->m_data; - while (bptr < m->m_data + m->m_len) { - u_short p; - static int ra = 0; - char ra_tbl[4]; - - ra_tbl[0] = 0x50; - ra_tbl[1] = 0x4e; - ra_tbl[2] = 0x41; - ra_tbl[3] = 0; - - switch (ra) { - case 0: - case 2: - case 3: - if (*bptr++ != ra_tbl[ra]) { - ra = 0; - continue; - } - break; - - case 1: - /* - * We may get 0x50 several times, ignore them - */ - if (*bptr == 0x50) { - ra = 1; - bptr++; - continue; - } else if (*bptr++ != ra_tbl[ra]) { - ra = 0; - continue; - } - break; - - case 4: - /* - * skip version number - */ - bptr++; - break; - - case 5: - /* - * The difference between versions 1.0 and - * 2.0 is here. For future versions of - * the player this may need to be modified. - */ - if (*(bptr + 1) == 0x02) - bptr += 8; - else - bptr += 4; - break; - - case 6: - /* This is the field containing the port - * number that RA-player is listening to. - */ - lport = (((u_char*)bptr)[0] << 8) - + ((u_char *)bptr)[1]; - if (lport < 6970) - lport += 256; /* don't know why */ - if (lport < 6970 || lport > 7170) - return 1; /* failed */ - - /* try to get udp port between 6970 - 7170 */ - for (p = 6970; p < 7071; p++) { - if (udp_listen( htons(p), - so->so_laddr.s_addr, - htons(lport), - SS_FACCEPTONCE)) { - break; - } - } - if (p == 7071) - p = 0; - *(u_char *)bptr++ = (p >> 8) & 0xff; - *(u_char *)bptr++ = p & 0xff; - ra = 0; - return 1; /* port redirected, we're done */ - break; - - default: - ra = 0; - } - ra++; - } - return 1; - - default: - /* Ooops, not emulated, won't call tcp_emu again */ - so->so_emu = 0; - return 1; - } -} - -/* - * Do misc. config of SLiRP while its running. - * Return 0 if this connections is to be closed, 1 otherwise, - * return 2 if this is a command-line connection - */ -int tcp_ctl(struct socket *so) -{ - struct sbuf *sb = &so->so_snd; - int command; - struct ex_list *ex_ptr; - int do_pty; - // struct socket *tmpso; - - DEBUG_CALL("tcp_ctl"); - DEBUG_ARG("so = %lx", (long )so); - -#if 0 - /* - * Check if they're authorised - */ - if (ctl_addr.s_addr && (ctl_addr.s_addr == -1 || (so->so_laddr.s_addr != ctl_addr.s_addr))) { - sb->sb_cc = sprintf(sb->sb_wptr,"Error: Permission denied.\r\n"); - sb->sb_wptr += sb->sb_cc; - return 0; - } -#endif - command = (ntohl(so->so_faddr.s_addr) & 0xff); - - switch(command) { - default: /* Check for exec's */ - - /* - * Check if it's pty_exec - */ - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->ex_fport == so->so_fport && - command == ex_ptr->ex_addr) { - do_pty = ex_ptr->ex_pty; - goto do_exec; - } - } - - /* - * Nothing bound.. - */ - /* tcp_fconnect(so); */ - - /* FALLTHROUGH */ - case CTL_ALIAS: - sb->sb_cc = sprintf(sb->sb_wptr, - "Error: No application configured.\r\n"); - sb->sb_wptr += sb->sb_cc; - return(0); - - do_exec: - DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec)); - return(fork_exec(so, ex_ptr->ex_exec, do_pty)); - -#if 0 - case CTL_CMD: - for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { - if (tmpso->so_emu == EMU_CTL && - !(tmpso->so_tcpcb? - (tmpso->so_tcpcb->t_state & (TCPS_TIME_WAIT|TCPS_LAST_ACK)) - :0)) { - /* Ooops, control connection already active */ - sb->sb_cc = sprintf(sb->sb_wptr,"Sorry, already connected.\r\n"); - sb->sb_wptr += sb->sb_cc; - return 0; - } - } - so->so_emu = EMU_CTL; - ctl_password_ok = 0; - sb->sb_cc = sprintf(sb->sb_wptr, "Slirp command-line ready (type \"help\" for help).\r\nSlirp> "); - sb->sb_wptr += sb->sb_cc; - do_echo=-1; - return(2); -#endif - } -} diff --git a/BasiliskII/src/slirp/tcp_timer.c b/BasiliskII/src/slirp/tcp_timer.c deleted file mode 100644 index ab9aa580..00000000 --- a/BasiliskII/src/slirp/tcp_timer.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)tcp_timer.c 8.1 (Berkeley) 6/10/93 - * tcp_timer.c,v 1.2 1994/08/02 07:49:10 davidg Exp - */ - -#include - -int tcp_keepidle = TCPTV_KEEP_IDLE; -int tcp_keepintvl = TCPTV_KEEPINTVL; -int tcp_maxidle; -int so_options = DO_KEEPALIVE; - -struct tcpstat tcpstat; /* tcp statistics */ -u_int32_t tcp_now; /* for RFC 1323 timestamps */ - -/* - * Fast timeout routine for processing delayed acks - */ -void -tcp_fasttimo() -{ - register struct socket *so; - register struct tcpcb *tp; - - DEBUG_CALL("tcp_fasttimo"); - - so = tcb.so_next; - if (so) - for (; so != &tcb; so = so->so_next) - if ((tp = (struct tcpcb *)so->so_tcpcb) && - (tp->t_flags & TF_DELACK)) { - tp->t_flags &= ~TF_DELACK; - tp->t_flags |= TF_ACKNOW; - tcpstat.tcps_delack++; - (void) tcp_output(tp); - } -} - -/* - * Tcp protocol timeout routine called every 500 ms. - * Updates the timers in all active tcb's and - * causes finite state machine actions if timers expire. - */ -void -tcp_slowtimo() -{ - register struct socket *ip, *ipnxt; - register struct tcpcb *tp; - register int i; - - DEBUG_CALL("tcp_slowtimo"); - - tcp_maxidle = TCPTV_KEEPCNT * tcp_keepintvl; - /* - * Search through tcb's and update active timers. - */ - ip = tcb.so_next; - if (ip == 0) - return; - for (; ip != &tcb; ip = ipnxt) { - ipnxt = ip->so_next; - tp = sototcpcb(ip); - if (tp == 0) - continue; - for (i = 0; i < TCPT_NTIMERS; i++) { - if (tp->t_timer[i] && --tp->t_timer[i] == 0) { - tcp_timers(tp,i); - if (ipnxt->so_prev != ip) - goto tpgone; - } - } - tp->t_idle++; - if (tp->t_rtt) - tp->t_rtt++; -tpgone: - ; - } - tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */ -#ifdef TCP_COMPAT_42 - if ((int)tcp_iss < 0) - tcp_iss = 0; /* XXX */ -#endif - tcp_now++; /* for timestamps */ -} - -/* - * Cancel all timers for TCP tp. - */ -void -tcp_canceltimers(tp) - struct tcpcb *tp; -{ - register int i; - - for (i = 0; i < TCPT_NTIMERS; i++) - tp->t_timer[i] = 0; -} - -int tcp_backoff[TCP_MAXRXTSHIFT + 1] = - { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 }; - -/* - * TCP timer processing. - */ -struct tcpcb * -tcp_timers(tp, timer) - register struct tcpcb *tp; - int timer; -{ - register int rexmt; - - DEBUG_CALL("tcp_timers"); - - switch (timer) { - - /* - * 2 MSL timeout in shutdown went off. If we're closed but - * still waiting for peer to close and connection has been idle - * too long, or if 2MSL time is up from TIME_WAIT, delete connection - * control block. Otherwise, check again in a bit. - */ - case TCPT_2MSL: - if (tp->t_state != TCPS_TIME_WAIT && - tp->t_idle <= tcp_maxidle) - tp->t_timer[TCPT_2MSL] = tcp_keepintvl; - else - tp = tcp_close(tp); - break; - - /* - * Retransmission timer went off. Message has not - * been acked within retransmit interval. Back off - * to a longer retransmit interval and retransmit one segment. - */ - case TCPT_REXMT: - - /* - * XXXXX If a packet has timed out, then remove all the queued - * packets for that session. - */ - - if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) { - /* - * This is a hack to suit our terminal server here at the uni of canberra - * since they have trouble with zeroes... It usually lets them through - * unharmed, but under some conditions, it'll eat the zeros. If we - * keep retransmitting it, it'll keep eating the zeroes, so we keep - * retransmitting, and eventually the connection dies... - * (this only happens on incoming data) - * - * So, if we were gonna drop the connection from too many retransmits, - * don't... instead halve the t_maxseg, which might break up the NULLs and - * let them through - * - * *sigh* - */ - - tp->t_maxseg >>= 1; - if (tp->t_maxseg < 32) { - /* - * We tried our best, now the connection must die! - */ - tp->t_rxtshift = TCP_MAXRXTSHIFT; - tcpstat.tcps_timeoutdrop++; - tp = tcp_drop(tp, tp->t_softerror); - /* tp->t_softerror : ETIMEDOUT); */ /* XXX */ - return (tp); /* XXX */ - } - - /* - * Set rxtshift to 6, which is still at the maximum - * backoff time - */ - tp->t_rxtshift = 6; - } - tcpstat.tcps_rexmttimeo++; - rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift]; - TCPT_RANGESET(tp->t_rxtcur, rexmt, - (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */ - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - /* - * If losing, let the lower level know and try for - * a better route. Also, if we backed off this far, - * our srtt estimate is probably bogus. Clobber it - * so we'll take the next rtt measurement as our srtt; - * move the current srtt into rttvar to keep the current - * retransmit times until then. - */ - if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) { -/* in_losing(tp->t_inpcb); */ - tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT); - tp->t_srtt = 0; - } - tp->snd_nxt = tp->snd_una; - /* - * If timing a segment in this window, stop the timer. - */ - tp->t_rtt = 0; - /* - * Close the congestion window down to one segment - * (we'll open it by one segment for each ack we get). - * Since we probably have a window's worth of unacked - * data accumulated, this "slow start" keeps us from - * dumping all that data as back-to-back packets (which - * might overwhelm an intermediate gateway). - * - * There are two phases to the opening: Initially we - * open by one mss on each ack. This makes the window - * size increase exponentially with time. If the - * window is larger than the path can handle, this - * exponential growth results in dropped packet(s) - * almost immediately. To get more time between - * drops but still "push" the network to take advantage - * of improving conditions, we switch from exponential - * to linear window opening at some threshold size. - * For a threshold, we use half the current window - * size, truncated to a multiple of the mss. - * - * (the minimum cwnd that will give us exponential - * growth is 2 mss. We don't allow the threshold - * to go below this.) - */ - { - u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg; - if (win < 2) - win = 2; - tp->snd_cwnd = tp->t_maxseg; - tp->snd_ssthresh = win * tp->t_maxseg; - tp->t_dupacks = 0; - } - (void) tcp_output(tp); - break; - - /* - * Persistence timer into zero window. - * Force a byte to be output, if possible. - */ - case TCPT_PERSIST: - tcpstat.tcps_persisttimeo++; - tcp_setpersist(tp); - tp->t_force = 1; - (void) tcp_output(tp); - tp->t_force = 0; - break; - - /* - * Keep-alive timer went off; send something - * or drop connection if idle for too long. - */ - case TCPT_KEEP: - tcpstat.tcps_keeptimeo++; - if (tp->t_state < TCPS_ESTABLISHED) - goto dropit; - -/* if (tp->t_socket->so_options & SO_KEEPALIVE && */ - if ((so_options) && tp->t_state <= TCPS_CLOSE_WAIT) { - if (tp->t_idle >= tcp_keepidle + tcp_maxidle) - goto dropit; - /* - * Send a packet designed to force a response - * if the peer is up and reachable: - * either an ACK if the connection is still alive, - * or an RST if the peer has closed the connection - * due to timeout or reboot. - * Using sequence number tp->snd_una-1 - * causes the transmitted zero-length segment - * to lie outside the receive window; - * by the protocol spec, this requires the - * correspondent TCP to respond. - */ - tcpstat.tcps_keepprobe++; -#ifdef TCP_COMPAT_42 - /* - * The keepalive packet must have nonzero length - * to get a 4.2 host to respond. - */ - tcp_respond(tp, &tp->t_template, (struct mbuf *)NULL, - tp->rcv_nxt - 1, tp->snd_una - 1, 0); -#else - tcp_respond(tp, &tp->t_template, (struct mbuf *)NULL, - tp->rcv_nxt, tp->snd_una - 1, 0); -#endif - tp->t_timer[TCPT_KEEP] = tcp_keepintvl; - } else - tp->t_timer[TCPT_KEEP] = tcp_keepidle; - break; - - dropit: - tcpstat.tcps_keepdrops++; - tp = tcp_drop(tp, 0); /* ETIMEDOUT); */ - break; - } - - return (tp); -} diff --git a/BasiliskII/src/slirp/tcp_timer.h b/BasiliskII/src/slirp/tcp_timer.h deleted file mode 100644 index 73fe2089..00000000 --- a/BasiliskII/src/slirp/tcp_timer.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)tcp_timer.h 8.1 (Berkeley) 6/10/93 - * tcp_timer.h,v 1.4 1994/08/21 05:27:38 paul Exp - */ - -#ifndef _TCP_TIMER_H_ -#define _TCP_TIMER_H_ - -/* - * Definitions of the TCP timers. These timers are counted - * down PR_SLOWHZ times a second. - */ -#define TCPT_NTIMERS 4 - -#define TCPT_REXMT 0 /* retransmit */ -#define TCPT_PERSIST 1 /* retransmit persistence */ -#define TCPT_KEEP 2 /* keep alive */ -#define TCPT_2MSL 3 /* 2*msl quiet time timer */ - -/* - * The TCPT_REXMT timer is used to force retransmissions. - * The TCP has the TCPT_REXMT timer set whenever segments - * have been sent for which ACKs are expected but not yet - * received. If an ACK is received which advances tp->snd_una, - * then the retransmit timer is cleared (if there are no more - * outstanding segments) or reset to the base value (if there - * are more ACKs expected). Whenever the retransmit timer goes off, - * we retransmit one unacknowledged segment, and do a backoff - * on the retransmit timer. - * - * The TCPT_PERSIST timer is used to keep window size information - * flowing even if the window goes shut. If all previous transmissions - * have been acknowledged (so that there are no retransmissions in progress), - * and the window is too small to bother sending anything, then we start - * the TCPT_PERSIST timer. When it expires, if the window is nonzero, - * we go to transmit state. Otherwise, at intervals send a single byte - * into the peer's window to force him to update our window information. - * We do this at most as often as TCPT_PERSMIN time intervals, - * but no more frequently than the current estimate of round-trip - * packet time. The TCPT_PERSIST timer is cleared whenever we receive - * a window update from the peer. - * - * The TCPT_KEEP timer is used to keep connections alive. If an - * connection is idle (no segments received) for TCPTV_KEEP_INIT amount of time, - * but not yet established, then we drop the connection. Once the connection - * is established, if the connection is idle for TCPTV_KEEP_IDLE time - * (and keepalives have been enabled on the socket), we begin to probe - * the connection. We force the peer to send us a segment by sending: - * - * This segment is (deliberately) outside the window, and should elicit - * an ack segment in response from the peer. If, despite the TCPT_KEEP - * initiated segments we cannot elicit a response from a peer in TCPT_MAXIDLE - * amount of time probing, then we drop the connection. - */ - -/* - * Time constants. - */ -#define TCPTV_MSL ( 5*PR_SLOWHZ) /* max seg lifetime (hah!) */ - -#define TCPTV_SRTTBASE 0 /* base roundtrip time; - if 0, no idea yet */ -#define TCPTV_SRTTDFLT ( 3*PR_SLOWHZ) /* assumed RTT if no info */ - -#define TCPTV_PERSMIN ( 5*PR_SLOWHZ) /* retransmit persistence */ -#define TCPTV_PERSMAX ( 60*PR_SLOWHZ) /* maximum persist interval */ - -#define TCPTV_KEEP_INIT ( 75*PR_SLOWHZ) /* initial connect keep alive */ -#define TCPTV_KEEP_IDLE (120*60*PR_SLOWHZ) /* dflt time before probing */ -#define TCPTV_KEEPINTVL ( 75*PR_SLOWHZ) /* default probe interval */ -#define TCPTV_KEEPCNT 8 /* max probes before drop */ - -#define TCPTV_MIN ( 1*PR_SLOWHZ) /* minimum allowable value */ -/* #define TCPTV_REXMTMAX ( 64*PR_SLOWHZ) */ /* max allowable REXMT value */ -#define TCPTV_REXMTMAX ( 12*PR_SLOWHZ) /* max allowable REXMT value */ - -#define TCP_LINGERTIME 120 /* linger at most 2 minutes */ - -#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */ - - -#ifdef TCPTIMERS -char *tcptimers[] = - { "REXMT", "PERSIST", "KEEP", "2MSL" }; -#endif - -/* - * Force a time value to be in a certain range. - */ -#define TCPT_RANGESET(tv, value, tvmin, tvmax) { \ - (tv) = (value); \ - if ((tv) < (tvmin)) \ - (tv) = (tvmin); \ - else if ((tv) > (tvmax)) \ - (tv) = (tvmax); \ -} - -extern int tcp_keepidle; /* time before keepalive probes begin */ -extern int tcp_keepintvl; /* time between keepalive probes */ -extern int tcp_maxidle; /* time to drop after starting probes */ -extern int tcp_ttl; /* time to live for TCP segs */ -extern int tcp_backoff[]; - -struct tcpcb; - -void tcp_fasttimo(void); -void tcp_slowtimo(void); -void tcp_canceltimers(struct tcpcb *); -struct tcpcb * tcp_timers(register struct tcpcb *, int); - -#endif diff --git a/BasiliskII/src/slirp/tcp_var.h b/BasiliskII/src/slirp/tcp_var.h deleted file mode 100644 index c8e99ae0..00000000 --- a/BasiliskII/src/slirp/tcp_var.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)tcp_var.h 8.3 (Berkeley) 4/10/94 - * tcp_var.h,v 1.3 1994/08/21 05:27:39 paul Exp - */ - -#ifndef _TCP_VAR_H_ -#define _TCP_VAR_H_ - -#include "tcpip.h" -#include "tcp_timer.h" - -#if SIZEOF_CHAR_P == 4 - typedef struct tcpiphdr *tcpiphdrp_32; -#else - typedef u_int32_t tcpiphdrp_32; -#endif - -/* - * Tcp control block, one per tcp; fields: - */ -struct tcpcb { - tcpiphdrp_32 seg_next; /* sequencing queue */ - tcpiphdrp_32 seg_prev; - short t_state; /* state of this connection */ - short t_timer[TCPT_NTIMERS]; /* tcp timers */ - short t_rxtshift; /* log(2) of rexmt exp. backoff */ - short t_rxtcur; /* current retransmit value */ - short t_dupacks; /* consecutive dup acks recd */ - u_short t_maxseg; /* maximum segment size */ - char t_force; /* 1 if forcing out a byte */ - u_short t_flags; -#define TF_ACKNOW 0x0001 /* ack peer immediately */ -#define TF_DELACK 0x0002 /* ack, but try to delay it */ -#define TF_NODELAY 0x0004 /* don't delay packets to coalesce */ -#define TF_NOOPT 0x0008 /* don't use tcp options */ -#define TF_SENTFIN 0x0010 /* have sent FIN */ -#define TF_REQ_SCALE 0x0020 /* have/will request window scaling */ -#define TF_RCVD_SCALE 0x0040 /* other side has requested scaling */ -#define TF_REQ_TSTMP 0x0080 /* have/will request timestamps */ -#define TF_RCVD_TSTMP 0x0100 /* a timestamp was received in SYN */ -#define TF_SACK_PERMIT 0x0200 /* other side said I could SACK */ - - /* Make it static for now */ -/* struct tcpiphdr *t_template; / * skeletal packet for transmit */ - struct tcpiphdr t_template; - - struct socket *t_socket; /* back pointer to socket */ -/* - * The following fields are used as in the protocol specification. - * See RFC783, Dec. 1981, page 21. - */ -/* send sequence variables */ - tcp_seq snd_una; /* send unacknowledged */ - tcp_seq snd_nxt; /* send next */ - tcp_seq snd_up; /* send urgent pointer */ - tcp_seq snd_wl1; /* window update seg seq number */ - tcp_seq snd_wl2; /* window update seg ack number */ - tcp_seq iss; /* initial send sequence number */ - u_int32_t snd_wnd; /* send window */ -/* receive sequence variables */ - u_int32_t rcv_wnd; /* receive window */ - tcp_seq rcv_nxt; /* receive next */ - tcp_seq rcv_up; /* receive urgent pointer */ - tcp_seq irs; /* initial receive sequence number */ -/* - * Additional variables for this implementation. - */ -/* receive variables */ - tcp_seq rcv_adv; /* advertised window */ -/* retransmit variables */ - tcp_seq snd_max; /* highest sequence number sent; - * used to recognize retransmits - */ -/* congestion control (for slow start, source quench, retransmit after loss) */ - u_int32_t snd_cwnd; /* congestion-controlled window */ - u_int32_t snd_ssthresh; /* snd_cwnd size threshold for - * for slow start exponential to - * linear switch - */ -/* - * transmit timing stuff. See below for scale of srtt and rttvar. - * "Variance" is actually smoothed difference. - */ - short t_idle; /* inactivity time */ - short t_rtt; /* round trip time */ - tcp_seq t_rtseq; /* sequence number being timed */ - short t_srtt; /* smoothed round-trip time */ - short t_rttvar; /* variance in round-trip time */ - u_short t_rttmin; /* minimum rtt allowed */ - u_int32_t max_sndwnd; /* largest window peer has offered */ - -/* out-of-band data */ - char t_oobflags; /* have some */ - char t_iobc; /* input character */ -#define TCPOOB_HAVEDATA 0x01 -#define TCPOOB_HADDATA 0x02 - short t_softerror; /* possible error not yet reported */ - -/* RFC 1323 variables */ - u_char snd_scale; /* window scaling for send window */ - u_char rcv_scale; /* window scaling for recv window */ - u_char request_r_scale; /* pending window scaling */ - u_char requested_s_scale; - u_int32_t ts_recent; /* timestamp echo data */ - u_int32_t ts_recent_age; /* when last updated */ - tcp_seq last_ack_sent; - -}; - -#define sototcpcb(so) ((so)->so_tcpcb) - -/* - * The smoothed round-trip time and estimated variance - * are stored as fixed point numbers scaled by the values below. - * For convenience, these scales are also used in smoothing the average - * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed). - * With these scales, srtt has 3 bits to the right of the binary point, - * and thus an "ALPHA" of 0.875. rttvar has 2 bits to the right of the - * binary point, and is smoothed with an ALPHA of 0.75. - */ -#define TCP_RTT_SCALE 8 /* multiplier for srtt; 3 bits frac. */ -#define TCP_RTT_SHIFT 3 /* shift for srtt; 3 bits frac. */ -#define TCP_RTTVAR_SCALE 4 /* multiplier for rttvar; 2 bits */ -#define TCP_RTTVAR_SHIFT 2 /* multiplier for rttvar; 2 bits */ - -/* - * The initial retransmission should happen at rtt + 4 * rttvar. - * Because of the way we do the smoothing, srtt and rttvar - * will each average +1/2 tick of bias. When we compute - * the retransmit timer, we want 1/2 tick of rounding and - * 1 extra tick because of +-1/2 tick uncertainty in the - * firing of the timer. The bias will give us exactly the - * 1.5 tick we need. But, because the bias is - * statistical, we have to test that we don't drop below - * the minimum feasible timer (which is 2 ticks). - * This macro assumes that the value of TCP_RTTVAR_SCALE - * is the same as the multiplier for rttvar. - */ -#define TCP_REXMTVAL(tp) \ - (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) - -/* XXX - * We want to avoid doing m_pullup on incoming packets but that - * means avoiding dtom on the tcp reassembly code. That in turn means - * keeping an mbuf pointer in the reassembly queue (since we might - * have a cluster). As a quick hack, the source & destination - * port numbers (which are no longer needed once we've located the - * tcpcb) are overlayed with an mbuf pointer. - */ -#if SIZEOF_CHAR_P == 4 -typedef struct mbuf *mbufp_32; -#else -typedef u_int32_t mbufp_32; -#endif -#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t)) - -/* - * TCP statistics. - * Many of these should be kept per connection, - * but that's inconvenient at the moment. - */ -struct tcpstat { - u_long tcps_connattempt; /* connections initiated */ - u_long tcps_accepts; /* connections accepted */ - u_long tcps_connects; /* connections established */ - u_long tcps_drops; /* connections dropped */ - u_long tcps_conndrops; /* embryonic connections dropped */ - u_long tcps_closed; /* conn. closed (includes drops) */ - u_long tcps_segstimed; /* segs where we tried to get rtt */ - u_long tcps_rttupdated; /* times we succeeded */ - u_long tcps_delack; /* delayed acks sent */ - u_long tcps_timeoutdrop; /* conn. dropped in rxmt timeout */ - u_long tcps_rexmttimeo; /* retransmit timeouts */ - u_long tcps_persisttimeo; /* persist timeouts */ - u_long tcps_keeptimeo; /* keepalive timeouts */ - u_long tcps_keepprobe; /* keepalive probes sent */ - u_long tcps_keepdrops; /* connections dropped in keepalive */ - - u_long tcps_sndtotal; /* total packets sent */ - u_long tcps_sndpack; /* data packets sent */ - u_long tcps_sndbyte; /* data bytes sent */ - u_long tcps_sndrexmitpack; /* data packets retransmitted */ - u_long tcps_sndrexmitbyte; /* data bytes retransmitted */ - u_long tcps_sndacks; /* ack-only packets sent */ - u_long tcps_sndprobe; /* window probes sent */ - u_long tcps_sndurg; /* packets sent with URG only */ - u_long tcps_sndwinup; /* window update-only packets sent */ - u_long tcps_sndctrl; /* control (SYN|FIN|RST) packets sent */ - - u_long tcps_rcvtotal; /* total packets received */ - u_long tcps_rcvpack; /* packets received in sequence */ - u_long tcps_rcvbyte; /* bytes received in sequence */ - u_long tcps_rcvbadsum; /* packets received with ccksum errs */ - u_long tcps_rcvbadoff; /* packets received with bad offset */ -/* u_long tcps_rcvshort; */ /* packets received too short */ - u_long tcps_rcvduppack; /* duplicate-only packets received */ - u_long tcps_rcvdupbyte; /* duplicate-only bytes received */ - u_long tcps_rcvpartduppack; /* packets with some duplicate data */ - u_long tcps_rcvpartdupbyte; /* dup. bytes in part-dup. packets */ - u_long tcps_rcvoopack; /* out-of-order packets received */ - u_long tcps_rcvoobyte; /* out-of-order bytes received */ - u_long tcps_rcvpackafterwin; /* packets with data after window */ - u_long tcps_rcvbyteafterwin; /* bytes rcvd after window */ - u_long tcps_rcvafterclose; /* packets rcvd after "close" */ - u_long tcps_rcvwinprobe; /* rcvd window probe packets */ - u_long tcps_rcvdupack; /* rcvd duplicate acks */ - u_long tcps_rcvacktoomuch; /* rcvd acks for unsent data */ - u_long tcps_rcvackpack; /* rcvd ack packets */ - u_long tcps_rcvackbyte; /* bytes acked by rcvd acks */ - u_long tcps_rcvwinupd; /* rcvd window update packets */ -/* u_long tcps_pawsdrop; */ /* segments dropped due to PAWS */ - u_long tcps_predack; /* times hdr predict ok for acks */ - u_long tcps_preddat; /* times hdr predict ok for data pkts */ - u_long tcps_socachemiss; /* tcp_last_so misses */ - u_long tcps_didnuttin; /* Times tcp_output didn't do anything XXX */ -}; - -extern struct tcpstat tcpstat; /* tcp statistics */ -extern u_int32_t tcp_now; /* for RFC 1323 timestamps */ - -#endif diff --git a/BasiliskII/src/slirp/tcpip.h b/BasiliskII/src/slirp/tcpip.h deleted file mode 100644 index dff5a3c9..00000000 --- a/BasiliskII/src/slirp/tcpip.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)tcpip.h 8.1 (Berkeley) 6/10/93 - * tcpip.h,v 1.3 1994/08/21 05:27:40 paul Exp - */ - -#ifndef _TCPIP_H_ -#define _TCPIP_H_ - -/* - * Tcp+ip header, after ip options removed. - */ -struct tcpiphdr { - struct ipovly ti_i; /* overlaid ip structure */ - struct tcphdr ti_t; /* tcp header */ -}; -#define ti_next ti_i.ih_next -#define ti_prev ti_i.ih_prev -#define ti_x1 ti_i.ih_x1 -#define ti_pr ti_i.ih_pr -#define ti_len ti_i.ih_len -#define ti_src ti_i.ih_src -#define ti_dst ti_i.ih_dst -#define ti_sport ti_t.th_sport -#define ti_dport ti_t.th_dport -#define ti_seq ti_t.th_seq -#define ti_ack ti_t.th_ack -#define ti_x2 ti_t.th_x2 -#define ti_off ti_t.th_off -#define ti_flags ti_t.th_flags -#define ti_win ti_t.th_win -#define ti_sum ti_t.th_sum -#define ti_urp ti_t.th_urp - -/* - * Just a clean way to get to the first byte - * of the packet - */ -struct tcpiphdr_2 { - struct tcpiphdr dummy; - char first_char; -}; - -#endif diff --git a/BasiliskII/src/slirp/tftp.c b/BasiliskII/src/slirp/tftp.c deleted file mode 100644 index e656c4f0..00000000 --- a/BasiliskII/src/slirp/tftp.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * tftp.c - a simple, read-only tftp server for qemu - * - * Copyright (c) 2004 Magnus Damm - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, 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: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * 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, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -struct tftp_session { - int in_use; - char filename[TFTP_FILENAME_MAX]; - - struct in_addr client_ip; - u_int16_t client_port; - - int timestamp; -}; - -struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; - -const char *tftp_prefix; - -static void tftp_session_update(struct tftp_session *spt) -{ - spt->timestamp = curtime; - spt->in_use = 1; -} - -static void tftp_session_terminate(struct tftp_session *spt) -{ - spt->in_use = 0; -} - -static int tftp_session_allocate(struct tftp_t *tp) -{ - struct tftp_session *spt; - int k; - - for (k = 0; k < TFTP_SESSIONS_MAX; k++) { - spt = &tftp_sessions[k]; - - if (!spt->in_use) - goto found; - - /* sessions time out after 5 inactive seconds */ - if ((int)(curtime - spt->timestamp) > 5000) - goto found; - } - - return -1; - - found: - memset(spt, 0, sizeof(*spt)); - memcpy(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip)); - spt->client_port = tp->udp.uh_sport; - - tftp_session_update(spt); - - return k; -} - -static int tftp_session_find(struct tftp_t *tp) -{ - struct tftp_session *spt; - int k; - - for (k = 0; k < TFTP_SESSIONS_MAX; k++) { - spt = &tftp_sessions[k]; - - if (spt->in_use) { - if (!memcmp(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip))) { - if (spt->client_port == tp->udp.uh_sport) { - return k; - } - } - } - } - - return -1; -} - -static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr, - u_int8_t *buf, int len) -{ - int fd; - int bytes_read = 0; - - fd = open(spt->filename, O_RDONLY | O_BINARY); - - if (fd < 0) { - return -1; - } - - if (len) { - lseek(fd, block_nr * 512, SEEK_SET); - - bytes_read = read(fd, buf, len); - } - - close(fd); - - return bytes_read; -} - -static int tftp_send_error(struct tftp_session *spt, - u_int16_t errorcode, const char *msg, - struct tftp_t *recv_tp) -{ - struct sockaddr_in saddr, daddr; - struct mbuf *m; - struct tftp_t *tp; - int nobytes; - - m = m_get(); - - if (!m) { - return -1; - } - - memset(m->m_data, 0, m->m_size); - - m->m_data += if_maxlinkhdr; - tp = (void *)m->m_data; - m->m_data += sizeof(struct udpiphdr); - - tp->tp_op = htons(TFTP_ERROR); - tp->x.tp_error.tp_error_code = htons(errorcode); - strncpy((char *)tp->x.tp_error.tp_msg, msg, sizeof(tp->x.tp_error.tp_msg)); - tp->x.tp_error.tp_msg[sizeof(tp->x.tp_error.tp_msg)-1] = 0; - - saddr.sin_addr = recv_tp->ip.ip_dst; - saddr.sin_port = recv_tp->udp.uh_dport; - - daddr.sin_addr = spt->client_ip; - daddr.sin_port = spt->client_port; - - nobytes = 2; - - m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) - - sizeof(struct ip) - sizeof(struct udphdr); - - udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); - - tftp_session_terminate(spt); - - return 0; -} - -static int tftp_send_data(struct tftp_session *spt, - u_int16_t block_nr, - struct tftp_t *recv_tp) -{ - struct sockaddr_in saddr, daddr; - struct mbuf *m; - struct tftp_t *tp; - int nobytes; - - if (block_nr < 1) { - return -1; - } - - m = m_get(); - - if (!m) { - return -1; - } - - memset(m->m_data, 0, m->m_size); - - m->m_data += if_maxlinkhdr; - tp = (void *)m->m_data; - m->m_data += sizeof(struct udpiphdr); - - tp->tp_op = htons(TFTP_DATA); - tp->x.tp_data.tp_block_nr = htons(block_nr); - - saddr.sin_addr = recv_tp->ip.ip_dst; - saddr.sin_port = recv_tp->udp.uh_dport; - - daddr.sin_addr = spt->client_ip; - daddr.sin_port = spt->client_port; - - nobytes = tftp_read_data(spt, block_nr - 1, tp->x.tp_data.tp_buf, 512); - - if (nobytes < 0) { - m_free(m); - - /* send "file not found" error back */ - - tftp_send_error(spt, 1, "File not found", tp); - - return -1; - } - - m->m_len = sizeof(struct tftp_t) - (512 - nobytes) - - sizeof(struct ip) - sizeof(struct udphdr); - - udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); - - if (nobytes == 512) { - tftp_session_update(spt); - } - else { - tftp_session_terminate(spt); - } - - return 0; -} - -static void tftp_handle_rrq(struct tftp_t *tp, int pktlen) -{ - struct tftp_session *spt; - int s, k, n; - u_int8_t *src, *dst; - - s = tftp_session_allocate(tp); - - if (s < 0) { - return; - } - - spt = &tftp_sessions[s]; - - src = tp->x.tp_buf; - dst = (u_int8_t *)spt->filename; - n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp); - - /* get name */ - - for (k = 0; k < n; k++) { - if (k < TFTP_FILENAME_MAX) { - dst[k] = src[k]; - } - else { - return; - } - - if (src[k] == '\0') { - break; - } - } - - if (k >= n) { - return; - } - - k++; - - /* check mode */ - if ((n - k) < 6) { - return; - } - - if (memcmp(&src[k], "octet\0", 6) != 0) { - tftp_send_error(spt, 4, "Unsupported transfer mode", tp); - return; - } - - /* do sanity checks on the filename */ - - if ((spt->filename[0] != '/') - || (spt->filename[strlen(spt->filename) - 1] == '/') - || strstr(spt->filename, "/../")) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } - - /* only allow exported prefixes */ - - if (!tftp_prefix - || (strncmp(spt->filename, tftp_prefix, strlen(tftp_prefix)) != 0)) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } - - /* check if the file exists */ - - if (tftp_read_data(spt, 0, (u_int8_t *)spt->filename, 0) < 0) { - tftp_send_error(spt, 1, "File not found", tp); - return; - } - - tftp_send_data(spt, 1, tp); -} - -static void tftp_handle_ack(struct tftp_t *tp, int pktlen) -{ - int s; - - s = tftp_session_find(tp); - - if (s < 0) { - return; - } - - if (tftp_send_data(&tftp_sessions[s], - ntohs(tp->x.tp_data.tp_block_nr) + 1, - tp) < 0) { - return; - } -} - -void tftp_input(struct mbuf *m) -{ - struct tftp_t *tp = (struct tftp_t *)m->m_data; - - switch(ntohs(tp->tp_op)) { - case TFTP_RRQ: - tftp_handle_rrq(tp, m->m_len); - break; - - case TFTP_ACK: - tftp_handle_ack(tp, m->m_len); - break; - } -} diff --git a/BasiliskII/src/slirp/tftp.h b/BasiliskII/src/slirp/tftp.h deleted file mode 100644 index b150a049..00000000 --- a/BasiliskII/src/slirp/tftp.h +++ /dev/null @@ -1,40 +0,0 @@ -/* tftp defines */ - -#define TFTP_SESSIONS_MAX 3 - -#define TFTP_SERVER 69 - -#define TFTP_RRQ 1 -#define TFTP_WRQ 2 -#define TFTP_DATA 3 -#define TFTP_ACK 4 -#define TFTP_ERROR 5 - -#define TFTP_FILENAME_MAX 512 - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct tftp_t { - struct ip ip; - struct udphdr udp; - u_int16_t tp_op; - union { - struct { - u_int16_t tp_block_nr; - u_int8_t tp_buf[512]; - } tp_data; - struct { - u_int16_t tp_error_code; - u_int8_t tp_msg[512]; - } tp_error; - u_int8_t tp_buf[512 + 2]; - } x; -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) -#endif - -void tftp_input(struct mbuf *m); diff --git a/BasiliskII/src/slirp/udp.c b/BasiliskII/src/slirp/udp.c deleted file mode 100644 index deedb1e7..00000000 --- a/BasiliskII/src/slirp/udp.c +++ /dev/null @@ -1,672 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)udp_usrreq.c 8.4 (Berkeley) 1/21/94 - * udp_usrreq.c,v 1.4 1994/10/02 17:48:45 phk Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include -#include -#include "ip_icmp.h" - -struct udpstat udpstat; - -struct socket udb; - -/* - * UDP protocol implementation. - * Per RFC 768, August, 1980. - */ -#ifndef COMPAT_42 -int udpcksum = 1; -#else -int udpcksum = 0; /* XXX */ -#endif - -struct socket *udp_last_so = &udb; - -void -udp_init() -{ - udb.so_next = udb.so_prev = &udb; -} -/* m->m_data points at ip packet header - * m->m_len length ip packet - * ip->ip_len length data (IPDU) - */ -void -udp_input(m, iphlen) - register struct mbuf *m; - int iphlen; -{ - register struct ip *ip; - register struct udphdr *uh; -/* struct mbuf *opts = 0;*/ - int len; - struct ip save_ip; - struct socket *so; - - DEBUG_CALL("udp_input"); - DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("iphlen = %d", iphlen); - - udpstat.udps_ipackets++; - - /* - * Strip IP options, if any; should skip this, - * make available to user, and use on returned packets, - * but we don't yet have a way to check the checksum - * with options still present. - */ - if(iphlen > sizeof(struct ip)) { - ip_stripoptions(m, (struct mbuf *)0); - iphlen = sizeof(struct ip); - } - - /* - * Get IP and UDP header together in first mbuf. - */ - ip = mtod(m, struct ip *); - uh = (struct udphdr *)((caddr_t)ip + iphlen); - - /* - * Make mbuf data length reflect UDP length. - * If not enough data to reflect UDP length, drop. - */ - len = ntohs((u_int16_t)uh->uh_ulen); - - if (ip->ip_len != len) { - if (len > ip->ip_len) { - udpstat.udps_badlen++; - goto bad; - } - m_adj(m, len - ip->ip_len); - ip->ip_len = len; - } - - /* - * Save a copy of the IP header in case we want restore it - * for sending an ICMP error message in response. - */ - save_ip = *ip; - save_ip.ip_len+= iphlen; /* tcp_input subtracts this */ - - /* - * Checksum extended UDP header and data. - */ - if (udpcksum && uh->uh_sum) { - ((struct ipovly *)ip)->ih_next = 0; - ((struct ipovly *)ip)->ih_prev = 0; - ((struct ipovly *)ip)->ih_x1 = 0; - ((struct ipovly *)ip)->ih_len = uh->uh_ulen; - /* keep uh_sum for ICMP reply - * uh->uh_sum = cksum(m, len + sizeof (struct ip)); - * if (uh->uh_sum) { - */ - if(cksum(m, len + sizeof(struct ip))) { - udpstat.udps_badsum++; - goto bad; - } - } - - /* - * handle DHCP/BOOTP - */ - if (ntohs(uh->uh_dport) == BOOTP_SERVER) { - bootp_input(m); - goto bad; - } - - /* - * handle TFTP - */ - if (ntohs(uh->uh_dport) == TFTP_SERVER) { - tftp_input(m); - goto bad; - } - - /* - * Locate pcb for datagram. - */ - so = udp_last_so; - if (so->so_lport != uh->uh_sport || - so->so_laddr.s_addr != ip->ip_src.s_addr) { - struct socket *tmp; - - for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) { - if (tmp->so_lport == uh->uh_sport && - tmp->so_laddr.s_addr == ip->ip_src.s_addr) { - tmp->so_faddr.s_addr = ip->ip_dst.s_addr; - tmp->so_fport = uh->uh_dport; - so = tmp; - break; - } - } - if (tmp == &udb) { - so = NULL; - } else { - udpstat.udpps_pcbcachemiss++; - udp_last_so = so; - } - } - - if (so == NULL) { - /* - * If there's no socket for this packet, - * create one - */ - if ((so = socreate()) == NULL) goto bad; - if(udp_attach(so) == -1) { - DEBUG_MISC((dfd," udp_attach errno = %d-%s\n", - errno,strerror(errno))); - sofree(so); - goto bad; - } - - /* - * Setup fields - */ - /* udp_last_so = so; */ - so->so_laddr = ip->ip_src; - so->so_lport = uh->uh_sport; - - if ((so->so_iptos = udp_tos(so)) == 0) - so->so_iptos = ip->ip_tos; - - /* - * XXXXX Here, check if it's in udpexec_list, - * and if it is, do the fork_exec() etc. - */ - } - - so->so_faddr = ip->ip_dst; /* XXX */ - so->so_fport = uh->uh_dport; /* XXX */ - - iphlen += sizeof(struct udphdr); - m->m_len -= iphlen; - m->m_data += iphlen; - - /* - * Now we sendto() the packet. - */ - if (so->so_emu) - udp_emu(so, m); - - if(sosendto(so,m) == -1) { - m->m_len += iphlen; - m->m_data -= iphlen; - *ip=save_ip; - DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno))); - icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); - } - - m_free(so->so_m); /* used for ICMP if error on sorecvfrom */ - - /* restore the orig mbuf packet */ - m->m_len += iphlen; - m->m_data -= iphlen; - *ip=save_ip; - so->so_m=m; /* ICMP backup */ - - return; -bad: - m_freem(m); - /* if (opts) m_freem(opts); */ - return; -} - -int udp_output2(struct socket *so, struct mbuf *m, - struct sockaddr_in *saddr, struct sockaddr_in *daddr, - int iptos) -{ - register struct udpiphdr *ui; - int error = 0; - - DEBUG_CALL("udp_output"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("saddr = %lx", (long)saddr->sin_addr.s_addr); - DEBUG_ARG("daddr = %lx", (long)daddr->sin_addr.s_addr); - - /* - * Adjust for header - */ - m->m_data -= sizeof(struct udpiphdr); - m->m_len += sizeof(struct udpiphdr); - - /* - * Fill in mbuf with extended UDP header - * and addresses and length put into network format. - */ - ui = mtod(m, struct udpiphdr *); - ui->ui_next = ui->ui_prev = 0; - ui->ui_x1 = 0; - ui->ui_pr = IPPROTO_UDP; - ui->ui_len = htons((u_short) (m->m_len - sizeof(struct ip))); /* + sizeof (struct udphdr)); */ - /* XXXXX Check for from-one-location sockets, or from-any-location sockets */ - ui->ui_src = saddr->sin_addr; - ui->ui_dst = daddr->sin_addr; - ui->ui_sport = saddr->sin_port; - ui->ui_dport = daddr->sin_port; - ui->ui_ulen = ui->ui_len; - - /* - * Stuff checksum and output datagram. - */ - ui->ui_sum = 0; - if (udpcksum) { - if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0) - ui->ui_sum = 0xffff; - } - ((struct ip *)ui)->ip_len = (u_int16_t) m->m_len; - - ((struct ip *)ui)->ip_ttl = ip_defttl; - ((struct ip *)ui)->ip_tos = iptos; - - udpstat.udps_opackets++; - - error = ip_output(so, m); - - return (error); -} - -int udp_output(struct socket *so, struct mbuf *m, - struct sockaddr_in *addr) - -{ - struct sockaddr_in saddr, daddr; - - saddr = *addr; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { - saddr.sin_addr.s_addr = so->so_faddr.s_addr; - if ((so->so_faddr.s_addr & htonl(0x000000ff)) == htonl(0xff)) - saddr.sin_addr.s_addr = alias_addr.s_addr; - } - daddr.sin_addr = so->so_laddr; - daddr.sin_port = so->so_lport; - - return udp_output2(so, m, &saddr, &daddr, so->so_iptos); -} - -int -udp_attach(so) - struct socket *so; -{ - struct sockaddr_in addr; - - if((so->s = socket(AF_INET,SOCK_DGRAM,0)) != -1) { - /* - * Here, we bind() the socket. Although not really needed - * (sendto() on an unbound socket will bind it), it's done - * here so that emulation of ytalk etc. don't have to do it - */ - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = 0; - addr.sin_addr.s_addr = INADDR_ANY; - if(bind(so->s, (struct sockaddr *)&addr, sizeof(addr))<0) { - int error = WSAGetLastError(); - closesocket(so->s); - so->s=-1; - WSASetLastError(error); - } else { - /* success, insert in queue */ - so->so_expire = curtime + SO_EXPIRE; - insque(so,&udb); - } - } - return(so->s); -} - -void -udp_detach(so) - struct socket *so; -{ - closesocket(so->s); - /* if (so->so_m) m_free(so->so_m); done by sofree */ - - sofree(so); -} - -struct tos_t udptos[] = { - {0, 53, IPTOS_LOWDELAY, 0}, /* DNS */ - {517, 517, IPTOS_LOWDELAY, EMU_TALK}, /* talk */ - {518, 518, IPTOS_LOWDELAY, EMU_NTALK}, /* ntalk */ - {0, 7648, IPTOS_LOWDELAY, EMU_CUSEEME}, /* Cu-Seeme */ - {0, 0, 0, 0} -}; - -u_int8_t -udp_tos(so) - struct socket *so; -{ - int i = 0; - - while(udptos[i].tos) { - if ((udptos[i].fport && ntohs(so->so_fport) == udptos[i].fport) || - (udptos[i].lport && ntohs(so->so_lport) == udptos[i].lport)) { - so->so_emu = udptos[i].emu; - return udptos[i].tos; - } - i++; - } - - return 0; -} - -#ifdef EMULATE_TALK -#include "talkd.h" -#endif - -/* - * Here, talk/ytalk/ntalk requests must be emulated - */ -void -udp_emu(so, m) - struct socket *so; - struct mbuf *m; -{ - struct sockaddr_in addr; - socklen_t addrlen = sizeof(addr); -#ifdef EMULATE_TALK - CTL_MSG_OLD *omsg; - CTL_MSG *nmsg; - char buff[sizeof(CTL_MSG)]; - u_char type; - -struct talk_request { - struct talk_request *next; - struct socket *udp_so; - struct socket *tcp_so; -} *req; - - static struct talk_request *req_tbl = 0; - -#endif - -struct cu_header { - uint16_t d_family; // destination family - uint16_t d_port; // destination port - uint32_t d_addr; // destination address - uint16_t s_family; // source family - uint16_t s_port; // source port - uint32_t so_addr; // source address - uint32_t seqn; // sequence number - uint16_t message; // message - uint16_t data_type; // data type - uint16_t pkt_len; // packet length -} *cu_head; - - switch(so->so_emu) { - -#ifdef EMULATE_TALK - case EMU_TALK: - case EMU_NTALK: - /* - * Talk emulation. We always change the ctl_addr to get - * some answers from the daemon. When an ANNOUNCE comes, - * we send LEAVE_INVITE to the local daemons. Also when a - * DELETE comes, we send copies to the local daemons. - */ - if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) - return; - -#define IS_OLD (so->so_emu == EMU_TALK) - -#define COPY_MSG(dest, src) { dest->type = src->type; \ - dest->id_num = src->id_num; \ - dest->pid = src->pid; \ - dest->addr = src->addr; \ - dest->ctl_addr = src->ctl_addr; \ - memcpy(&dest->l_name, &src->l_name, NAME_SIZE_OLD); \ - memcpy(&dest->r_name, &src->r_name, NAME_SIZE_OLD); \ - memcpy(&dest->r_tty, &src->r_tty, TTY_SIZE); } - -#define OTOSIN(ptr, field) ((struct sockaddr_in *)&ptr->field) -/* old_sockaddr to sockaddr_in */ - - - if (IS_OLD) { /* old talk */ - omsg = mtod(m, CTL_MSG_OLD*); - nmsg = (CTL_MSG *) buff; - type = omsg->type; - OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port; - OTOSIN(omsg, ctl_addr)->sin_addr = our_addr; - strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD); - } else { /* new talk */ - omsg = (CTL_MSG_OLD *) buff; - nmsg = mtod(m, CTL_MSG *); - type = nmsg->type; - OTOSIN(nmsg, ctl_addr)->sin_port = addr.sin_port; - OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr; - strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD); - } - - if (type == LOOK_UP) - return; /* for LOOK_UP this is enough */ - - if (IS_OLD) { /* make a copy of the message */ - COPY_MSG(nmsg, omsg); - nmsg->vers = 1; - nmsg->answer = 0; - } else - COPY_MSG(omsg, nmsg); - - /* - * If if is an ANNOUNCE message, we go through the - * request table to see if a tcp port has already - * been redirected for this socket. If not, we solisten() - * a new socket and add this entry to the table. - * The port number of the tcp socket and our IP - * are put to the addr field of the message structures. - * Then a LEAVE_INVITE is sent to both local daemon - * ports, 517 and 518. This is why we have two copies - * of the message, one in old talk and one in new talk - * format. - */ - - if (type == ANNOUNCE) { - int s; - u_short temp_port; - - for(req = req_tbl; req; req = req->next) - if (so == req->udp_so) - break; /* found it */ - - if (!req) { /* no entry for so, create new */ - req = (struct talk_request *) - malloc(sizeof(struct talk_request)); - req->udp_so = so; - req->tcp_so = solisten(0, - OTOSIN(omsg, addr)->sin_addr.s_addr, - OTOSIN(omsg, addr)->sin_port, - SS_FACCEPTONCE); - req->next = req_tbl; - req_tbl = req; - } - - /* replace port number in addr field */ - addrlen = sizeof(addr); - getsockname(req->tcp_so->s, - (struct sockaddr *) &addr, - &addrlen); - OTOSIN(omsg, addr)->sin_port = addr.sin_port; - OTOSIN(omsg, addr)->sin_addr = our_addr; - OTOSIN(nmsg, addr)->sin_port = addr.sin_port; - OTOSIN(nmsg, addr)->sin_addr = our_addr; - - /* send LEAVE_INVITEs */ - temp_port = OTOSIN(omsg, ctl_addr)->sin_port; - OTOSIN(omsg, ctl_addr)->sin_port = 0; - OTOSIN(nmsg, ctl_addr)->sin_port = 0; - omsg->type = nmsg->type = LEAVE_INVITE; - - s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); - addr.sin_addr = our_addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(517); - sendto(s, (char *)omsg, sizeof(*omsg), 0, - (struct sockaddr *)&addr, sizeof(addr)); - addr.sin_port = htons(518); - sendto(s, (char *)nmsg, sizeof(*nmsg), 0, - (struct sockaddr *) &addr, sizeof(addr)); - closesocket(s) ; - - omsg->type = nmsg->type = ANNOUNCE; - OTOSIN(omsg, ctl_addr)->sin_port = temp_port; - OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; - } - - /* - * If it is a DELETE message, we send a copy to the - * local daemons. Then we delete the entry corresponding - * to our socket from the request table. - */ - - if (type == DELETE) { - struct talk_request *temp_req, *req_next; - int s; - u_short temp_port; - - temp_port = OTOSIN(omsg, ctl_addr)->sin_port; - OTOSIN(omsg, ctl_addr)->sin_port = 0; - OTOSIN(nmsg, ctl_addr)->sin_port = 0; - - s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); - addr.sin_addr = our_addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(517); - sendto(s, (char *)omsg, sizeof(*omsg), 0, - (struct sockaddr *)&addr, sizeof(addr)); - addr.sin_port = htons(518); - sendto(s, (char *)nmsg, sizeof(*nmsg), 0, - (struct sockaddr *)&addr, sizeof(addr)); - closesocket(s); - - OTOSIN(omsg, ctl_addr)->sin_port = temp_port; - OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; - - /* delete table entry */ - if (so == req_tbl->udp_so) { - temp_req = req_tbl; - req_tbl = req_tbl->next; - free(temp_req); - } else { - temp_req = req_tbl; - for(req = req_tbl->next; req; req = req_next) { - req_next = req->next; - if (so == req->udp_so) { - temp_req->next = req_next; - free(req); - break; - } else { - temp_req = req; - } - } - } - } - - return; -#endif - - case EMU_CUSEEME: - - /* - * Cu-SeeMe emulation. - * Hopefully the packet is more that 16 bytes long. We don't - * do any other tests, just replace the address and port - * fields. - */ - if (m->m_len >= sizeof (*cu_head)) { - if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) - return; - cu_head = mtod(m, struct cu_header *); - cu_head->s_port = addr.sin_port; - cu_head->so_addr = our_addr.s_addr; - } - - return; - } -} - -struct socket * -udp_listen(port, laddr, lport, flags) - u_int port; - u_int32_t laddr; - u_int lport; - int flags; -{ - struct sockaddr_in addr; - struct socket *so; - socklen_t addrlen = sizeof(struct sockaddr_in); - int opt = 1; - - if ((so = socreate()) == NULL) { - free(so); - return NULL; - } - so->s = socket(AF_INET,SOCK_DGRAM,0); - so->so_expire = curtime + SO_EXPIRE; - insque(so,&udb); - - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = port; - - if (bind(so->s,(struct sockaddr *)&addr, addrlen) < 0) { - udp_detach(so); - return NULL; - } - setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); -/* setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); */ - - getsockname(so->s,(struct sockaddr *)&addr,&addrlen); - so->so_fport = addr.sin_port; - if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) - so->so_faddr = alias_addr; - else - so->so_faddr = addr.sin_addr; - - so->so_lport = lport; - so->so_laddr.s_addr = laddr; - if (flags != SS_FACCEPTONCE) - so->so_expire = 0; - - so->so_state = SS_ISFCONNECTED; - - return so; -} diff --git a/BasiliskII/src/slirp/udp.h b/BasiliskII/src/slirp/udp.h deleted file mode 100644 index 7d844efe..00000000 --- a/BasiliskII/src/slirp/udp.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - * SUCH DAMAGE. - * - * @(#)udp.h 8.1 (Berkeley) 6/10/93 - * udp.h,v 1.3 1994/08/21 05:27:41 paul Exp - */ - -#ifndef _UDP_H_ -#define _UDP_H_ - -#define UDP_TTL 0x60 -#define UDP_UDPDATALEN 16192 - -extern struct socket *udp_last_so; - -/* - * Udp protocol header. - * Per RFC 768, September, 1981. - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct udphdr { - u_int16_t uh_sport; /* source port */ - u_int16_t uh_dport; /* destination port */ - int16_t uh_ulen; /* udp length */ - u_int16_t uh_sum; /* udp checksum */ -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) -#endif - -/* - * UDP kernel structures and variables. - */ -struct udpiphdr { - struct ipovly ui_i; /* overlaid ip structure */ - struct udphdr ui_u; /* udp header */ -}; -#define ui_next ui_i.ih_next -#define ui_prev ui_i.ih_prev -#define ui_x1 ui_i.ih_x1 -#define ui_pr ui_i.ih_pr -#define ui_len ui_i.ih_len -#define ui_src ui_i.ih_src -#define ui_dst ui_i.ih_dst -#define ui_sport ui_u.uh_sport -#define ui_dport ui_u.uh_dport -#define ui_ulen ui_u.uh_ulen -#define ui_sum ui_u.uh_sum - -struct udpstat { - /* input statistics: */ - u_long udps_ipackets; /* total input packets */ - u_long udps_hdrops; /* packet shorter than header */ - u_long udps_badsum; /* checksum error */ - u_long udps_badlen; /* data length larger than packet */ - u_long udps_noport; /* no socket on port */ - u_long udps_noportbcast; /* of above, arrived as broadcast */ - u_long udps_fullsock; /* not delivered, input socket full */ - u_long udpps_pcbcachemiss; /* input packets missing pcb cache */ - /* output statistics: */ - u_long udps_opackets; /* total output packets */ -}; - -/* - * Names for UDP sysctl objects - */ -#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ -#define UDPCTL_MAXID 2 - -extern struct udpstat udpstat; -extern struct socket udb; -struct mbuf; - -void udp_init(void); -void udp_input(register struct mbuf *, int); -int udp_output(struct socket *, struct mbuf *, struct sockaddr_in *); -int udp_attach(struct socket *); -void udp_detach(struct socket *); -u_int8_t udp_tos(struct socket *); -void udp_emu(struct socket *, struct mbuf *); -struct socket * udp_listen(u_int, u_int32_t, u_int, int); -int udp_output2(struct socket *so, struct mbuf *m, - struct sockaddr_in *saddr, struct sockaddr_in *daddr, - int iptos); -#endif diff --git a/BasiliskII/src/sony.cpp b/BasiliskII/src/sony.cpp index 804239b7..a8d8220d 100644 --- a/BasiliskII/src/sony.cpp +++ b/BasiliskII/src/sony.cpp @@ -50,11 +50,7 @@ using std::vector; // Check for inserted disks by polling? -#ifdef AMIGA -#define DISK_INSERT_CHECK 1 -#else #define DISK_INSERT_CHECK 0 -#endif // Floppy disk icon diff --git a/BasiliskII/src/uae_cpu/basilisk_glue.cpp b/BasiliskII/src/uae_cpu/basilisk_glue.cpp index b29c7702..8dd7d173 100644 --- a/BasiliskII/src/uae_cpu/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu/basilisk_glue.cpp @@ -30,7 +30,6 @@ #include "memory.h" #include "readcpu.h" #include "newcpu.h" -#include "compiler/compemu.h" // RAM and ROM pointers @@ -41,21 +40,15 @@ uint32 ROMBaseMac; // ROM base (Mac address space) uint8 *ROMBaseHost; // ROM base (host address space) uint32 ROMSize; // Size of ROM -#if !REAL_ADDRESSING // Mac frame buffer uint8 *MacFrameBaseHost; // Frame buffer base (host address space) uint32 MacFrameSize; // Size of frame buffer int MacFrameLayout; // Frame buffer layout -#endif #if DIRECT_ADDRESSING uintptr MEMBaseDiff; // Global offset between a Mac address and its Host equivalent #endif -#if USE_JIT -bool UseJIT = false; -#endif - // From newcpu.cpp extern bool quit_program; @@ -66,42 +59,15 @@ extern bool quit_program; bool Init680x0(void) { -#if REAL_ADDRESSING - // Mac address space = host address space - RAMBaseMac = (uintptr)RAMBaseHost; - ROMBaseMac = (uintptr)ROMBaseHost; -#elif DIRECT_ADDRESSING +#if DIRECT_ADDRESSING // Mac address space = host address space minus constant offset (MEMBaseDiff) // NOTE: MEMBaseDiff is set up in main_unix.cpp/main() RAMBaseMac = 0; ROMBaseMac = Host2MacAddr(ROMBaseHost); -#else - // Initialize UAE memory banks - RAMBaseMac = 0; - switch (ROMVersion) { - case ROM_VERSION_64K: - case ROM_VERSION_PLUS: - case ROM_VERSION_CLASSIC: - ROMBaseMac = 0x00400000; - break; - case ROM_VERSION_II: - ROMBaseMac = 0x00a00000; - break; - case ROM_VERSION_32: - ROMBaseMac = 0x40800000; - break; - default: - return false; - } - memory_init(); #endif init_m68k(); -#if USE_JIT - UseJIT = compiler_use_jit(); - if (UseJIT) - compiler_init(); -#endif + return true; } @@ -112,10 +78,7 @@ bool Init680x0(void) void Exit680x0(void) { -#if USE_JIT - if (UseJIT) - compiler_exit(); -#endif + exit_m68k(); } @@ -126,9 +89,7 @@ void Exit680x0(void) void InitFrameBufferMapping(void) { -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING - memory_init(); -#endif + } /* @@ -138,11 +99,7 @@ void InitFrameBufferMapping(void) void Start680x0(void) { m68k_reset(); -#if USE_JIT - if (UseJIT) - m68k_compile_execute(); - else -#endif + m68k_execute(); } diff --git a/BasiliskII/src/uae_cpu/build68k.c b/BasiliskII/src/uae_cpu/build68k.c index 8ec3ab55..af5cac92 100644 --- a/BasiliskII/src/uae_cpu/build68k.c +++ b/BasiliskII/src/uae_cpu/build68k.c @@ -72,15 +72,7 @@ int main(int argc, char **argv) printf ("#include \"sysdeps.h\"\n"); printf ("#include \"readcpu.h\"\n"); printf ("struct instr_def defs68k[] = {\n"); -#ifdef WIN32 - tablef = fopen(argc > 1 ? argv[1] : "table68k","r"); - if (tablef == NULL) { - fprintf(stderr, "table68k not found\n"); - exit(1); - } -#else tablef = stdin; -#endif getnextch(); while (nextch != EOF) { int cpulevel, plevel, sduse; diff --git a/BasiliskII/src/uae_cpu/compiler/codegen_x86.cpp b/BasiliskII/src/uae_cpu/compiler/codegen_x86.cpp deleted file mode 100644 index f03c4f3c..00000000 --- a/BasiliskII/src/uae_cpu/compiler/codegen_x86.cpp +++ /dev/null @@ -1,4758 +0,0 @@ -/* - * compiler/codegen_x86.cpp - IA-32 code generator - * - * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer - * - * Adaptation for Basilisk II and improvements, copyright 2000-2005 - * Gwenole Beauchesne - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * Portions related to CPU detection come from linux/arch/i386/kernel/setup.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* This should eventually end up in machdep/, but for now, x86 is the - only target, and it's easier this way... */ - -#include "flags_x86.h" - -/************************************************************************* - * Some basic information about the the target CPU * - *************************************************************************/ - -#define EAX_INDEX 0 -#define ECX_INDEX 1 -#define EDX_INDEX 2 -#define EBX_INDEX 3 -#define ESP_INDEX 4 -#define EBP_INDEX 5 -#define ESI_INDEX 6 -#define EDI_INDEX 7 -#if defined(__x86_64__) -#define R8_INDEX 8 -#define R9_INDEX 9 -#define R10_INDEX 10 -#define R11_INDEX 11 -#define R12_INDEX 12 -#define R13_INDEX 13 -#define R14_INDEX 14 -#define R15_INDEX 15 -#endif -/* XXX this has to match X86_Reg8H_Base + 4 */ -#define AH_INDEX (0x10+4+EAX_INDEX) -#define CH_INDEX (0x10+4+ECX_INDEX) -#define DH_INDEX (0x10+4+EDX_INDEX) -#define BH_INDEX (0x10+4+EBX_INDEX) - -/* The register in which subroutines return an integer return value */ -#define REG_RESULT EAX_INDEX - -/* The registers subroutines take their first and second argument in */ -#if defined( _MSC_VER ) && !USE_NORMAL_CALLING_CONVENTION -/* Handle the _fastcall parameters of ECX and EDX */ -#define REG_PAR1 ECX_INDEX -#define REG_PAR2 EDX_INDEX -#elif defined(__x86_64__) -#define REG_PAR1 EDI_INDEX -#define REG_PAR2 ESI_INDEX -#else -#define REG_PAR1 EAX_INDEX -#define REG_PAR2 EDX_INDEX -#endif - -#define REG_PC_PRE EAX_INDEX /* The register we use for preloading regs.pc_p */ -#if defined( _MSC_VER ) && !USE_NORMAL_CALLING_CONVENTION -#define REG_PC_TMP EAX_INDEX -#else -#define REG_PC_TMP ECX_INDEX /* Another register that is not the above */ -#endif - -#define SHIFTCOUNT_NREG ECX_INDEX /* Register that can be used for shiftcount. - -1 if any reg will do */ -#define MUL_NREG1 EAX_INDEX /* %eax will hold the low 32 bits after a 32x32 mul */ -#define MUL_NREG2 EDX_INDEX /* %edx will hold the high 32 bits */ - -#define STACK_ALIGN 16 -#define STACK_OFFSET sizeof(void *) - -uae_s8 always_used[]={4,-1}; -#if defined(__x86_64__) -uae_s8 can_byte[]={0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,-1}; -uae_s8 can_word[]={0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,-1}; -#else -uae_s8 can_byte[]={0,1,2,3,-1}; -uae_s8 can_word[]={0,1,2,3,5,6,7,-1}; -#endif - -#if USE_OPTIMIZED_CALLS -/* Make sure interpretive core does not use cpuopti */ -uae_u8 call_saved[]={0,0,0,1,1,1,1,1}; -#error FIXME: code not ready -#else -/* cpuopti mutate instruction handlers to assume registers are saved - by the caller */ -uae_u8 call_saved[]={0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}; -#endif - -/* This *should* be the same as call_saved. But: - - We might not really know which registers are saved, and which aren't, - so we need to preserve some, but don't want to rely on everyone else - also saving those registers - - Special registers (such like the stack pointer) should not be "preserved" - by pushing, even though they are "saved" across function calls -*/ -#if defined(__x86_64__) -/* callee-saved registers as defined by Linux AMD64 ABI: rbx, rbp, rsp, r12 - r15 */ -/* preserve r11 because it's generally used to hold pointers to functions */ -static const uae_u8 need_to_preserve[]={0,0,0,1,0,1,0,0,0,0,0,1,1,1,1,1}; -#else -/* callee-saved registers as defined by System V IA-32 ABI: edi, esi, ebx, ebp */ -static const uae_u8 need_to_preserve[]={0,0,0,1,0,1,1,1}; -#endif - -/* Whether classes of instructions do or don't clobber the native flags */ -#define CLOBBER_MOV -#define CLOBBER_LEA -#define CLOBBER_CMOV -#define CLOBBER_POP -#define CLOBBER_PUSH -#define CLOBBER_SUB clobber_flags() -#define CLOBBER_SBB clobber_flags() -#define CLOBBER_CMP clobber_flags() -#define CLOBBER_ADD clobber_flags() -#define CLOBBER_ADC clobber_flags() -#define CLOBBER_AND clobber_flags() -#define CLOBBER_OR clobber_flags() -#define CLOBBER_XOR clobber_flags() - -#define CLOBBER_ROL clobber_flags() -#define CLOBBER_ROR clobber_flags() -#define CLOBBER_SHLL clobber_flags() -#define CLOBBER_SHRL clobber_flags() -#define CLOBBER_SHRA clobber_flags() -#define CLOBBER_TEST clobber_flags() -#define CLOBBER_CL16 -#define CLOBBER_CL8 -#define CLOBBER_SE32 -#define CLOBBER_SE16 -#define CLOBBER_SE8 -#define CLOBBER_ZE32 -#define CLOBBER_ZE16 -#define CLOBBER_ZE8 -#define CLOBBER_SW16 clobber_flags() -#define CLOBBER_SW32 -#define CLOBBER_SETCC -#define CLOBBER_MUL clobber_flags() -#define CLOBBER_BT clobber_flags() -#define CLOBBER_BSF clobber_flags() - -/* The older code generator is now deprecated. */ -#define USE_NEW_RTASM 1 - -#if USE_NEW_RTASM - -#if defined(__x86_64__) -#define X86_TARGET_64BIT 1 -/* The address override prefix causes a 5 cycles penalty on Intel Core - processors. Another solution would be to decompose the load in an LEA, - MOV (to zero-extend), MOV (from memory): is it better? */ -#define ADDR32 x86_emit_byte(0x67), -#else -#define ADDR32 /**/ -#endif -#define X86_FLAT_REGISTERS 0 -#define X86_OPTIMIZE_ALU 1 -#define X86_OPTIMIZE_ROTSHI 1 -#include "codegen_x86.h" - -#define x86_emit_byte(B) emit_byte(B) -#define x86_emit_word(W) emit_word(W) -#define x86_emit_long(L) emit_long(L) -#define x86_emit_quad(Q) emit_quad(Q) -#define x86_get_target() get_target() -#define x86_emit_failure(MSG) jit_fail(MSG, __FILE__, __LINE__, __FUNCTION__) - -static void jit_fail(const char *msg, const char *file, int line, const char *function) -{ - fprintf(stderr, "JIT failure in function %s from file %s at line %d: %s\n", - function, file, line, msg); - abort(); -} - -LOWFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r)) -{ -#if defined(__x86_64__) - PUSHQr(r); -#else - PUSHLr(r); -#endif -} -LENDFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r)) - -LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r)) -{ -#if defined(__x86_64__) - POPQr(r); -#else - POPLr(r); -#endif -} -LENDFUNC(NONE,READ,1,raw_pop_l_r,(R4 r)) - -LOWFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d)) -{ -#if defined(__x86_64__) - POPQm(d, X86_NOREG, X86_NOREG, 1); -#else - POPLm(d, X86_NOREG, X86_NOREG, 1); -#endif -} -LENDFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d)) - -LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i)) -{ - BTLir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b)) -{ - BTLrr(b, r); -} -LENDFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b)) - -LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i)) -{ - BTCLir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b)) -{ - BTCLrr(b, r); -} -LENDFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b)) - -LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i)) -{ - BTRLir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b)) -{ - BTRLrr(b, r); -} -LENDFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b)) - -LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i)) -{ - BTSLir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b)) -{ - BTSLrr(b, r); -} -LENDFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b)) - -LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i)) -{ - SUBWir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i)) - -LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s)) -{ - MOVLmr(s, X86_NOREG, X86_NOREG, 1, d); -} -LENDFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s)) -{ - MOVLim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s)) -{ - MOVWim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s)) -{ - MOVBim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i)) -{ - ROLBim(i, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i)) -{ - ROLBir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i)) -{ - ROLWir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i)) -{ - ROLLir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r)) -{ - ROLLrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r)) -{ - ROLWrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r)) -{ - ROLBrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r)) -{ - SHLLrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r)) -{ - SHLWrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r)) -{ - SHLBrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i)) -{ - RORBir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i)) -{ - RORWir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s)) -{ - ORLmr(s, X86_NOREG, X86_NOREG, 1, d); -} -LENDFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s)) - -LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i)) -{ - RORLir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r)) -{ - RORLrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r)) -{ - RORWrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r)) -{ - RORBrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r)) -{ - SHRLrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r)) -{ - SHRWrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r)) -{ - SHRBrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r)) -{ - SARLrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r)) -{ - SARWrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r)) -{ - SARBrr(r, d); -} -LENDFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i)) -{ - SHLLir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i)) -{ - SHLWir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i)) -{ - SHLBir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i)) -{ - SHRLir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i)) -{ - SHRWir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i)) -{ - SHRBir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i)) -{ - SARLir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i)) -{ - SARWir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i)) -{ - SARBir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah)) -{ - SAHF(); -} -LENDFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah)) - -LOWFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax)) -{ - CPUID(); -} -LENDFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax)) - -LOWFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah)) -{ - LAHF(); -} -LENDFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah)) - -LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc)) -{ - SETCCir(cc, d); -} -LENDFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc)) - -LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc)) -{ - SETCCim(cc, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc)) - -LOWFUNC(READ,NONE,3,raw_cmov_b_rr,(RW1 d, R1 s, IMM cc)) -{ - /* replacement using branch and mov */ - int8 *target_p = (int8 *)x86_get_target() + 1; - JCCSii(cc^1, 0); - MOVBrr(s, d); - *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1); -} -LENDFUNC(READ,NONE,3,raw_cmov_b_rr,(RW1 d, R1 s, IMM cc)) - -LOWFUNC(READ,NONE,3,raw_cmov_w_rr,(RW2 d, R2 s, IMM cc)) -{ - if (have_cmov) - CMOVWrr(cc, s, d); - else { /* replacement using branch and mov */ - int8 *target_p = (int8 *)x86_get_target() + 1; - JCCSii(cc^1, 0); - MOVWrr(s, d); - *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1); - } -} -LENDFUNC(READ,NONE,3,raw_cmov_w_rr,(RW2 d, R2 s, IMM cc)) - -LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc)) -{ - if (have_cmov) - CMOVLrr(cc, s, d); - else { /* replacement using branch and mov */ - int8 *target_p = (int8 *)x86_get_target() + 1; - JCCSii(cc^1, 0); - MOVLrr(s, d); - *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1); - } -} -LENDFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc)) - -LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s)) -{ - BSFLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s)) - -LOWFUNC(NONE,NONE,2,raw_sign_extend_32_rr,(W4 d, R4 s)) -{ - MOVSLQrr(s, d); -} -LENDFUNC(NONE,NONE,2,raw_sign_extend_32_rr,(W4 d, R4 s)) - -LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s)) -{ - MOVSWLrr(s, d); -} -LENDFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s)) - -LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s)) -{ - MOVSBLrr(s, d); -} -LENDFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s)) - -LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s)) -{ - MOVZWLrr(s, d); -} -LENDFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s)) - -LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s)) -{ - MOVZBLrr(s, d); -} -LENDFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s)) - -LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s)) -{ - IMULLrr(s, d); -} -LENDFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s)) - -LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s)) -{ - if (d!=MUL_NREG1 || s!=MUL_NREG2) { - write_log("Bad register in IMUL: d=%d, s=%d\n",d,s); - abort(); - } - IMULLr(s); -} -LENDFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s)) - -LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s)) -{ - if (d!=MUL_NREG1 || s!=MUL_NREG2) { - write_log("Bad register in MUL: d=%d, s=%d\n",d,s); - abort(); - } - MULLr(s); -} -LENDFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s)) - -LOWFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s)) -{ - abort(); /* %^$&%^$%#^ x86! */ -} -LENDFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s)) - -LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s)) -{ - MOVBrr(s, d); -} -LENDFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s)) - -LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s)) -{ - MOVWrr(s, d); -} -LENDFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s)) - -LOWFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor)) -{ - ADDR32 MOVLmr(0, baser, index, factor, d); -} -LENDFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor)) -{ - ADDR32 MOVWmr(0, baser, index, factor, d); -} -LENDFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor)) -{ - ADDR32 MOVBmr(0, baser, index, factor, d); -} -LENDFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s)) -{ - ADDR32 MOVLrm(s, 0, baser, index, factor); -} -LENDFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s)) - -LOWFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s)) -{ - ADDR32 MOVWrm(s, 0, baser, index, factor); -} -LENDFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s)) - -LOWFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s)) -{ - ADDR32 MOVBrm(s, 0, baser, index, factor); -} -LENDFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s)) - -LOWFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s)) -{ - ADDR32 MOVLrm(s, base, baser, index, factor); -} -LENDFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s)) - -LOWFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s)) -{ - ADDR32 MOVWrm(s, base, baser, index, factor); -} -LENDFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s)) - -LOWFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s)) -{ - ADDR32 MOVBrm(s, base, baser, index, factor); -} -LENDFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s)) - -LOWFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - ADDR32 MOVLmr(base, baser, index, factor, d); -} -LENDFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - ADDR32 MOVWmr(base, baser, index, factor, d); -} -LENDFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - ADDR32 MOVBmr(base, baser, index, factor, d); -} -LENDFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor)) -{ - ADDR32 MOVLmr(base, X86_NOREG, index, factor, d); -} -LENDFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond)) -{ - if (have_cmov) - ADDR32 CMOVLmr(cond, base, X86_NOREG, index, factor, d); - else { /* replacement using branch and mov */ - int8 *target_p = (int8 *)x86_get_target() + 1; - JCCSii(cond^1, 0); - ADDR32 MOVLmr(base, X86_NOREG, index, factor, d); - *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1); - } -} -LENDFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond)) - -LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond)) -{ - if (have_cmov) - CMOVLmr(cond, mem, X86_NOREG, X86_NOREG, 1, d); - else { /* replacement using branch and mov */ - int8 *target_p = (int8 *)x86_get_target() + 1; - JCCSii(cond^1, 0); - MOVLmr(mem, X86_NOREG, X86_NOREG, 1, d); - *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1); - } -} -LENDFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond)) - -LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset)) -{ - ADDR32 MOVLmr(offset, s, X86_NOREG, 1, d); -} -LENDFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset)) -{ - ADDR32 MOVWmr(offset, s, X86_NOREG, 1, d); -} -LENDFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset)) -{ - ADDR32 MOVBmr(offset, s, X86_NOREG, 1, d); -} -LENDFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset)) -{ - ADDR32 MOVLmr(offset, s, X86_NOREG, 1, d); -} -LENDFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset)) -{ - ADDR32 MOVWmr(offset, s, X86_NOREG, 1, d); -} -LENDFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset)) -{ - ADDR32 MOVBmr(offset, s, X86_NOREG, 1, d); -} -LENDFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset)) -{ - ADDR32 MOVLim(i, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset)) -{ - ADDR32 MOVWim(i, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset)) -{ - ADDR32 MOVBim(i, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset)) -{ - ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset)) -{ - ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset)) -{ - ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset)) - -LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset)) -{ - LEALmr(offset, s, X86_NOREG, 1, d); -} -LENDFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset)) -{ - LEALmr(offset, s, index, factor, d); -} -LENDFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset)) - -LOWFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor)) -{ - LEALmr(0, s, index, factor, d); -} -LENDFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor)) - -LOWFUNC(NONE,NONE,4,raw_lea_l_r_scaled,(W4 d, R4 index, IMM factor)) -{ - LEALmr(0, X86_NOREG, index, factor, d); -} -LENDFUNC(NONE,NONE,4,raw_lea_l_r_scaled,(W4 d, R4 index, IMM factor)) - -LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset)) -{ - ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset)) -{ - ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset)) -{ - ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset)) - -LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r)) -{ - BSWAPLr(r); -} -LENDFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r)) - -LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r)) -{ - ROLWir(8, r); -} -LENDFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r)) - -LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s)) -{ - MOVLrr(s, d); -} -LENDFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s)) -{ - MOVLrm(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s)) -{ - MOVWrm(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s)) - -LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s)) -{ - MOVWmr(s, X86_NOREG, X86_NOREG, 1, d); -} -LENDFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s)) -{ - MOVBrm(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s)) - -LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s)) -{ - MOVBmr(s, X86_NOREG, X86_NOREG, 1, d); -} -LENDFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s)) -{ - MOVLir(s, d); -} -LENDFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s)) -{ - MOVWir(s, d); -} -LENDFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s)) -{ - MOVBir(s, d); -} -LENDFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s)) - -LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s)) -{ - ADCLim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) -{ - ADDLim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) -{ - ADDWim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) -{ - ADDBim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) - -LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i)) -{ - TESTLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s)) -{ - TESTLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s)) -{ - TESTWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s)) -{ - TESTBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i)) -{ - XORLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i)) -{ - ANDLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i)) -{ - ANDWir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s)) -{ - ANDLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s)) -{ - ANDWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s)) -{ - ANDBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i)) -{ - ORLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s)) -{ - ORLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s)) -{ - ORWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s)) -{ - ORBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s)) - -LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s)) -{ - ADCLrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s)) - -LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s)) -{ - ADCWrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s)) - -LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s)) -{ - ADCBrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s)) -{ - ADDLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s)) -{ - ADDWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s)) -{ - ADDBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i)) -{ - SUBLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i)) -{ - SUBBir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i)) -{ - ADDLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i)) -{ - ADDWir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i)) -{ - ADDBir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i)) - -LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s)) -{ - SBBLrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s)) - -LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s)) -{ - SBBWrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s)) - -LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s)) -{ - SBBBrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s)) -{ - SUBLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s)) -{ - SUBWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s)) -{ - SUBBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s)) -{ - CMPLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i)) -{ - CMPLir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s)) -{ - CMPWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s)) - -LOWFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s)) -{ - CMPBim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i)) -{ - CMPBir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s)) -{ - CMPBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s)) - -LOWFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor)) -{ - ADDR32 CMPLmr(offset, X86_NOREG, index, factor, d); -} -LENDFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor)) - -LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s)) -{ - XORLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s)) -{ - XORWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s)) -{ - XORBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s)) -{ - SUBLim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s)) - -LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) -{ - CMPLim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2)) -{ - XCHGLrr(r2, r1); -} -LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2)) - -LOWFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2)) -{ - XCHGBrr(r2, r1); -} -LENDFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2)) - -LOWFUNC(READ,WRITE,0,raw_pushfl,(void)) -{ - PUSHF(); -} -LENDFUNC(READ,WRITE,0,raw_pushfl,(void)) - -LOWFUNC(WRITE,READ,0,raw_popfl,(void)) -{ - POPF(); -} -LENDFUNC(WRITE,READ,0,raw_popfl,(void)) - -/* Generate floating-point instructions */ -static inline void x86_fadd_m(MEMR s) -{ - FADDDm(s,X86_NOREG,X86_NOREG,1); -} - -#else - -const bool optimize_accum = true; -const bool optimize_imm8 = true; -const bool optimize_shift_once = true; - -/************************************************************************* - * Actual encoding of the instructions on the target CPU * - *************************************************************************/ - -static __inline__ int isaccum(int r) -{ - return (r == EAX_INDEX); -} - -static __inline__ int isbyte(uae_s32 x) -{ - return (x>=-128 && x<=127); -} - -static __inline__ int isword(uae_s32 x) -{ - return (x>=-32768 && x<=32767); -} - -LOWFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r)) -{ - emit_byte(0x50+r); -} -LENDFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r)) - -LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r)) -{ - emit_byte(0x58+r); -} -LENDFUNC(NONE,READ,1,raw_pop_l_r,(R4 r)) - -LOWFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d)) -{ - emit_byte(0x8f); - emit_byte(0x05); - emit_long(d); -} -LENDFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d)) - -LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i)) -{ - emit_byte(0x0f); - emit_byte(0xba); - emit_byte(0xe0+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b)) -{ - emit_byte(0x0f); - emit_byte(0xa3); - emit_byte(0xc0+8*b+r); -} -LENDFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b)) - -LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i)) -{ - emit_byte(0x0f); - emit_byte(0xba); - emit_byte(0xf8+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b)) -{ - emit_byte(0x0f); - emit_byte(0xbb); - emit_byte(0xc0+8*b+r); -} -LENDFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b)) - - -LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i)) -{ - emit_byte(0x0f); - emit_byte(0xba); - emit_byte(0xf0+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b)) -{ - emit_byte(0x0f); - emit_byte(0xb3); - emit_byte(0xc0+8*b+r); -} -LENDFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b)) - -LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i)) -{ - emit_byte(0x0f); - emit_byte(0xba); - emit_byte(0xe8+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b)) -{ - emit_byte(0x0f); - emit_byte(0xab); - emit_byte(0xc0+8*b+r); -} -LENDFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b)) - -LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i)) -{ - emit_byte(0x66); - if (isbyte(i)) { - emit_byte(0x83); - emit_byte(0xe8+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x2d); - else { - emit_byte(0x81); - emit_byte(0xe8+d); - } - emit_word(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i)) - - -LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s)) -{ - emit_byte(0x8b); - emit_byte(0x05+8*d); - emit_long(s); -} -LENDFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s)) -{ - emit_byte(0xc7); - emit_byte(0x05); - emit_long(d); - emit_long(s); -} -LENDFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s)) -{ - emit_byte(0x66); - emit_byte(0xc7); - emit_byte(0x05); - emit_long(d); - emit_word(s); -} -LENDFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s)) -{ - emit_byte(0xc6); - emit_byte(0x05); - emit_long(d); - emit_byte(s); -} -LENDFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0x05); - emit_long(d); - } - else { - emit_byte(0xc0); - emit_byte(0x05); - emit_long(d); - emit_byte(i); - } -} -LENDFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0xc0+r); - } - else { - emit_byte(0xc0); - emit_byte(0xc0+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i)) -{ - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xc0+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd1); - emit_byte(0xc0+r); - } - else { - emit_byte(0xc1); - emit_byte(0xc0+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r)) -{ - emit_byte(0xd3); - emit_byte(0xc0+d); -} -LENDFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r)) -{ - emit_byte(0x66); - emit_byte(0xd3); - emit_byte(0xc0+d); -} -LENDFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r)) -{ - emit_byte(0xd2); - emit_byte(0xc0+d); -} -LENDFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r)) -{ - emit_byte(0xd3); - emit_byte(0xe0+d); -} -LENDFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r)) -{ - emit_byte(0x66); - emit_byte(0xd3); - emit_byte(0xe0+d); -} -LENDFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r)) -{ - emit_byte(0xd2); - emit_byte(0xe0+d); -} -LENDFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0xc8+r); - } - else { - emit_byte(0xc0); - emit_byte(0xc8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i)) -{ - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xc8+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i)) - -// gb-- used for making an fpcr value in compemu_fpp.cpp -LOWFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s)) -{ - emit_byte(0x0b); - emit_byte(0x05+8*d); - emit_long(s); -} -LENDFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s)) - -LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd1); - emit_byte(0xc8+r); - } - else { - emit_byte(0xc1); - emit_byte(0xc8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r)) -{ - emit_byte(0xd3); - emit_byte(0xc8+d); -} -LENDFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r)) -{ - emit_byte(0x66); - emit_byte(0xd3); - emit_byte(0xc8+d); -} -LENDFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r)) -{ - emit_byte(0xd2); - emit_byte(0xc8+d); -} -LENDFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r)) -{ - emit_byte(0xd3); - emit_byte(0xe8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r)) -{ - emit_byte(0x66); - emit_byte(0xd3); - emit_byte(0xe8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r)) -{ - emit_byte(0xd2); - emit_byte(0xe8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r)) -{ - emit_byte(0xd3); - emit_byte(0xf8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r)) -{ - emit_byte(0x66); - emit_byte(0xd3); - emit_byte(0xf8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r)) -{ - emit_byte(0xd2); - emit_byte(0xf8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd1); - emit_byte(0xe0+r); - } - else { - emit_byte(0xc1); - emit_byte(0xe0+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i)) -{ - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xe0+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0xe0+r); - } - else { - emit_byte(0xc0); - emit_byte(0xe0+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd1); - emit_byte(0xe8+r); - } - else { - emit_byte(0xc1); - emit_byte(0xe8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i)) -{ - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xe8+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0xe8+r); - } - else { - emit_byte(0xc0); - emit_byte(0xe8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd1); - emit_byte(0xf8+r); - } - else { - emit_byte(0xc1); - emit_byte(0xf8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i)) -{ - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xf8+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0xf8+r); - } - else { - emit_byte(0xc0); - emit_byte(0xf8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah)) -{ - emit_byte(0x9e); -} -LENDFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah)) - -LOWFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax)) -{ - emit_byte(0x0f); - emit_byte(0xa2); -} -LENDFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax)) - -LOWFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah)) -{ - emit_byte(0x9f); -} -LENDFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah)) - -LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc)) -{ - emit_byte(0x0f); - emit_byte(0x90+cc); - emit_byte(0xc0+d); -} -LENDFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc)) - -LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc)) -{ - emit_byte(0x0f); - emit_byte(0x90+cc); - emit_byte(0x05); - emit_long(d); -} -LENDFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc)) - -LOWFUNC(READ,NONE,3,raw_cmov_b_rr,(RW1 d, R1 s, IMM cc)) -{ - /* replacement using branch and mov */ - int uncc=(cc^1); - emit_byte(0x70+uncc); - emit_byte(3); /* skip next 2 bytes if not cc=true */ - emit_byte(0x88); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(READ,NONE,3,raw_cmov_b_rr,(RW1 d, R1 s, IMM cc)) - -LOWFUNC(READ,NONE,3,raw_cmov_w_rr,(RW2 d, R2 s, IMM cc)) -{ - if (have_cmov) { - emit_byte(0x66); - emit_byte(0x0f); - emit_byte(0x40+cc); - emit_byte(0xc0+8*d+s); - } - else { /* replacement using branch and mov */ - int uncc=(cc^1); - emit_byte(0x70+uncc); - emit_byte(3); /* skip next 3 bytes if not cc=true */ - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0xc0+8*s+d); - } -} -LENDFUNC(READ,NONE,3,raw_cmov_w_rr,(RW2 d, R2 s, IMM cc)) - -LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc)) -{ - if (have_cmov) { - emit_byte(0x0f); - emit_byte(0x40+cc); - emit_byte(0xc0+8*d+s); - } - else { /* replacement using branch and mov */ - int uncc=(cc^1); - emit_byte(0x70+uncc); - emit_byte(2); /* skip next 2 bytes if not cc=true */ - emit_byte(0x89); - emit_byte(0xc0+8*s+d); - } -} -LENDFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc)) - -LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s)) -{ - emit_byte(0x0f); - emit_byte(0xbc); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s)) - -LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s)) -{ - emit_byte(0x0f); - emit_byte(0xbf); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s)) - -LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s)) -{ - emit_byte(0x0f); - emit_byte(0xbe); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s)) - -LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s)) -{ - emit_byte(0x0f); - emit_byte(0xb7); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s)) - -LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s)) -{ - emit_byte(0x0f); - emit_byte(0xb6); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s)) - -LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s)) -{ - emit_byte(0x0f); - emit_byte(0xaf); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s)) - -LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s)) -{ - if (d!=MUL_NREG1 || s!=MUL_NREG2) - abort(); - emit_byte(0xf7); - emit_byte(0xea); -} -LENDFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s)) - -LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s)) -{ - if (d!=MUL_NREG1 || s!=MUL_NREG2) { - printf("Bad register in MUL: d=%d, s=%d\n",d,s); - abort(); - } - emit_byte(0xf7); - emit_byte(0xe2); -} -LENDFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s)) - -LOWFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s)) -{ - abort(); /* %^$&%^$%#^ x86! */ - emit_byte(0x0f); - emit_byte(0xaf); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s)) - -LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s)) -{ - emit_byte(0x88); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s)) - -LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s)) - -LOWFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor)) -{ - int isebp=(baser==5)?0x40:0; - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - - emit_byte(0x8b); - emit_byte(0x04+8*d+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor)) -{ - int fi; - int isebp; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - isebp=(baser==5)?0x40:0; - - emit_byte(0x66); - emit_byte(0x8b); - emit_byte(0x04+8*d+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor)) -{ - int fi; - int isebp; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - isebp=(baser==5)?0x40:0; - - emit_byte(0x8a); - emit_byte(0x04+8*d+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s)) -{ - int fi; - int isebp; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - - isebp=(baser==5)?0x40:0; - - emit_byte(0x89); - emit_byte(0x04+8*s+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s)) - -LOWFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s)) -{ - int fi; - int isebp; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - isebp=(baser==5)?0x40:0; - - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0x04+8*s+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s)) - -LOWFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s)) -{ - int fi; - int isebp; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - isebp=(baser==5)?0x40:0; - - emit_byte(0x88); - emit_byte(0x04+8*s+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s)) - -LOWFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x89); - emit_byte(0x84+8*s); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s)) - -LOWFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0x84+8*s); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s)) - -LOWFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x88); - emit_byte(0x84+8*s); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s)) - -LOWFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x8b); - emit_byte(0x84+8*d); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x66); - emit_byte(0x8b); - emit_byte(0x84+8*d); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x8a); - emit_byte(0x84+8*d); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor)) -{ - int fi; - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: - fprintf(stderr,"Bad factor %d in mov_l_rm_indexed!\n",factor); - abort(); - } - emit_byte(0x8b); - emit_byte(0x04+8*d); - emit_byte(0x05+8*index+64*fi); - emit_long(base); -} -LENDFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond)) -{ - int fi; - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: - fprintf(stderr,"Bad factor %d in mov_l_rm_indexed!\n",factor); - abort(); - } - if (have_cmov) { - emit_byte(0x0f); - emit_byte(0x40+cond); - emit_byte(0x04+8*d); - emit_byte(0x05+8*index+64*fi); - emit_long(base); - } - else { /* replacement using branch and mov */ - int uncc=(cond^1); - emit_byte(0x70+uncc); - emit_byte(7); /* skip next 7 bytes if not cc=true */ - emit_byte(0x8b); - emit_byte(0x04+8*d); - emit_byte(0x05+8*index+64*fi); - emit_long(base); - } -} -LENDFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond)) - -LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond)) -{ - if (have_cmov) { - emit_byte(0x0f); - emit_byte(0x40+cond); - emit_byte(0x05+8*d); - emit_long(mem); - } - else { /* replacement using branch and mov */ - int uncc=(cond^1); - emit_byte(0x70+uncc); - emit_byte(6); /* skip next 6 bytes if not cc=true */ - emit_byte(0x8b); - emit_byte(0x05+8*d); - emit_long(mem); - } -} -LENDFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond)) - -LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x8b); - emit_byte(0x40+8*d+s); - emit_byte(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x66); - emit_byte(0x8b); - emit_byte(0x40+8*d+s); - emit_byte(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x8a); - emit_byte(0x40+8*d+s); - emit_byte(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset)) -{ - emit_byte(0x8b); - emit_byte(0x80+8*d+s); - emit_long(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset)) -{ - emit_byte(0x66); - emit_byte(0x8b); - emit_byte(0x80+8*d+s); - emit_long(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset)) -{ - emit_byte(0x8a); - emit_byte(0x80+8*d+s); - emit_long(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0xc7); - emit_byte(0x40+d); - emit_byte(offset); - emit_long(i); -} -LENDFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x66); - emit_byte(0xc7); - emit_byte(0x40+d); - emit_byte(offset); - emit_word(i); -} -LENDFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0xc6); - emit_byte(0x40+d); - emit_byte(offset); - emit_byte(i); -} -LENDFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x89); - emit_byte(0x40+8*s+d); - emit_byte(offset); -} -LENDFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0x40+8*s+d); - emit_byte(offset); -} -LENDFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x88); - emit_byte(0x40+8*s+d); - emit_byte(offset); -} -LENDFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset)) - -LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset)) -{ - if (optimize_imm8 && isbyte(offset)) { - emit_byte(0x8d); - emit_byte(0x40+8*d+s); - emit_byte(offset); - } - else { - emit_byte(0x8d); - emit_byte(0x80+8*d+s); - emit_long(offset); - } -} -LENDFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - if (optimize_imm8 && isbyte(offset)) { - emit_byte(0x8d); - emit_byte(0x44+8*d); - emit_byte(0x40*fi+8*index+s); - emit_byte(offset); - } - else { - emit_byte(0x8d); - emit_byte(0x84+8*d); - emit_byte(0x40*fi+8*index+s); - emit_long(offset); - } -} -LENDFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset)) - -LOWFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor)) -{ - int isebp=(s==5)?0x40:0; - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x8d); - emit_byte(0x04+8*d+isebp); - emit_byte(0x40*fi+8*index+s); - if (isebp) - emit_byte(0); -} -LENDFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor)) - -LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset)) -{ - if (optimize_imm8 && isbyte(offset)) { - emit_byte(0x89); - emit_byte(0x40+8*s+d); - emit_byte(offset); - } - else { - emit_byte(0x89); - emit_byte(0x80+8*s+d); - emit_long(offset); - } -} -LENDFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset)) -{ - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0x80+8*s+d); - emit_long(offset); -} -LENDFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset)) -{ - if (optimize_imm8 && isbyte(offset)) { - emit_byte(0x88); - emit_byte(0x40+8*s+d); - emit_byte(offset); - } - else { - emit_byte(0x88); - emit_byte(0x80+8*s+d); - emit_long(offset); - } -} -LENDFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset)) - -LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r)) -{ - emit_byte(0x0f); - emit_byte(0xc8+r); -} -LENDFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r)) - -LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r)) -{ - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xc0+r); - emit_byte(0x08); -} -LENDFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r)) - -LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s)) -{ - emit_byte(0x89); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s)) -{ - emit_byte(0x89); - emit_byte(0x05+8*s); - emit_long(d); -} -LENDFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0x05+8*s); - emit_long(d); -} -LENDFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s)) - -LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s)) -{ - emit_byte(0x66); - emit_byte(0x8b); - emit_byte(0x05+8*d); - emit_long(s); -} -LENDFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s)) -{ - emit_byte(0x88); - emit_byte(0x05+8*(s&0xf)); /* XXX this handles %ah case (defined as 0x10+4) and others */ - emit_long(d); -} -LENDFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s)) - -LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s)) -{ - emit_byte(0x8a); - emit_byte(0x05+8*d); - emit_long(s); -} -LENDFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s)) -{ - emit_byte(0xb8+d); - emit_long(s); -} -LENDFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s)) -{ - emit_byte(0x66); - emit_byte(0xb8+d); - emit_word(s); -} -LENDFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s)) -{ - emit_byte(0xb0+d); - emit_byte(s); -} -LENDFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s)) - -LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s)) -{ - emit_byte(0x81); - emit_byte(0x15); - emit_long(d); - emit_long(s); -} -LENDFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) -{ - if (optimize_imm8 && isbyte(s)) { - emit_byte(0x83); - emit_byte(0x05); - emit_long(d); - emit_byte(s); - } - else { - emit_byte(0x81); - emit_byte(0x05); - emit_long(d); - emit_long(s); - } -} -LENDFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) -{ - emit_byte(0x66); - emit_byte(0x81); - emit_byte(0x05); - emit_long(d); - emit_word(s); -} -LENDFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) -{ - emit_byte(0x80); - emit_byte(0x05); - emit_long(d); - emit_byte(s); -} -LENDFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) - -LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i)) -{ - if (optimize_accum && isaccum(d)) - emit_byte(0xa9); - else { - emit_byte(0xf7); - emit_byte(0xc0+d); - } - emit_long(i); -} -LENDFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s)) -{ - emit_byte(0x85); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x85); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s)) -{ - emit_byte(0x84); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i)) -{ - emit_byte(0x81); - emit_byte(0xf0+d); - emit_long(i); -} -LENDFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i)) -{ - if (optimize_imm8 && isbyte(i)) { - emit_byte(0x83); - emit_byte(0xe0+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x25); - else { - emit_byte(0x81); - emit_byte(0xe0+d); - } - emit_long(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i)) -{ - emit_byte(0x66); - if (optimize_imm8 && isbyte(i)) { - emit_byte(0x83); - emit_byte(0xe0+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x25); - else { - emit_byte(0x81); - emit_byte(0xe0+d); - } - emit_word(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s)) -{ - emit_byte(0x21); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x21); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s)) -{ - emit_byte(0x20); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i)) -{ - if (optimize_imm8 && isbyte(i)) { - emit_byte(0x83); - emit_byte(0xc8+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x0d); - else { - emit_byte(0x81); - emit_byte(0xc8+d); - } - emit_long(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s)) -{ - emit_byte(0x09); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x09); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s)) -{ - emit_byte(0x08); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s)) - -LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s)) -{ - emit_byte(0x11); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s)) - -LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x11); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s)) - -LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s)) -{ - emit_byte(0x10); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s)) -{ - emit_byte(0x01); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x01); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s)) -{ - emit_byte(0x00); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i)) -{ - if (isbyte(i)) { - emit_byte(0x83); - emit_byte(0xe8+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x2d); - else { - emit_byte(0x81); - emit_byte(0xe8+d); - } - emit_long(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i)) -{ - if (optimize_accum && isaccum(d)) - emit_byte(0x2c); - else { - emit_byte(0x80); - emit_byte(0xe8+d); - } - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i)) -{ - if (isbyte(i)) { - emit_byte(0x83); - emit_byte(0xc0+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x05); - else { - emit_byte(0x81); - emit_byte(0xc0+d); - } - emit_long(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i)) -{ - emit_byte(0x66); - if (isbyte(i)) { - emit_byte(0x83); - emit_byte(0xc0+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x05); - else { - emit_byte(0x81); - emit_byte(0xc0+d); - } - emit_word(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i)) -{ - if (optimize_accum && isaccum(d)) - emit_byte(0x04); - else { - emit_byte(0x80); - emit_byte(0xc0+d); - } - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i)) - -LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s)) -{ - emit_byte(0x19); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s)) - -LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x19); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s)) - -LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s)) -{ - emit_byte(0x18); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s)) -{ - emit_byte(0x29); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x29); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s)) -{ - emit_byte(0x28); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s)) -{ - emit_byte(0x39); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i)) -{ - if (optimize_imm8 && isbyte(i)) { - emit_byte(0x83); - emit_byte(0xf8+r); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(r)) - emit_byte(0x3d); - else { - emit_byte(0x81); - emit_byte(0xf8+r); - } - emit_long(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x39); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s)) - -LOWFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s)) -{ - emit_byte(0x80); - emit_byte(0x3d); - emit_long(d); - emit_byte(s); -} -LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i)) -{ - if (optimize_accum && isaccum(d)) - emit_byte(0x3c); - else { - emit_byte(0x80); - emit_byte(0xf8+d); - } - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s)) -{ - emit_byte(0x38); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s)) - -LOWFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - emit_byte(0x39); - emit_byte(0x04+8*d); - emit_byte(5+8*index+0x40*fi); - emit_long(offset); -} -LENDFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor)) - -LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s)) -{ - emit_byte(0x31); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x31); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s)) -{ - emit_byte(0x30); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s)) -{ - if (optimize_imm8 && isbyte(s)) { - emit_byte(0x83); - emit_byte(0x2d); - emit_long(d); - emit_byte(s); - } - else { - emit_byte(0x81); - emit_byte(0x2d); - emit_long(d); - emit_long(s); - } -} -LENDFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s)) - -LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) -{ - if (optimize_imm8 && isbyte(s)) { - emit_byte(0x83); - emit_byte(0x3d); - emit_long(d); - emit_byte(s); - } - else { - emit_byte(0x81); - emit_byte(0x3d); - emit_long(d); - emit_long(s); - } -} -LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2)) -{ - emit_byte(0x87); - emit_byte(0xc0+8*r1+r2); -} -LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2)) - -LOWFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2)) -{ - emit_byte(0x86); - emit_byte(0xc0+8*(r1&0xf)+(r2&0xf)); /* XXX this handles upper-halves registers (e.g. %ah defined as 0x10+4) */ -} -LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2)) - -/************************************************************************* - * FIXME: mem access modes probably wrong * - *************************************************************************/ - -LOWFUNC(READ,WRITE,0,raw_pushfl,(void)) -{ - emit_byte(0x9c); -} -LENDFUNC(READ,WRITE,0,raw_pushfl,(void)) - -LOWFUNC(WRITE,READ,0,raw_popfl,(void)) -{ - emit_byte(0x9d); -} -LENDFUNC(WRITE,READ,0,raw_popfl,(void)) - -/* Generate floating-point instructions */ -static inline void x86_fadd_m(MEMR s) -{ - emit_byte(0xdc); - emit_byte(0x05); - emit_long(s); -} - -#endif - -/************************************************************************* - * Unoptimizable stuff --- jump * - *************************************************************************/ - -static __inline__ void raw_call_r(R4 r) -{ -#if USE_NEW_RTASM - CALLsr(r); -#else - emit_byte(0xff); - emit_byte(0xd0+r); -#endif -} - -static __inline__ void raw_call_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m) -{ -#if USE_NEW_RTASM - CALLsm(base, X86_NOREG, r, m); -#else - int mu; - switch(m) { - case 1: mu=0; break; - case 2: mu=1; break; - case 4: mu=2; break; - case 8: mu=3; break; - default: abort(); - } - emit_byte(0xff); - emit_byte(0x14); - emit_byte(0x05+8*r+0x40*mu); - emit_long(base); -#endif -} - -static __inline__ void raw_jmp_r(R4 r) -{ -#if USE_NEW_RTASM - JMPsr(r); -#else - emit_byte(0xff); - emit_byte(0xe0+r); -#endif -} - -static __inline__ void raw_jmp_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m) -{ -#if USE_NEW_RTASM - JMPsm(base, X86_NOREG, r, m); -#else - int mu; - switch(m) { - case 1: mu=0; break; - case 2: mu=1; break; - case 4: mu=2; break; - case 8: mu=3; break; - default: abort(); - } - emit_byte(0xff); - emit_byte(0x24); - emit_byte(0x05+8*r+0x40*mu); - emit_long(base); -#endif -} - -static __inline__ void raw_jmp_m(uae_u32 base) -{ - emit_byte(0xff); - emit_byte(0x25); - emit_long(base); -} - - -static __inline__ void raw_call(uae_u32 t) -{ -#if USE_NEW_RTASM - CALLm(t); -#else - emit_byte(0xe8); - emit_long(t-(uae_u32)target-4); -#endif -} - -static __inline__ void raw_jmp(uae_u32 t) -{ -#if USE_NEW_RTASM - JMPm(t); -#else - emit_byte(0xe9); - emit_long(t-(uae_u32)target-4); -#endif -} - -static __inline__ void raw_jl(uae_u32 t) -{ - emit_byte(0x0f); - emit_byte(0x8c); - emit_long(t-(uintptr)target-4); -} - -static __inline__ void raw_jz(uae_u32 t) -{ - emit_byte(0x0f); - emit_byte(0x84); - emit_long(t-(uintptr)target-4); -} - -static __inline__ void raw_jnz(uae_u32 t) -{ - emit_byte(0x0f); - emit_byte(0x85); - emit_long(t-(uintptr)target-4); -} - -static __inline__ void raw_jnz_l_oponly(void) -{ - emit_byte(0x0f); - emit_byte(0x85); -} - -static __inline__ void raw_jcc_l_oponly(int cc) -{ - emit_byte(0x0f); - emit_byte(0x80+cc); -} - -static __inline__ void raw_jnz_b_oponly(void) -{ - emit_byte(0x75); -} - -static __inline__ void raw_jz_b_oponly(void) -{ - emit_byte(0x74); -} - -static __inline__ void raw_jcc_b_oponly(int cc) -{ - emit_byte(0x70+cc); -} - -static __inline__ void raw_jmp_l_oponly(void) -{ - emit_byte(0xe9); -} - -static __inline__ void raw_jmp_b_oponly(void) -{ - emit_byte(0xeb); -} - -static __inline__ void raw_ret(void) -{ - emit_byte(0xc3); -} - -static __inline__ void raw_nop(void) -{ - emit_byte(0x90); -} - -static __inline__ void raw_emit_nop_filler(int nbytes) -{ - /* Source: GNU Binutils 2.12.90.0.15 */ - /* Various efficient no-op patterns for aligning code labels. - Note: Don't try to assemble the instructions in the comments. - 0L and 0w are not legal. */ - static const uae_u8 f32_1[] = - {0x90}; /* nop */ - static const uae_u8 f32_2[] = - {0x89,0xf6}; /* movl %esi,%esi */ - static const uae_u8 f32_3[] = - {0x8d,0x76,0x00}; /* leal 0(%esi),%esi */ - static const uae_u8 f32_4[] = - {0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */ - static const uae_u8 f32_5[] = - {0x90, /* nop */ - 0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */ - static const uae_u8 f32_6[] = - {0x8d,0xb6,0x00,0x00,0x00,0x00}; /* leal 0L(%esi),%esi */ - static const uae_u8 f32_7[] = - {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */ - static const uae_u8 f32_8[] = - {0x90, /* nop */ - 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */ - static const uae_u8 f32_9[] = - {0x89,0xf6, /* movl %esi,%esi */ - 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const uae_u8 f32_10[] = - {0x8d,0x76,0x00, /* leal 0(%esi),%esi */ - 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const uae_u8 f32_11[] = - {0x8d,0x74,0x26,0x00, /* leal 0(%esi,1),%esi */ - 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const uae_u8 f32_12[] = - {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */ - 0x8d,0xbf,0x00,0x00,0x00,0x00}; /* leal 0L(%edi),%edi */ - static const uae_u8 f32_13[] = - {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */ - 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const uae_u8 f32_14[] = - {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00, /* leal 0L(%esi,1),%esi */ - 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const uae_u8 f32_15[] = - {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90, /* jmp .+15; lotsa nops */ - 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}; - static const uae_u8 f32_16[] = - {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90, /* jmp .+15; lotsa nops */ - 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}; - static const uae_u8 *const f32_patt[] = { - f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8, - f32_9, f32_10, f32_11, f32_12, f32_13, f32_14, f32_15 - }; - static const uae_u8 prefixes[4] = { 0x66, 0x66, 0x66, 0x66 }; - -#if defined(__x86_64__) - /* The recommended way to pad 64bit code is to use NOPs preceded by - maximally four 0x66 prefixes. Balance the size of nops. */ - if (nbytes == 0) - return; - - int i; - int nnops = (nbytes + 3) / 4; - int len = nbytes / nnops; - int remains = nbytes - nnops * len; - - for (i = 0; i < remains; i++) { - emit_block(prefixes, len); - raw_nop(); - } - for (; i < nnops; i++) { - emit_block(prefixes, len - 1); - raw_nop(); - } -#else - int nloops = nbytes / 16; - while (nloops-- > 0) - emit_block(f32_16, sizeof(f32_16)); - - nbytes %= 16; - if (nbytes) - emit_block(f32_patt[nbytes - 1], nbytes); -#endif -} - - -/************************************************************************* - * Flag handling, to and fro UAE flag register * - *************************************************************************/ - -static __inline__ void raw_flags_evicted(int r) -{ - //live.state[FLAGTMP].status=CLEAN; - live.state[FLAGTMP].status=INMEM; - live.state[FLAGTMP].realreg=-1; - /* We just "evicted" FLAGTMP. */ - if (live.nat[r].nholds!=1) { - /* Huh? */ - abort(); - } - live.nat[r].nholds=0; -} - -#define FLAG_NREG1_FLAGREG 0 /* Set to -1 if any register will do */ -static __inline__ void raw_flags_to_reg_FLAGREG(int r) -{ - raw_lahf(0); /* Most flags in AH */ - //raw_setcc(r,0); /* V flag in AL */ - raw_setcc_m((uintptr)live.state[FLAGTMP].mem,0); - -#if 1 /* Let's avoid those nasty partial register stalls */ - //raw_mov_b_mr((uintptr)live.state[FLAGTMP].mem,r); - raw_mov_b_mr(((uintptr)live.state[FLAGTMP].mem)+1,AH_INDEX); - raw_flags_evicted(r); -#endif -} - -#define FLAG_NREG2_FLAGREG 0 /* Set to -1 if any register will do */ -static __inline__ void raw_reg_to_flags_FLAGREG(int r) -{ - raw_cmp_b_ri(r,-127); /* set V */ - raw_sahf(0); -} - -#define FLAG_NREG3_FLAGREG 0 /* Set to -1 if any register will do */ -static __inline__ void raw_flags_set_zero_FLAGREG(int s, int tmp) -{ - raw_mov_l_rr(tmp,s); - raw_lahf(s); /* flags into ah */ - raw_and_l_ri(s,0xffffbfff); - raw_and_l_ri(tmp,0x00004000); - raw_xor_l_ri(tmp,0x00004000); - raw_or_l(s,tmp); - raw_sahf(s); -} - -static __inline__ void raw_flags_init_FLAGREG(void) { } - -#define FLAG_NREG1_FLAGSTK -1 /* Set to -1 if any register will do */ -static __inline__ void raw_flags_to_reg_FLAGSTK(int r) -{ - raw_pushfl(); - raw_pop_l_r(r); - raw_mov_l_mr((uintptr)live.state[FLAGTMP].mem,r); - raw_flags_evicted(r); -} - -#define FLAG_NREG2_FLAGSTK -1 /* Set to -1 if any register will do */ -static __inline__ void raw_reg_to_flags_FLAGSTK(int r) -{ - raw_push_l_r(r); - raw_popfl(); -} - -#define FLAG_NREG3_FLAGSTK -1 /* Set to -1 if any register will do */ -static __inline__ void raw_flags_set_zero_FLAGSTK(int s, int tmp) -{ - raw_mov_l_rr(tmp,s); - raw_pushfl(); - raw_pop_l_r(s); - raw_and_l_ri(s,0xffffffbf); - raw_and_l_ri(tmp,0x00000040); - raw_xor_l_ri(tmp,0x00000040); - raw_or_l(s,tmp); - raw_push_l_r(s); - raw_popfl(); -} - -static __inline__ void raw_flags_init_FLAGSTK(void) { } - -#if defined(__x86_64__) -/* Try to use the LAHF/SETO method on x86_64 since it is faster. - This can't be the default because some older CPUs don't support - LAHF/SAHF in long mode. */ -static int FLAG_NREG1_FLAGGEN = 0; -static __inline__ void raw_flags_to_reg_FLAGGEN(int r) -{ - if (have_lahf_lm) { - // NOTE: the interpreter uses the normal EFLAGS layout - // pushf/popf CF(0) ZF( 6) SF( 7) OF(11) - // sahf/lahf CF(8) ZF(14) SF(15) OF( 0) - assert(r == 0); - raw_setcc(r,0); /* V flag in AL */ - raw_lea_l_r_scaled(0,0,8); /* move it to its EFLAGS location */ - raw_mov_b_mr(((uintptr)live.state[FLAGTMP].mem)+1,0); - raw_lahf(0); /* most flags in AH */ - raw_mov_b_mr((uintptr)live.state[FLAGTMP].mem,AH_INDEX); - raw_flags_evicted(r); - } - else - raw_flags_to_reg_FLAGSTK(r); -} - -static int FLAG_NREG2_FLAGGEN = 0; -static __inline__ void raw_reg_to_flags_FLAGGEN(int r) -{ - if (have_lahf_lm) { - raw_xchg_b_rr(0,AH_INDEX); - raw_cmp_b_ri(r,-120); /* set V */ - raw_sahf(0); - } - else - raw_reg_to_flags_FLAGSTK(r); -} - -static int FLAG_NREG3_FLAGGEN = 0; -static __inline__ void raw_flags_set_zero_FLAGGEN(int s, int tmp) -{ - if (have_lahf_lm) - raw_flags_set_zero_FLAGREG(s, tmp); - else - raw_flags_set_zero_FLAGSTK(s, tmp); -} - -static __inline__ void raw_flags_init_FLAGGEN(void) -{ - if (have_lahf_lm) { - FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGREG; - FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGREG; - FLAG_NREG1_FLAGGEN = FLAG_NREG3_FLAGREG; - } - else { - FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGSTK; - FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGSTK; - FLAG_NREG1_FLAGGEN = FLAG_NREG3_FLAGSTK; - } -} -#endif - -#ifdef SAHF_SETO_PROFITABLE -#define FLAG_SUFFIX FLAGREG -#elif defined __x86_64__ -#define FLAG_SUFFIX FLAGGEN -#else -#define FLAG_SUFFIX FLAGSTK -#endif - -#define FLAG_GLUE_2(x, y) x ## _ ## y -#define FLAG_GLUE_1(x, y) FLAG_GLUE_2(x, y) -#define FLAG_GLUE(x) FLAG_GLUE_1(x, FLAG_SUFFIX) - -#define raw_flags_init FLAG_GLUE(raw_flags_init) -#define FLAG_NREG1 FLAG_GLUE(FLAG_NREG1) -#define raw_flags_to_reg FLAG_GLUE(raw_flags_to_reg) -#define FLAG_NREG2 FLAG_GLUE(FLAG_NREG2) -#define raw_reg_to_flags FLAG_GLUE(raw_reg_to_flags) -#define FLAG_NREG3 FLAG_GLUE(FLAG_NREG3) -#define raw_flags_set_zero FLAG_GLUE(raw_flags_set_zero) - -/* Apparently, there are enough instructions between flag store and - flag reload to avoid the partial memory stall */ -static __inline__ void raw_load_flagreg(uae_u32 target, uae_u32 r) -{ -#if 1 - raw_mov_l_rm(target,(uintptr)live.state[r].mem); -#else - raw_mov_b_rm(target,(uintptr)live.state[r].mem); - raw_mov_b_rm(target+4,((uintptr)live.state[r].mem)+1); -#endif -} - -/* FLAGX is byte sized, and we *do* write it at that size */ -static __inline__ void raw_load_flagx(uae_u32 target, uae_u32 r) -{ - if (live.nat[target].canbyte) - raw_mov_b_rm(target,(uintptr)live.state[r].mem); - else if (live.nat[target].canword) - raw_mov_w_rm(target,(uintptr)live.state[r].mem); - else - raw_mov_l_rm(target,(uintptr)live.state[r].mem); -} - -static __inline__ void raw_dec_sp(int off) -{ - if (off) raw_sub_l_ri(ESP_INDEX,off); -} - -static __inline__ void raw_inc_sp(int off) -{ - if (off) raw_add_l_ri(ESP_INDEX,off); -} - -/************************************************************************* - * Handling mistaken direct memory access * - *************************************************************************/ - -// gb-- I don't need that part for JIT Basilisk II -#if defined(NATMEM_OFFSET) && 0 -#include -#include - -#define SIG_READ 1 -#define SIG_WRITE 2 - -static int in_handler=0; -static uae_u8 veccode[256]; - -static void vec(int x, struct sigcontext sc) -{ - uae_u8* i=(uae_u8*)sc.eip; - uae_u32 addr=sc.cr2; - int r=-1; - int size=4; - int dir=-1; - int len=0; - int j; - - write_log("fault address is %08x at %08x\n",sc.cr2,sc.eip); - if (!canbang) - write_log("Not happy! Canbang is 0 in SIGSEGV handler!\n"); - if (in_handler) - write_log("Argh --- Am already in a handler. Shouldn't happen!\n"); - - if (canbang && i>=compiled_code && i<=current_compile_p) { - if (*i==0x66) { - i++; - size=2; - len++; - } - - switch(i[0]) { - case 0x8a: - if ((i[1]&0xc0)==0x80) { - r=(i[1]>>3)&7; - dir=SIG_READ; - size=1; - len+=6; - break; - } - break; - case 0x88: - if ((i[1]&0xc0)==0x80) { - r=(i[1]>>3)&7; - dir=SIG_WRITE; - size=1; - len+=6; - break; - } - break; - case 0x8b: - if ((i[1]&0xc0)==0x80) { - r=(i[1]>>3)&7; - dir=SIG_READ; - len+=6; - break; - } - if ((i[1]&0xc0)==0x40) { - r=(i[1]>>3)&7; - dir=SIG_READ; - len+=3; - break; - } - break; - case 0x89: - if ((i[1]&0xc0)==0x80) { - r=(i[1]>>3)&7; - dir=SIG_WRITE; - len+=6; - break; - } - if ((i[1]&0xc0)==0x40) { - r=(i[1]>>3)&7; - dir=SIG_WRITE; - len+=3; - break; - } - break; - } - } - - if (r!=-1) { - void* pr=NULL; - write_log("register was %d, direction was %d, size was %d\n",r,dir,size); - - switch(r) { - case 0: pr=&(sc.eax); break; - case 1: pr=&(sc.ecx); break; - case 2: pr=&(sc.edx); break; - case 3: pr=&(sc.ebx); break; - case 4: pr=(size>1)?NULL:(((uae_u8*)&(sc.eax))+1); break; - case 5: pr=(size>1)? - (void*)(&(sc.ebp)): - (void*)(((uae_u8*)&(sc.ecx))+1); break; - case 6: pr=(size>1)? - (void*)(&(sc.esi)): - (void*)(((uae_u8*)&(sc.edx))+1); break; - case 7: pr=(size>1)? - (void*)(&(sc.edi)): - (void*)(((uae_u8*)&(sc.ebx))+1); break; - default: abort(); - } - if (pr) { - blockinfo* bi; - - if (currprefs.comp_oldsegv) { - addr-=NATMEM_OFFSET; - - if ((addr>=0x10000000 && addr<0x40000000) || - (addr>=0x50000000)) { - write_log("Suspicious address in %x SEGV handler.\n",addr); - } - if (dir==SIG_READ) { - switch(size) { - case 1: *((uae_u8*)pr)=get_byte(addr); break; - case 2: *((uae_u16*)pr)=get_word(addr); break; - case 4: *((uae_u32*)pr)=get_long(addr); break; - default: abort(); - } - } - else { /* write */ - switch(size) { - case 1: put_byte(addr,*((uae_u8*)pr)); break; - case 2: put_word(addr,*((uae_u16*)pr)); break; - case 4: put_long(addr,*((uae_u32*)pr)); break; - default: abort(); - } - } - write_log("Handled one access!\n"); - fflush(stdout); - segvcount++; - sc.eip+=len; - } - else { - void* tmp=target; - int i; - uae_u8 vecbuf[5]; - - addr-=NATMEM_OFFSET; - - if ((addr>=0x10000000 && addr<0x40000000) || - (addr>=0x50000000)) { - write_log("Suspicious address in %x SEGV handler.\n",addr); - } - - target=(uae_u8*)sc.eip; - for (i=0;i<5;i++) - vecbuf[i]=target[i]; - emit_byte(0xe9); - emit_long((uintptr)veccode-(uintptr)target-4); - write_log("Create jump to %p\n",veccode); - - write_log("Handled one access!\n"); - fflush(stdout); - segvcount++; - - target=veccode; - - if (dir==SIG_READ) { - switch(size) { - case 1: raw_mov_b_ri(r,get_byte(addr)); break; - case 2: raw_mov_w_ri(r,get_byte(addr)); break; - case 4: raw_mov_l_ri(r,get_byte(addr)); break; - default: abort(); - } - } - else { /* write */ - switch(size) { - case 1: put_byte(addr,*((uae_u8*)pr)); break; - case 2: put_word(addr,*((uae_u16*)pr)); break; - case 4: put_long(addr,*((uae_u32*)pr)); break; - default: abort(); - } - } - for (i=0;i<5;i++) - raw_mov_b_mi(sc.eip+i,vecbuf[i]); - raw_mov_l_mi((uintptr)&in_handler,0); - emit_byte(0xe9); - emit_long(sc.eip+len-(uintptr)target-4); - in_handler=1; - target=tmp; - } - bi=active; - while (bi) { - if (bi->handler && - (uae_u8*)bi->direct_handler<=i && - (uae_u8*)bi->nexthandler>i) { - write_log("deleted trigger (%p<%p<%p) %p\n", - bi->handler, - i, - bi->nexthandler, - bi->pc_p); - invalidate_block(bi); - raise_in_cl_list(bi); - set_special(0); - return; - } - bi=bi->next; - } - /* Not found in the active list. Might be a rom routine that - is in the dormant list */ - bi=dormant; - while (bi) { - if (bi->handler && - (uae_u8*)bi->direct_handler<=i && - (uae_u8*)bi->nexthandler>i) { - write_log("deleted trigger (%p<%p<%p) %p\n", - bi->handler, - i, - bi->nexthandler, - bi->pc_p); - invalidate_block(bi); - raise_in_cl_list(bi); - set_special(0); - return; - } - bi=bi->next; - } - write_log("Huh? Could not find trigger!\n"); - return; - } - } - write_log("Can't handle access!\n"); - for (j=0;j<10;j++) { - write_log("instruction byte %2d is %02x\n",j,i[j]); - } - write_log("Please send the above info (starting at \"fault address\") to\n" - "bmeyer@csse.monash.edu.au\n" - "This shouldn't happen ;-)\n"); - fflush(stdout); - signal(SIGSEGV,SIG_DFL); /* returning here will cause a "real" SEGV */ -} -#endif - - -/************************************************************************* - * Checking for CPU features * - *************************************************************************/ - -struct cpuinfo_x86 { - uae_u8 x86; // CPU family - uae_u8 x86_vendor; // CPU vendor - uae_u8 x86_processor; // CPU canonical processor type - uae_u8 x86_brand_id; // CPU BrandID if supported, yield 0 otherwise - uae_u32 x86_hwcap; - uae_u8 x86_model; - uae_u8 x86_mask; - int cpuid_level; // Maximum supported CPUID level, -1=no CPUID - char x86_vendor_id[16]; -}; -struct cpuinfo_x86 cpuinfo; - -enum { - X86_VENDOR_INTEL = 0, - X86_VENDOR_CYRIX = 1, - X86_VENDOR_AMD = 2, - X86_VENDOR_UMC = 3, - X86_VENDOR_NEXGEN = 4, - X86_VENDOR_CENTAUR = 5, - X86_VENDOR_RISE = 6, - X86_VENDOR_TRANSMETA = 7, - X86_VENDOR_NSC = 8, - X86_VENDOR_UNKNOWN = 0xff -}; - -enum { - X86_PROCESSOR_I386, /* 80386 */ - X86_PROCESSOR_I486, /* 80486DX, 80486SX, 80486DX[24] */ - X86_PROCESSOR_PENTIUM, - X86_PROCESSOR_PENTIUMPRO, - X86_PROCESSOR_K6, - X86_PROCESSOR_ATHLON, - X86_PROCESSOR_PENTIUM4, - X86_PROCESSOR_X86_64, - X86_PROCESSOR_max -}; - -static const char * x86_processor_string_table[X86_PROCESSOR_max] = { - "80386", - "80486", - "Pentium", - "PentiumPro", - "K6", - "Athlon", - "Pentium4", - "x86-64" -}; - -static struct ptt { - const int align_loop; - const int align_loop_max_skip; - const int align_jump; - const int align_jump_max_skip; - const int align_func; -} -x86_alignments[X86_PROCESSOR_max] = { - { 4, 3, 4, 3, 4 }, - { 16, 15, 16, 15, 16 }, - { 16, 7, 16, 7, 16 }, - { 16, 15, 16, 7, 16 }, - { 32, 7, 32, 7, 32 }, - { 16, 7, 16, 7, 16 }, - { 0, 0, 0, 0, 0 }, - { 16, 7, 16, 7, 16 } -}; - -static void -x86_get_cpu_vendor(struct cpuinfo_x86 *c) -{ - char *v = c->x86_vendor_id; - - if (!strcmp(v, "GenuineIntel")) - c->x86_vendor = X86_VENDOR_INTEL; - else if (!strcmp(v, "AuthenticAMD")) - c->x86_vendor = X86_VENDOR_AMD; - else if (!strcmp(v, "CyrixInstead")) - c->x86_vendor = X86_VENDOR_CYRIX; - else if (!strcmp(v, "Geode by NSC")) - c->x86_vendor = X86_VENDOR_NSC; - else if (!strcmp(v, "UMC UMC UMC ")) - c->x86_vendor = X86_VENDOR_UMC; - else if (!strcmp(v, "CentaurHauls")) - c->x86_vendor = X86_VENDOR_CENTAUR; - else if (!strcmp(v, "NexGenDriven")) - c->x86_vendor = X86_VENDOR_NEXGEN; - else if (!strcmp(v, "RiseRiseRise")) - c->x86_vendor = X86_VENDOR_RISE; - else if (!strcmp(v, "GenuineTMx86") || - !strcmp(v, "TransmetaCPU")) - c->x86_vendor = X86_VENDOR_TRANSMETA; - else - c->x86_vendor = X86_VENDOR_UNKNOWN; -} - -static void -cpuid(uae_u32 op, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx) -{ - const int CPUID_SPACE = 4096; - uae_u8* cpuid_space = (uae_u8 *)vm_acquire(CPUID_SPACE); - if (cpuid_space == VM_MAP_FAILED) - abort(); - vm_protect(cpuid_space, CPUID_SPACE, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE); - - static uae_u32 s_op, s_eax, s_ebx, s_ecx, s_edx; - uae_u8* tmp=get_target(); - - s_op = op; - set_target(cpuid_space); - raw_push_l_r(0); /* eax */ - raw_push_l_r(1); /* ecx */ - raw_push_l_r(2); /* edx */ - raw_push_l_r(3); /* ebx */ - raw_mov_l_rm(0,(uintptr)&s_op); - raw_cpuid(0); - raw_mov_l_mr((uintptr)&s_eax,0); - raw_mov_l_mr((uintptr)&s_ebx,3); - raw_mov_l_mr((uintptr)&s_ecx,1); - raw_mov_l_mr((uintptr)&s_edx,2); - raw_pop_l_r(3); - raw_pop_l_r(2); - raw_pop_l_r(1); - raw_pop_l_r(0); - raw_ret(); - set_target(tmp); - - ((cpuop_func*)cpuid_space)(0); - if (eax != NULL) *eax = s_eax; - if (ebx != NULL) *ebx = s_ebx; - if (ecx != NULL) *ecx = s_ecx; - if (edx != NULL) *edx = s_edx; - - vm_release(cpuid_space, CPUID_SPACE); -} - -static void -raw_init_cpu(void) -{ - struct cpuinfo_x86 *c = &cpuinfo; - - /* Defaults */ - c->x86_processor = X86_PROCESSOR_max; - c->x86_vendor = X86_VENDOR_UNKNOWN; - c->cpuid_level = -1; /* CPUID not detected */ - c->x86_model = c->x86_mask = 0; /* So far unknown... */ - c->x86_vendor_id[0] = '\0'; /* Unset */ - c->x86_hwcap = 0; - - /* Get vendor name */ - c->x86_vendor_id[12] = '\0'; - cpuid(0x00000000, - (uae_u32 *)&c->cpuid_level, - (uae_u32 *)&c->x86_vendor_id[0], - (uae_u32 *)&c->x86_vendor_id[8], - (uae_u32 *)&c->x86_vendor_id[4]); - x86_get_cpu_vendor(c); - - /* Intel-defined flags: level 0x00000001 */ - c->x86_brand_id = 0; - if ( c->cpuid_level >= 0x00000001 ) { - uae_u32 tfms, brand_id; - cpuid(0x00000001, &tfms, &brand_id, NULL, &c->x86_hwcap); - c->x86 = (tfms >> 8) & 15; - if (c->x86 == 0xf) - c->x86 += (tfms >> 20) & 0xff; /* extended family */ - c->x86_model = (tfms >> 4) & 15; - if (c->x86_model == 0xf) - c->x86_model |= (tfms >> 12) & 0xf0; /* extended model */ - c->x86_brand_id = brand_id & 0xff; - c->x86_mask = tfms & 15; - } else { - /* Have CPUID level 0 only - unheard of */ - c->x86 = 4; - } - - /* AMD-defined flags: level 0x80000001 */ - uae_u32 xlvl; - cpuid(0x80000000, &xlvl, NULL, NULL, NULL); - if ( (xlvl & 0xffff0000) == 0x80000000 ) { - if ( xlvl >= 0x80000001 ) { - uae_u32 features, extra_features; - cpuid(0x80000001, NULL, NULL, &extra_features, &features); - if (features & (1 << 29)) { - /* Assume x86-64 if long mode is supported */ - c->x86_processor = X86_PROCESSOR_X86_64; - } - if (extra_features & (1 << 0)) - have_lahf_lm = true; - } - } - - /* Canonicalize processor ID */ - switch (c->x86) { - case 3: - c->x86_processor = X86_PROCESSOR_I386; - break; - case 4: - c->x86_processor = X86_PROCESSOR_I486; - break; - case 5: - if (c->x86_vendor == X86_VENDOR_AMD) - c->x86_processor = X86_PROCESSOR_K6; - else - c->x86_processor = X86_PROCESSOR_PENTIUM; - break; - case 6: - if (c->x86_vendor == X86_VENDOR_AMD) - c->x86_processor = X86_PROCESSOR_ATHLON; - else - c->x86_processor = X86_PROCESSOR_PENTIUMPRO; - break; - case 15: - if (c->x86_processor == X86_PROCESSOR_max) { - switch (c->x86_vendor) { - case X86_VENDOR_INTEL: - c->x86_processor = X86_PROCESSOR_PENTIUM4; - break; - case X86_VENDOR_AMD: - /* Assume a 32-bit Athlon processor if not in long mode */ - c->x86_processor = X86_PROCESSOR_ATHLON; - break; - } - } - break; - } - if (c->x86_processor == X86_PROCESSOR_max) { - c->x86_processor = X86_PROCESSOR_I386; - fprintf(stderr, "Error: unknown processor type, assuming i386\n"); - fprintf(stderr, " Family : %d\n", c->x86); - fprintf(stderr, " Model : %d\n", c->x86_model); - fprintf(stderr, " Mask : %d\n", c->x86_mask); - fprintf(stderr, " Vendor : %s [%d]\n", c->x86_vendor_id, c->x86_vendor); - if (c->x86_brand_id) - fprintf(stderr, " BrandID : %02x\n", c->x86_brand_id); - } - - /* Have CMOV support? */ - have_cmov = (c->x86_hwcap & (1 << 15)) != 0; -#if defined(__x86_64__) - if (!have_cmov) { - write_log("x86-64 implementations are bound to have CMOV!\n"); - abort(); - } -#endif - - /* Can the host CPU suffer from partial register stalls? */ - have_rat_stall = (c->x86_vendor == X86_VENDOR_INTEL); -#if 1 - /* It appears that partial register writes are a bad idea even on - AMD K7 cores, even though they are not supposed to have the - dreaded rat stall. Why? Anyway, that's why we lie about it ;-) */ - if (c->x86_processor == X86_PROCESSOR_ATHLON) - have_rat_stall = true; -#endif - - /* Alignments */ - if (tune_alignment) { - align_loops = x86_alignments[c->x86_processor].align_loop; - align_jumps = x86_alignments[c->x86_processor].align_jump; - } - - write_log("Max CPUID level=%d Processor is %s [%s]\n", - c->cpuid_level, c->x86_vendor_id, - x86_processor_string_table[c->x86_processor]); - - raw_flags_init(); -} - -static bool target_check_bsf(void) -{ - bool mismatch = false; - for (int g_ZF = 0; g_ZF <= 1; g_ZF++) { - for (int g_CF = 0; g_CF <= 1; g_CF++) { - for (int g_OF = 0; g_OF <= 1; g_OF++) { - for (int g_SF = 0; g_SF <= 1; g_SF++) { - for (int value = -1; value <= 1; value++) { - unsigned long flags = (g_SF << 7) | (g_OF << 11) | (g_ZF << 6) | g_CF; - unsigned long tmp = value; -#ifdef _MSC_VER - __writeeflags(flags); - _BitScanForward(&tmp, value); - flags = __readeflags(); -#else - __asm__ __volatile__ ("push %0; popf; bsf %1,%1; pushf; pop %0" - : "+r" (flags), "+r" (tmp) : : "cc"); -#endif - int OF = (flags >> 11) & 1; - int SF = (flags >> 7) & 1; - int ZF = (flags >> 6) & 1; - int CF = flags & 1; - tmp = (value == 0); - if (ZF != tmp || SF != g_SF || OF != g_OF || CF != g_CF) - mismatch = true; - } - }}}} - if (mismatch) - write_log("Target CPU defines all flags on BSF instruction\n"); - return !mismatch; -} - - -/************************************************************************* - * FPU stuff * - *************************************************************************/ - - -static __inline__ void raw_fp_init(void) -{ - int i; - - for (i=0;i1) { - emit_byte(0x9b); - emit_byte(0xdb); - emit_byte(0xe3); - live.tos=-1; - } -#endif - while (live.tos>=1) { - emit_byte(0xde); - emit_byte(0xd9); - live.tos-=2; - } - while (live.tos>=0) { - emit_byte(0xdd); - emit_byte(0xd8); - live.tos--; - } - raw_fp_init(); -} - -static __inline__ void make_tos(int r) -{ - int p,q; - - if (live.spos[r]<0) { /* Register not yet on stack */ - emit_byte(0xd9); - emit_byte(0xe8); /* Push '1' on the stack, just to grow it */ - live.tos++; - live.spos[r]=live.tos; - live.onstack[live.tos]=r; - return; - } - /* Register is on stack */ - if (live.tos==live.spos[r]) - return; - p=live.spos[r]; - q=live.onstack[live.tos]; - - emit_byte(0xd9); - emit_byte(0xc8+live.tos-live.spos[r]); /* exchange it with top of stack */ - live.onstack[live.tos]=r; - live.spos[r]=live.tos; - live.onstack[p]=q; - live.spos[q]=p; -} - -static __inline__ void make_tos2(int r, int r2) -{ - int q; - - make_tos(r2); /* Put the reg that's supposed to end up in position2 - on top */ - - if (live.spos[r]<0) { /* Register not yet on stack */ - make_tos(r); /* This will extend the stack */ - return; - } - /* Register is on stack */ - emit_byte(0xd9); - emit_byte(0xc9); /* Move r2 into position 2 */ - - q=live.onstack[live.tos-1]; - live.onstack[live.tos]=q; - live.spos[q]=live.tos; - live.onstack[live.tos-1]=r2; - live.spos[r2]=live.tos-1; - - make_tos(r); /* And r into 1 */ -} - -static __inline__ int stackpos(int r) -{ - if (live.spos[r]<0) - abort(); - if (live.tos=0) { - /* source is on top of stack, and we already have the dest */ - int dd=stackpos(d); - emit_byte(0xdd); - emit_byte(0xd0+dd); - } - else { - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source on tos */ - tos_make(d); /* store to destination, pop if necessary */ - } -} -LENDFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s)) - -LOWFUNC(NONE,READ,4,raw_fldcw_m_indexed,(R4 index, IMM base)) -{ - emit_byte(0xd9); - emit_byte(0xa8+index); - emit_long(base); -} -LENDFUNC(NONE,READ,4,raw_fldcw_m_indexed,(R4 index, IMM base)) - - -LOWFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s)) -{ - int ds; - - if (d!=s) { - usereg(s); - ds=stackpos(s); - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source */ - emit_byte(0xd9); - emit_byte(0xfa); /* take square root */ - tos_make(d); /* store to destination */ - } - else { - make_tos(d); - emit_byte(0xd9); - emit_byte(0xfa); /* take square root */ - } -} -LENDFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s)) -{ - int ds; - - if (d!=s) { - usereg(s); - ds=stackpos(s); - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source */ - emit_byte(0xd9); - emit_byte(0xe1); /* take fabs */ - tos_make(d); /* store to destination */ - } - else { - make_tos(d); - emit_byte(0xd9); - emit_byte(0xe1); /* take fabs */ - } -} -LENDFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s)) -{ - int ds; - - if (d!=s) { - usereg(s); - ds=stackpos(s); - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source */ - emit_byte(0xd9); - emit_byte(0xfc); /* take frndint */ - tos_make(d); /* store to destination */ - } - else { - make_tos(d); - emit_byte(0xd9); - emit_byte(0xfc); /* take frndint */ - } -} -LENDFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s)) -{ - int ds; - - if (d!=s) { - usereg(s); - ds=stackpos(s); - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source */ - emit_byte(0xd9); - emit_byte(0xff); /* take cos */ - tos_make(d); /* store to destination */ - } - else { - make_tos(d); - emit_byte(0xd9); - emit_byte(0xff); /* take cos */ - } -} -LENDFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s)) -{ - int ds; - - if (d!=s) { - usereg(s); - ds=stackpos(s); - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source */ - emit_byte(0xd9); - emit_byte(0xfe); /* take sin */ - tos_make(d); /* store to destination */ - } - else { - make_tos(d); - emit_byte(0xd9); - emit_byte(0xfe); /* take sin */ - } -} -LENDFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s)) - -static const double one=1; -LOWFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s)) -{ - int ds; - - usereg(s); - ds=stackpos(s); - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source */ - - emit_byte(0xd9); - emit_byte(0xc0); /* duplicate top of stack. Now up to 8 high */ - emit_byte(0xd9); - emit_byte(0xfc); /* rndint */ - emit_byte(0xd9); - emit_byte(0xc9); /* swap top two elements */ - emit_byte(0xd8); - emit_byte(0xe1); /* subtract rounded from original */ - emit_byte(0xd9); - emit_byte(0xf0); /* f2xm1 */ - x86_fadd_m((uintptr)&one); /* Add '1' without using extra stack space */ - emit_byte(0xd9); - emit_byte(0xfd); /* and scale it */ - emit_byte(0xdd); - emit_byte(0xd9); /* take he rounded value off */ - tos_make(d); /* store to destination */ -} -LENDFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s)) -{ - int ds; - - usereg(s); - ds=stackpos(s); - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source */ - emit_byte(0xd9); - emit_byte(0xea); /* fldl2e */ - emit_byte(0xde); - emit_byte(0xc9); /* fmulp --- multiply source by log2(e) */ - - emit_byte(0xd9); - emit_byte(0xc0); /* duplicate top of stack. Now up to 8 high */ - emit_byte(0xd9); - emit_byte(0xfc); /* rndint */ - emit_byte(0xd9); - emit_byte(0xc9); /* swap top two elements */ - emit_byte(0xd8); - emit_byte(0xe1); /* subtract rounded from original */ - emit_byte(0xd9); - emit_byte(0xf0); /* f2xm1 */ - x86_fadd_m((uintptr)&one); /* Add '1' without using extra stack space */ - emit_byte(0xd9); - emit_byte(0xfd); /* and scale it */ - emit_byte(0xdd); - emit_byte(0xd9); /* take he rounded value off */ - tos_make(d); /* store to destination */ -} -LENDFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s)) -{ - int ds; - - usereg(s); - ds=stackpos(s); - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source */ - emit_byte(0xd9); - emit_byte(0xe8); /* push '1' */ - emit_byte(0xd9); - emit_byte(0xc9); /* swap top two */ - emit_byte(0xd9); - emit_byte(0xf1); /* take 1*log2(x) */ - tos_make(d); /* store to destination */ -} -LENDFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s)) - - -LOWFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s)) -{ - int ds; - - if (d!=s) { - usereg(s); - ds=stackpos(s); - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source */ - emit_byte(0xd9); - emit_byte(0xe0); /* take fchs */ - tos_make(d); /* store to destination */ - } - else { - make_tos(d); - emit_byte(0xd9); - emit_byte(0xe0); /* take fchs */ - } -} -LENDFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s)) -{ - int ds; - - usereg(s); - usereg(d); - - if (live.spos[s]==live.tos) { - /* Source is on top of stack */ - ds=stackpos(d); - emit_byte(0xdc); - emit_byte(0xc0+ds); /* add source to dest*/ - } - else { - make_tos(d); - ds=stackpos(s); - - emit_byte(0xd8); - emit_byte(0xc0+ds); /* add source to dest*/ - } -} -LENDFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s)) -{ - int ds; - - usereg(s); - usereg(d); - - if (live.spos[s]==live.tos) { - /* Source is on top of stack */ - ds=stackpos(d); - emit_byte(0xdc); - emit_byte(0xe8+ds); /* sub source from dest*/ - } - else { - make_tos(d); - ds=stackpos(s); - - emit_byte(0xd8); - emit_byte(0xe0+ds); /* sub src from dest */ - } -} -LENDFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s)) -{ - int ds; - - usereg(s); - usereg(d); - - make_tos(d); - ds=stackpos(s); - - emit_byte(0xdd); - emit_byte(0xe0+ds); /* cmp dest with source*/ -} -LENDFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s)) -{ - int ds; - - usereg(s); - usereg(d); - - if (live.spos[s]==live.tos) { - /* Source is on top of stack */ - ds=stackpos(d); - emit_byte(0xdc); - emit_byte(0xc8+ds); /* mul dest by source*/ - } - else { - make_tos(d); - ds=stackpos(s); - - emit_byte(0xd8); - emit_byte(0xc8+ds); /* mul dest by source*/ - } -} -LENDFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s)) -{ - int ds; - - usereg(s); - usereg(d); - - if (live.spos[s]==live.tos) { - /* Source is on top of stack */ - ds=stackpos(d); - emit_byte(0xdc); - emit_byte(0xf8+ds); /* div dest by source */ - } - else { - make_tos(d); - ds=stackpos(s); - - emit_byte(0xd8); - emit_byte(0xf0+ds); /* div dest by source*/ - } -} -LENDFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s)) -{ - int ds; - - usereg(s); - usereg(d); - - make_tos2(d,s); - ds=stackpos(s); - - if (ds!=1) { - printf("Failed horribly in raw_frem_rr! ds is %d\n",ds); - abort(); - } - emit_byte(0xd9); - emit_byte(0xf8); /* take rem from dest by source */ -} -LENDFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s)) - -LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s)) -{ - int ds; - - usereg(s); - usereg(d); - - make_tos2(d,s); - ds=stackpos(s); - - if (ds!=1) { - printf("Failed horribly in raw_frem1_rr! ds is %d\n",ds); - abort(); - } - emit_byte(0xd9); - emit_byte(0xf5); /* take rem1 from dest by source */ -} -LENDFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s)) - - -LOWFUNC(NONE,NONE,1,raw_ftst_r,(FR r)) -{ - make_tos(r); - emit_byte(0xd9); /* ftst */ - emit_byte(0xe4); -} -LENDFUNC(NONE,NONE,1,raw_ftst_r,(FR r)) - -/* %eax register is clobbered if target processor doesn't support fucomi */ -#define FFLAG_NREG_CLOBBER_CONDITION !have_cmov -#define FFLAG_NREG EAX_INDEX - -static __inline__ void raw_fflags_into_flags(int r) -{ - int p; - - usereg(r); - p=stackpos(r); - - emit_byte(0xd9); - emit_byte(0xee); /* Push 0 */ - emit_byte(0xd9); - emit_byte(0xc9+p); /* swap top two around */ - if (have_cmov) { - // gb-- fucomi is for P6 cores only, not K6-2 then... - emit_byte(0xdb); - emit_byte(0xe9+p); /* fucomi them */ - } - else { - emit_byte(0xdd); - emit_byte(0xe1+p); /* fucom them */ - emit_byte(0x9b); - emit_byte(0xdf); - emit_byte(0xe0); /* fstsw ax */ - raw_sahf(0); /* sahf */ - } - emit_byte(0xdd); - emit_byte(0xd9+p); /* store value back, and get rid of 0 */ -} diff --git a/BasiliskII/src/uae_cpu/compiler/codegen_x86.h b/BasiliskII/src/uae_cpu/compiler/codegen_x86.h deleted file mode 100644 index 08538b7a..00000000 --- a/BasiliskII/src/uae_cpu/compiler/codegen_x86.h +++ /dev/null @@ -1,2565 +0,0 @@ -/******************** -*- mode: C; tab-width: 8 -*- ******************** - * - * Run-time assembler for IA-32 and AMD64 - * - ***********************************************************************/ - - -/*********************************************************************** - * - * This file is derived from CCG. - * - * Copyright 1999, 2000, 2001, 2002, 2003 Ian Piumarta - * - * Adaptations and enhancements for AMD64 support, Copyright 2003-2008 - * Gwenole Beauchesne - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - ***********************************************************************/ - -#ifndef X86_RTASM_H -#define X86_RTASM_H - -/* NOTES - * - * o Best viewed on a 1024x768 screen with fixed-6x10 font ;-) - * - * TODO - * - * o Fix FIXMEs - * o SSE instructions - * o Optimize for cases where register numbers are not integral constants - */ - -/* --- Configuration ------------------------------------------------------- */ - -/* Define to settle a "flat" register set, i.e. different regno for - each size variant. */ -#ifndef X86_FLAT_REGISTERS -#define X86_FLAT_REGISTERS 1 -#endif - -/* Define to generate x86-64 code. */ -#ifndef X86_TARGET_64BIT -#define X86_TARGET_64BIT 0 -#endif - -/* Define to optimize ALU instructions. */ -#ifndef X86_OPTIMIZE_ALU -#define X86_OPTIMIZE_ALU 1 -#endif - -/* Define to optimize rotate/shift instructions. */ -#ifndef X86_OPTIMIZE_ROTSHI -#define X86_OPTIMIZE_ROTSHI 1 -#endif - -/* Define to optimize absolute addresses for RIP relative addressing. */ -#ifndef X86_RIP_RELATIVE_ADDR -#define X86_RIP_RELATIVE_ADDR 1 -#endif - - -/* --- Macros -------------------------------------------------------------- */ - -/* Functions used to emit code. - * - * x86_emit_byte(B) - * x86_emit_word(W) - * x86_emit_long(L) - */ - -/* Get pointer to current code - * - * x86_get_target() - */ - -/* Abort assembler, fatal failure. - * - * x86_emit_failure(MSG) - */ - -#define x86_emit_failure0(MSG) (x86_emit_failure(MSG),0) - - -/* --- Register set -------------------------------------------------------- */ - -enum { - X86_RIP = -2, -#if X86_FLAT_REGISTERS - X86_NOREG = 0, - X86_Reg8L_Base = 0x10, - X86_Reg8H_Base = 0x20, - X86_Reg16_Base = 0x30, - X86_Reg32_Base = 0x40, - X86_Reg64_Base = 0x50, - X86_RegMMX_Base = 0x60, - X86_RegXMM_Base = 0x70, - X86_RegFPU_Base = 0x80 -#else - X86_NOREG = -1, - X86_Reg8L_Base = 0, - X86_Reg8H_Base = 16, - X86_Reg16_Base = 0, - X86_Reg32_Base = 0, - X86_Reg64_Base = 0, - X86_RegMMX_Base = 0, - X86_RegXMM_Base = 0, - X86_RegFPU_Base = 0 -#endif -}; - -enum { - X86_AL = X86_Reg8L_Base, - X86_CL, X86_DL, X86_BL, - X86_SPL, X86_BPL, X86_SIL, X86_DIL, - X86_R8B, X86_R9B, X86_R10B, X86_R11B, - X86_R12B, X86_R13B, X86_R14B, X86_R15B, - X86_AH = X86_Reg8H_Base + 4, - X86_CH, X86_DH, X86_BH -}; - -enum { - X86_AX = X86_Reg16_Base, - X86_CX, X86_DX, X86_BX, - X86_SP, X86_BP, X86_SI, X86_DI, - X86_R8W, X86_R9W, X86_R10W, X86_R11W, - X86_R12W, X86_R13W, X86_R14W, X86_R15W -}; - -enum { - X86_EAX = X86_Reg32_Base, - X86_ECX, X86_EDX, X86_EBX, - X86_ESP, X86_EBP, X86_ESI, X86_EDI, - X86_R8D, X86_R9D, X86_R10D, X86_R11D, - X86_R12D, X86_R13D, X86_R14D, X86_R15D -}; - -enum { - X86_RAX = X86_Reg64_Base, - X86_RCX, X86_RDX, X86_RBX, - X86_RSP, X86_RBP, X86_RSI, X86_RDI, - X86_R8, X86_R9, X86_R10, X86_R11, - X86_R12, X86_R13, X86_R14, X86_R15 -}; - -enum { - X86_MM0 = X86_RegMMX_Base, - X86_MM1, X86_MM2, X86_MM3, - X86_MM4, X86_MM5, X86_MM6, X86_MM7, -}; - -enum { - X86_XMM0 = X86_RegXMM_Base, - X86_XMM1, X86_XMM2, X86_XMM3, - X86_XMM4, X86_XMM5, X86_XMM6, X86_XMM7, - X86_XMM8, X86_XMM9, X86_XMM10, X86_XMM11, - X86_XMM12, X86_XMM13, X86_XMM14, X86_XMM15 -}; - -enum { - X86_ST0 = X86_RegFPU_Base, - X86_ST1, X86_ST2, X86_ST3, - X86_ST4, X86_ST5, X86_ST6, X86_ST7 -}; - -/* Register control and access - * - * _r0P(R) Null register? - * _rIP(R) RIP register? - * _rXP(R) Extended register? - * - * _rC(R) Class of register (only valid if X86_FLAT_REGISTERS) - * _rR(R) Full register number - * _rN(R) Short register number for encoding - * - * _r1(R) 8-bit register ID - * _r2(R) 16-bit register ID - * _r4(R) 32-bit register ID - * _r8(R) 64-bit register ID - * _rM(R) MMX register ID - * _rX(R) XMM register ID - * _rF(R) FPU register ID - * _rA(R) Address register ID used for EA calculation - */ - -#define _rST0P(R) ((int)(R) == (int)X86_ST0) -#define _r0P(R) ((int)(R) == (int)X86_NOREG) -#define _rIP(R) (X86_TARGET_64BIT ? ((int)(R) == (int)X86_RIP) : 0) - -#if X86_FLAT_REGISTERS -#define _rC(R) ((R) & 0xf0) -#define _rR(R) ((R) & 0x0f) -#define _rN(R) ((R) & 0x07) -#define _rXP(R) (((R) > 0 && _rR(R) > 7) ? 1 : 0) -#else -#define _rN(R) ((R) & 0x07) -#define _rR(R) (int(R)) -#define _rXP(R) ((_rR(R) > 7 && _rR(R) < 16) ? 1 : 0) -#endif - -#if !defined(_ASM_SAFETY) || ! X86_FLAT_REGISTERS -#define _r1(R) _rN(R) -#define _r2(R) _rN(R) -#define _r4(R) _rN(R) -#define _r8(R) _rN(R) -#define _rA(R) _rN(R) -#define _rM(R) _rN(R) -#define _rX(R) _rN(R) -#define _rF(R) _rN(R) -#else -#define _r1(R) ( ((_rC(R) & (X86_Reg8L_Base | X86_Reg8H_Base)) != 0) ? _rN(R) : x86_emit_failure0( "8-bit register required")) -#define _r2(R) ( (_rC(R) == X86_Reg16_Base) ? _rN(R) : x86_emit_failure0("16-bit register required")) -#define _r4(R) ( (_rC(R) == X86_Reg32_Base) ? _rN(R) : x86_emit_failure0("32-bit register required")) -#define _r8(R) ( (_rC(R) == X86_Reg64_Base) ? _rN(R) : x86_emit_failure0("64-bit register required")) -#define _rA(R) ( X86_TARGET_64BIT ? \ - ( (_rC(R) == X86_Reg64_Base) ? _rN(R) : x86_emit_failure0("not a valid 64-bit base/index expression")) : \ - ( (_rC(R) == X86_Reg32_Base) ? _rN(R) : x86_emit_failure0("not a valid 32-bit base/index expression")) ) -#define _rM(R) ( (_rC(R) == X86_RegMMX_Base) ? _rN(R) : x86_emit_failure0("MMX register required")) -#define _rX(R) ( (_rC(R) == X86_RegXMM_Base) ? _rN(R) : x86_emit_failure0("SSE register required")) -#define _rF(R) ( (_rC(R) == X86_RegFPU_Base) ? _rN(R) : x86_emit_failure0("FPU register required")) -#endif - -#define _rSP() (X86_TARGET_64BIT ? (int)X86_RSP : (int)X86_ESP) -#define _r1e8lP(R) (int(R) >= X86_SPL && int(R) <= X86_DIL) -#define _rbpP(R) (_rR(R) == _rR(X86_RBP)) -#define _rspP(R) (_rR(R) == _rR(X86_RSP)) -#define _rbp13P(R) (_rN(R) == _rN(X86_RBP)) -#define _rsp12P(R) (_rN(R) == _rN(X86_RSP)) - - -/* ========================================================================= */ -/* --- UTILITY ------------------------------------------------------------- */ -/* ========================================================================= */ - -typedef signed char _sc; -typedef unsigned char _uc; -typedef signed short _ss; -typedef unsigned short _us; -typedef signed int _sl; -typedef unsigned int _ul; - -#define _UC(X) ((_uc )(unsigned long)(X)) -#define _US(X) ((_us )(unsigned long)(X)) -#define _SL(X) ((_sl )(unsigned long)(X)) -#define _UL(X) ((_ul )(unsigned long)(X)) - -#define _PUC(X) ((_uc *)(X)) -#define _PUS(X) ((_us *)(X)) -#define _PSL(X) ((_sl *)(X)) -#define _PUL(X) ((_ul *)(X)) - -#define _B(B) x86_emit_byte((B)) -#define _W(W) x86_emit_word((W)) -#define _L(L) x86_emit_long((L)) -#define _Q(Q) x86_emit_quad((Q)) - -#define _MASK(N) ((unsigned)((1<<(N)))-1) -#define _siP(N,I) (!((((unsigned)(I))^(((unsigned)(I))<<1))&~_MASK(N))) -#define _uiP(N,I) (!(((unsigned)(I))&~_MASK(N))) -#define _suiP(N,I) (_siP(N,I) | _uiP(N,I)) - -#ifndef _ASM_SAFETY -#define _ck_s(W,I) (_UL(I) & _MASK(W)) -#define _ck_u(W,I) (_UL(I) & _MASK(W)) -#define _ck_su(W,I) (_UL(I) & _MASK(W)) -#define _ck_d(W,I) (_UL(I) & _MASK(W)) -#else -#define _ck_s(W,I) (_siP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0( "signed integer `"#I"' too large for "#W"-bit field")) -#define _ck_u(W,I) (_uiP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0("unsigned integer `"#I"' too large for "#W"-bit field")) -#define _ck_su(W,I) (_suiP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0( "integer `"#I"' too large for "#W"-bit field")) -#define _ck_d(W,I) (_siP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0( "displacement `"#I"' too large for "#W"-bit field")) -#endif - -#define _s0P(I) ((I)==0) -#define _s8P(I) _siP(8,I) -#define _s16P(I) _siP(16,I) -#define _u8P(I) _uiP(8,I) -#define _u16P(I) _uiP(16,I) - -#define _su8(I) _ck_su(8,I) -#define _su16(I) _ck_su(16,I) - -#define _s1(I) _ck_s( 1,I) -#define _s2(I) _ck_s( 2,I) -#define _s3(I) _ck_s( 3,I) -#define _s4(I) _ck_s( 4,I) -#define _s5(I) _ck_s( 5,I) -#define _s6(I) _ck_s( 6,I) -#define _s7(I) _ck_s( 7,I) -#define _s8(I) _ck_s( 8,I) -#define _s9(I) _ck_s( 9,I) -#define _s10(I) _ck_s(10,I) -#define _s11(I) _ck_s(11,I) -#define _s12(I) _ck_s(12,I) -#define _s13(I) _ck_s(13,I) -#define _s14(I) _ck_s(14,I) -#define _s15(I) _ck_s(15,I) -#define _s16(I) _ck_s(16,I) -#define _s17(I) _ck_s(17,I) -#define _s18(I) _ck_s(18,I) -#define _s19(I) _ck_s(19,I) -#define _s20(I) _ck_s(20,I) -#define _s21(I) _ck_s(21,I) -#define _s22(I) _ck_s(22,I) -#define _s23(I) _ck_s(23,I) -#define _s24(I) _ck_s(24,I) -#define _s25(I) _ck_s(25,I) -#define _s26(I) _ck_s(26,I) -#define _s27(I) _ck_s(27,I) -#define _s28(I) _ck_s(28,I) -#define _s29(I) _ck_s(29,I) -#define _s30(I) _ck_s(30,I) -#define _s31(I) _ck_s(31,I) -#define _u1(I) _ck_u( 1,I) -#define _u2(I) _ck_u( 2,I) -#define _u3(I) _ck_u( 3,I) -#define _u4(I) _ck_u( 4,I) -#define _u5(I) _ck_u( 5,I) -#define _u6(I) _ck_u( 6,I) -#define _u7(I) _ck_u( 7,I) -#define _u8(I) _ck_u( 8,I) -#define _u9(I) _ck_u( 9,I) -#define _u10(I) _ck_u(10,I) -#define _u11(I) _ck_u(11,I) -#define _u12(I) _ck_u(12,I) -#define _u13(I) _ck_u(13,I) -#define _u14(I) _ck_u(14,I) -#define _u15(I) _ck_u(15,I) -#define _u16(I) _ck_u(16,I) -#define _u17(I) _ck_u(17,I) -#define _u18(I) _ck_u(18,I) -#define _u19(I) _ck_u(19,I) -#define _u20(I) _ck_u(20,I) -#define _u21(I) _ck_u(21,I) -#define _u22(I) _ck_u(22,I) -#define _u23(I) _ck_u(23,I) -#define _u24(I) _ck_u(24,I) -#define _u25(I) _ck_u(25,I) -#define _u26(I) _ck_u(26,I) -#define _u27(I) _ck_u(27,I) -#define _u28(I) _ck_u(28,I) -#define _u29(I) _ck_u(29,I) -#define _u30(I) _ck_u(30,I) -#define _u31(I) _ck_u(31,I) - -/* ========================================================================= */ -/* --- ASSEMBLER ----------------------------------------------------------- */ -/* ========================================================================= */ - -#define _b00 0 -#define _b01 1 -#define _b10 2 -#define _b11 3 - -#define _b000 0 -#define _b001 1 -#define _b010 2 -#define _b011 3 -#define _b100 4 -#define _b101 5 -#define _b110 6 -#define _b111 7 - -#define _OFF4(D) (_UL(D) - _UL(x86_get_target())) -#define _CKD8(D) _ck_d(8, ((_uc) _OFF4(D)) ) - -#define _D8(D) (_B(0), ((*(_PUC(x86_get_target())-1))= _CKD8(D))) -#define _D32(D) (_L(0), ((*(_PUL(x86_get_target())-1))= _OFF4(D))) - -#ifndef _ASM_SAFETY -# define _M(M) (M) -# define _r(R) (R) -# define _m(M) (M) -# define _s(S) (S) -# define _i(I) (I) -# define _b(B) (B) -#else -# define _M(M) (((M)>3) ? x86_emit_failure0("internal error: mod = " #M) : (M)) -# define _r(R) (((R)>7) ? x86_emit_failure0("internal error: reg = " #R) : (R)) -# define _m(M) (((M)>7) ? x86_emit_failure0("internal error: r/m = " #M) : (M)) -# define _s(S) (((S)>3) ? x86_emit_failure0("internal error: memory scale = " #S) : (S)) -# define _i(I) (((I)>7) ? x86_emit_failure0("internal error: memory index = " #I) : (I)) -# define _b(B) (((B)>7) ? x86_emit_failure0("internal error: memory base = " #B) : (B)) -#endif - -#define _Mrm(Md,R,M) _B((_M(Md)<<6)|(_r(R)<<3)|_m(M)) -#define _SIB(Sc,I, B) _B((_s(Sc)<<6)|(_i(I)<<3)|_b(B)) - -#define _SCL(S) ((((S)==1) ? _b00 : \ - (((S)==2) ? _b01 : \ - (((S)==4) ? _b10 : \ - (((S)==8) ? _b11 : x86_emit_failure0("illegal scale: " #S)))))) - - -/* --- Memory subformats - urgh! ------------------------------------------- */ - -/* _r_D() is RIP addressing mode if X86_TARGET_64BIT, use _r_DSIB() instead */ -#define _r_D( R, D ) (_Mrm(_b00,_rN(R),_b101 ) ,_L((_sl)(D))) -#define _r_DSIB(R, D ) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(1),_b100 ,_b101 ),_L((_sl)(D))) -#define _r_0B( R, B ) (_Mrm(_b00,_rN(R),_rA(B)) ) -#define _r_0BIS(R, B,I,S) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)) ) -#define _r_1B( R, D,B ) (_Mrm(_b01,_rN(R),_rA(B)) ,_B((_sc)(D))) -#define _r_1BIS(R, D,B,I,S) (_Mrm(_b01,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)),_B((_sc)(D))) -#define _r_4B( R, D,B ) (_Mrm(_b10,_rN(R),_rA(B)) ,_L((_sl)(D))) -#define _r_4IS( R, D,I,S) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_b101 ),_L((_sl)(D))) -#define _r_4BIS(R, D,B,I,S) (_Mrm(_b10,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)),_L((_sl)(D))) - -#define _r_DB( R, D,B ) ((_s0P(D) && (!_rbp13P(B)) ? _r_0B (R, B ) : (_s8P(D) ? _r_1B( R,D,B ) : _r_4B( R,D,B )))) -#define _r_DBIS(R, D,B,I,S) ((_s0P(D) && (!_rbp13P(B)) ? _r_0BIS(R, B,I,S) : (_s8P(D) ? _r_1BIS(R,D,B,I,S) : _r_4BIS(R,D,B,I,S)))) - -/* Use RIP-addressing in 64-bit mode, if possible */ -#define _x86_RIP_addressing_possible(D,O) (X86_RIP_RELATIVE_ADDR && \ - ((uintptr)x86_get_target() + 4 + (O) - (D) <= 0xffffffff)) - -#define _r_X( R, D,B,I,S,O) (_r0P(I) ? (_r0P(B) ? (!X86_TARGET_64BIT ? _r_D(R,D) : \ - (_x86_RIP_addressing_possible(D, O) ? \ - _r_D(R, (D) - ((uintptr)x86_get_target() + 4 + (O))) : \ - _r_DSIB(R,D))) : \ - (_rIP(B) ? _r_D (R,D ) : \ - (_rsp12P(B) ? _r_DBIS(R,D,_rSP(),_rSP(),1) : \ - _r_DB (R,D, B )))) : \ - (_r0P(B) ? _r_4IS (R,D, I,S) : \ - (!_rspP(I) ? _r_DBIS(R,D, B, I,S) : \ - x86_emit_failure("illegal index register: %esp")))) - - -/* --- Instruction formats ------------------------------------------------- */ - -#define _m32only(X) (! X86_TARGET_64BIT ? X : x86_emit_failure("invalid instruction in 64-bit mode")) -#define _m64only(X) ( X86_TARGET_64BIT ? X : x86_emit_failure("invalid instruction in 32-bit mode")) -#define _m64(X) ( X86_TARGET_64BIT ? X : ((void)0) ) - -/* _format Opcd ModR/M dN(rB,rI,Sc) imm... */ - -#define _d16() ( _B(0x66 ) ) -#define _O( OP ) ( _B( OP ) ) -#define _Or( OP,R ) ( _B( (OP)|_r(R)) ) -#define _OO( OP ) ( _B((OP)>>8), _B(( (OP) )&0xff) ) -#define _OOr( OP,R ) ( _B((OP)>>8), _B(( (OP)|_r(R))&0xff) ) -#define _Os( OP,B ) ( _s8P(B) ? _B(((OP)|_b10)) : _B(OP) ) -#define _sW( W ) ( _s8P(W) ? _B(W):_W(W) ) -#define _sL( L ) ( _s8P(L) ? _B(L):_L(L) ) -#define _sWO( W ) ( _s8P(W) ? 1 : 2 ) -#define _sLO( L ) ( _s8P(L) ? 1 : 4 ) -#define _O_B( OP ,B ) ( _O ( OP ) ,_B(B) ) -#define _O_W( OP ,W ) ( _O ( OP ) ,_W(W) ) -#define _O_L( OP ,L ) ( _O ( OP ) ,_L(L) ) -#define _OO_L( OP ,L ) ( _OO ( OP ) ,_L(L) ) -#define _O_D8( OP ,D ) ( _O ( OP ) ,_D8(D) ) -#define _O_D32( OP ,D ) ( _O ( OP ) ,_D32(D) ) -#define _OO_D32( OP ,D ) ( _OO ( OP ) ,_D32(D) ) -#define _Os_sW( OP ,W ) ( _Os ( OP,W) ,_sW(W) ) -#define _Os_sL( OP ,L ) ( _Os ( OP,L) ,_sL(L) ) -#define _O_W_B( OP ,W,B) ( _O ( OP ) ,_W(W),_B(B)) -#define _Or_B( OP,R ,B ) ( _Or ( OP,R) ,_B(B) ) -#define _Or_W( OP,R ,W ) ( _Or ( OP,R) ,_W(W) ) -#define _Or_L( OP,R ,L ) ( _Or ( OP,R) ,_L(L) ) -#define _Or_Q( OP,R ,Q ) ( _Or ( OP,R) ,_Q(Q) ) -#define _O_Mrm( OP ,MO,R,M ) ( _O ( OP ),_Mrm(MO,R,M ) ) -#define _OO_Mrm( OP ,MO,R,M ) ( _OO ( OP ),_Mrm(MO,R,M ) ) -#define _O_Mrm_B( OP ,MO,R,M ,B ) ( _O ( OP ),_Mrm(MO,R,M ) ,_B(B) ) -#define _O_Mrm_W( OP ,MO,R,M ,W ) ( _O ( OP ),_Mrm(MO,R,M ) ,_W(W) ) -#define _O_Mrm_L( OP ,MO,R,M ,L ) ( _O ( OP ),_Mrm(MO,R,M ) ,_L(L) ) -#define _OO_Mrm_B( OP ,MO,R,M ,B ) ( _OO ( OP ),_Mrm(MO,R,M ) ,_B(B) ) -#define _Os_Mrm_sW(OP ,MO,R,M ,W ) ( _Os ( OP,W),_Mrm(MO,R,M ),_sW(W) ) -#define _Os_Mrm_sL(OP ,MO,R,M ,L ) ( _Os ( OP,L),_Mrm(MO,R,M ),_sL(L) ) -#define _O_r_X( OP ,R ,MD,MB,MI,MS ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,0) ) -#define _OO_r_X( OP ,R ,MD,MB,MI,MS ) ( _OO ( OP ),_r_X( R ,MD,MB,MI,MS,0) ) -#define _O_r_X_B( OP ,R ,MD,MB,MI,MS,B ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,1) ,_B(B) ) -#define _O_r_X_W( OP ,R ,MD,MB,MI,MS,W ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,2) ,_W(W) ) -#define _O_r_X_L( OP ,R ,MD,MB,MI,MS,L ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,4) ,_L(L) ) -#define _OO_r_X_B( OP ,R ,MD,MB,MI,MS,B ) ( _OO ( OP ),_r_X( R ,MD,MB,MI,MS,1) ,_B(B) ) -#define _Os_r_X_sW(OP ,R ,MD,MB,MI,MS,W ) ( _Os ( OP,W),_r_X( R ,MD,MB,MI,MS,_sWO(W)),_sW(W)) -#define _Os_r_X_sL(OP ,R ,MD,MB,MI,MS,L ) ( _Os ( OP,L),_r_X( R ,MD,MB,MI,MS,_sLO(L)),_sL(L)) -#define _O_X_B( OP ,MD,MB,MI,MS,B ) ( _O_r_X_B( OP ,0 ,MD,MB,MI,MS ,B) ) -#define _O_X_W( OP ,MD,MB,MI,MS,W ) ( _O_r_X_W( OP ,0 ,MD,MB,MI,MS ,W) ) -#define _O_X_L( OP ,MD,MB,MI,MS,L ) ( _O_r_X_L( OP ,0 ,MD,MB,MI,MS ,L) ) - - -/* --- REX prefixes -------------------------------------------------------- */ - -#define _VOID() ((void)0) -#define _BIT(X) ((X) ? 1 : 0) -#define _d64(W,R,X,B) (_B(0x40|(W)<<3|(R)<<2|(X)<<1|(B))) - -#define __REXwrxb(L,W,R,X,B) ((W|R|X|B) || (L) ? _d64(W,R,X,B) : _VOID()) -#define __REXwrx_(L,W,R,X,MR) (__REXwrxb(L,W,R,X,_BIT(_rIP(MR)?0:_rXP(MR)))) -#define __REXw_x_(L,W,R,X,MR) (__REXwrx_(L,W,_BIT(_rXP(R)),X,MR)) -#define __REX_reg(RR) (__REXwrxb(0,0,0,00,_BIT(_rXP(RR)))) -#define __REX_mem(MB,MI) (__REXwrxb(0,0,0,_BIT(_rXP(MI)),_BIT(_rXP(MB)))) - -// FIXME: can't mix new (SPL,BPL,SIL,DIL) with (AH,BH,CH,DH) -#define _REXBrr(RR,MR) _m64(__REXw_x_(_r1e8lP(RR)||_r1e8lP(MR),0,RR,0,MR)) -#define _REXBmr(MB,MI,RD) _m64(__REXw_x_(_r1e8lP(RD)||_r1e8lP(MB),0,RD,_BIT(_rXP(MI)),MB)) -#define _REXBrm(RS,MB,MI) _REXBmr(MB,MI,RS) - -#define _REXBLrr(RR,MR) _m64(__REXw_x_(_r1e8lP(MR),0,RR,0,MR)) -#define _REXLrr(RR,MR) _m64(__REXw_x_(0,0,RR,0,MR)) -#define _REXLmr(MB,MI,RD) _m64(__REXw_x_(0,0,RD,_BIT(_rXP(MI)),MB)) -#define _REXLrm(RS,MB,MI) _REXLmr(MB,MI,RS) -#define _REXLr(RR) _m64(__REX_reg(RR)) -#define _REXLm(MB,MI) _m64(__REX_mem(MB,MI)) - -#define _REXQrr(RR,MR) _m64only(__REXw_x_(0,1,RR,0,MR)) -#define _REXQmr(MB,MI,RD) _m64only(__REXw_x_(0,1,RD,_BIT(_rXP(MI)),MB)) -#define _REXQrm(RS,MB,MI) _REXQmr(MB,MI,RS) -#define _REXQr(RR) _m64only(__REX_reg(RR)) -#define _REXQm(MB,MI) _m64only(__REX_mem(MB,MI)) - - -/* ========================================================================= */ -/* --- Fully-qualified intrinsic instructions ------------------------------ */ -/* ========================================================================= */ - -/* OPCODE + i = immediate operand - * + r = register operand - * + m = memory operand (disp,base,index,scale) - * + sr/sm = a star preceding a register or memory - * + 0 = top of stack register (for FPU instructions) - * - * NOTE in x86-64 mode: a memory operand with only a valid - * displacement value will lead to the expect absolute mode. If - * RIP addressing is necessary, X86_RIP shall be used as the base - * register argument. - */ - -/* --- ALU instructions ---------------------------------------------------- */ - -enum { - X86_ADD = 0, - X86_OR = 1, - X86_ADC = 2, - X86_SBB = 3, - X86_AND = 4, - X86_SUB = 5, - X86_XOR = 6, - X86_CMP = 7, -}; - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define _ALUBrr(OP,RS, RD) (_REXBrr(RS, RD), _O_Mrm (((OP) << 3) ,_b11,_r1(RS),_r1(RD) )) -#define _ALUBmr(OP, MD, MB, MI, MS, RD) (_REXBmr(MB, MI, RD), _O_r_X (((OP) << 3) + 2 ,_r1(RD) ,MD,MB,MI,MS )) -#define _ALUBrm(OP, RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (((OP) << 3) ,_r1(RS) ,MD,MB,MI,MS )) -#define _ALUBir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AL) ? \ - (_REXBrr(0, RD), _O_B (((OP) << 3) + 4 ,_su8(IM))) : \ - (_REXBrr(0, RD), _O_Mrm_B (0x80 ,_b11,OP ,_r1(RD) ,_su8(IM))) ) -#define _ALUBim(OP, IM, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X_B (0x80 ,OP ,MD,MB,MI,MS ,_su8(IM))) - -#define _ALUWrr(OP, RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (((OP) << 3) + 1,_b11,_r2(RS),_r2(RD) )) -#define _ALUWmr(OP, MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _O_r_X (((OP) << 3) + 3 ,_r2(RD) ,MD,MB,MI,MS )) -#define _ALUWrm(OP, RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (((OP) << 3) + 1 ,_r2(RS) ,MD,MB,MI,MS )) -#define _ALUWir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AX) ? \ - (_d16(), _REXLrr(0, RD), _O_W (((OP) << 3) + 5 ,_su16(IM))) : \ - (_d16(), _REXLrr(0, RD), _Os_Mrm_sW (0x81 ,_b11,OP ,_r2(RD) ,_su16(IM))) ) -#define _ALUWim(OP, IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _Os_r_X_sW (0x81 ,OP ,MD,MB,MI,MS ,_su16(IM))) - -#define _ALULrr(OP, RS, RD) (_REXLrr(RS, RD), _O_Mrm (((OP) << 3) + 1,_b11,_r4(RS),_r4(RD) )) -#define _ALULmr(OP, MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _O_r_X (((OP) << 3) + 3 ,_r4(RD) ,MD,MB,MI,MS )) -#define _ALULrm(OP, RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (((OP) << 3) + 1 ,_r4(RS) ,MD,MB,MI,MS )) -#define _ALULir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_EAX) ? \ - (_REXLrr(0, RD), _O_L (((OP) << 3) + 5 ,IM )) : \ - (_REXLrr(0, RD), _Os_Mrm_sL (0x81 ,_b11,OP ,_r4(RD) ,IM )) ) -#define _ALULim(OP, IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _Os_r_X_sL (0x81 ,OP ,MD,MB,MI,MS ,IM )) - -#define _ALUQrr(OP, RS, RD) (_REXQrr(RS, RD), _O_Mrm (((OP) << 3) + 1,_b11,_r8(RS),_r8(RD) )) -#define _ALUQmr(OP, MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (((OP) << 3) + 3 ,_r8(RD) ,MD,MB,MI,MS )) -#define _ALUQrm(OP, RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (((OP) << 3) + 1 ,_r8(RS) ,MD,MB,MI,MS )) -#define _ALUQir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_RAX) ? \ - (_REXQrr(0, RD), _O_L (((OP) << 3) + 5 ,IM )) : \ - (_REXQrr(0, RD), _Os_Mrm_sL (0x81 ,_b11,OP ,_r8(RD) ,IM )) ) -#define _ALUQim(OP, IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _Os_r_X_sL (0x81 ,OP ,MD,MB,MI,MS ,IM )) - -#define ADCBrr(RS, RD) _ALUBrr(X86_ADC, RS, RD) -#define ADCBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_ADC, MD, MB, MI, MS, RD) -#define ADCBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_ADC, RS, MD, MB, MI, MS) -#define ADCBir(IM, RD) _ALUBir(X86_ADC, IM, RD) -#define ADCBim(IM, MD, MB, MI, MS) _ALUBim(X86_ADC, IM, MD, MB, MI, MS) - -#define ADCWrr(RS, RD) _ALUWrr(X86_ADC, RS, RD) -#define ADCWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_ADC, MD, MB, MI, MS, RD) -#define ADCWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_ADC, RS, MD, MB, MI, MS) -#define ADCWir(IM, RD) _ALUWir(X86_ADC, IM, RD) -#define ADCWim(IM, MD, MB, MI, MS) _ALUWim(X86_ADC, IM, MD, MB, MI, MS) - -#define ADCLrr(RS, RD) _ALULrr(X86_ADC, RS, RD) -#define ADCLmr(MD, MB, MI, MS, RD) _ALULmr(X86_ADC, MD, MB, MI, MS, RD) -#define ADCLrm(RS, MD, MB, MI, MS) _ALULrm(X86_ADC, RS, MD, MB, MI, MS) -#define ADCLir(IM, RD) _ALULir(X86_ADC, IM, RD) -#define ADCLim(IM, MD, MB, MI, MS) _ALULim(X86_ADC, IM, MD, MB, MI, MS) - -#define ADCQrr(RS, RD) _ALUQrr(X86_ADC, RS, RD) -#define ADCQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_ADC, MD, MB, MI, MS, RD) -#define ADCQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_ADC, RS, MD, MB, MI, MS) -#define ADCQir(IM, RD) _ALUQir(X86_ADC, IM, RD) -#define ADCQim(IM, MD, MB, MI, MS) _ALUQim(X86_ADC, IM, MD, MB, MI, MS) - -#define ADDBrr(RS, RD) _ALUBrr(X86_ADD, RS, RD) -#define ADDBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_ADD, MD, MB, MI, MS, RD) -#define ADDBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_ADD, RS, MD, MB, MI, MS) -#define ADDBir(IM, RD) _ALUBir(X86_ADD, IM, RD) -#define ADDBim(IM, MD, MB, MI, MS) _ALUBim(X86_ADD, IM, MD, MB, MI, MS) - -#define ADDWrr(RS, RD) _ALUWrr(X86_ADD, RS, RD) -#define ADDWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_ADD, MD, MB, MI, MS, RD) -#define ADDWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_ADD, RS, MD, MB, MI, MS) -#define ADDWir(IM, RD) _ALUWir(X86_ADD, IM, RD) -#define ADDWim(IM, MD, MB, MI, MS) _ALUWim(X86_ADD, IM, MD, MB, MI, MS) - -#define ADDLrr(RS, RD) _ALULrr(X86_ADD, RS, RD) -#define ADDLmr(MD, MB, MI, MS, RD) _ALULmr(X86_ADD, MD, MB, MI, MS, RD) -#define ADDLrm(RS, MD, MB, MI, MS) _ALULrm(X86_ADD, RS, MD, MB, MI, MS) -#define ADDLir(IM, RD) _ALULir(X86_ADD, IM, RD) -#define ADDLim(IM, MD, MB, MI, MS) _ALULim(X86_ADD, IM, MD, MB, MI, MS) - -#define ADDQrr(RS, RD) _ALUQrr(X86_ADD, RS, RD) -#define ADDQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_ADD, MD, MB, MI, MS, RD) -#define ADDQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_ADD, RS, MD, MB, MI, MS) -#define ADDQir(IM, RD) _ALUQir(X86_ADD, IM, RD) -#define ADDQim(IM, MD, MB, MI, MS) _ALUQim(X86_ADD, IM, MD, MB, MI, MS) - -#define ANDBrr(RS, RD) _ALUBrr(X86_AND, RS, RD) -#define ANDBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_AND, MD, MB, MI, MS, RD) -#define ANDBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_AND, RS, MD, MB, MI, MS) -#define ANDBir(IM, RD) _ALUBir(X86_AND, IM, RD) -#define ANDBim(IM, MD, MB, MI, MS) _ALUBim(X86_AND, IM, MD, MB, MI, MS) - -#define ANDWrr(RS, RD) _ALUWrr(X86_AND, RS, RD) -#define ANDWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_AND, MD, MB, MI, MS, RD) -#define ANDWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_AND, RS, MD, MB, MI, MS) -#define ANDWir(IM, RD) _ALUWir(X86_AND, IM, RD) -#define ANDWim(IM, MD, MB, MI, MS) _ALUWim(X86_AND, IM, MD, MB, MI, MS) - -#define ANDLrr(RS, RD) _ALULrr(X86_AND, RS, RD) -#define ANDLmr(MD, MB, MI, MS, RD) _ALULmr(X86_AND, MD, MB, MI, MS, RD) -#define ANDLrm(RS, MD, MB, MI, MS) _ALULrm(X86_AND, RS, MD, MB, MI, MS) -#define ANDLir(IM, RD) _ALULir(X86_AND, IM, RD) -#define ANDLim(IM, MD, MB, MI, MS) _ALULim(X86_AND, IM, MD, MB, MI, MS) - -#define ANDQrr(RS, RD) _ALUQrr(X86_AND, RS, RD) -#define ANDQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_AND, MD, MB, MI, MS, RD) -#define ANDQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_AND, RS, MD, MB, MI, MS) -#define ANDQir(IM, RD) _ALUQir(X86_AND, IM, RD) -#define ANDQim(IM, MD, MB, MI, MS) _ALUQim(X86_AND, IM, MD, MB, MI, MS) - -#define CMPBrr(RS, RD) _ALUBrr(X86_CMP, RS, RD) -#define CMPBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_CMP, MD, MB, MI, MS, RD) -#define CMPBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_CMP, RS, MD, MB, MI, MS) -#define CMPBir(IM, RD) _ALUBir(X86_CMP, IM, RD) -#define CMPBim(IM, MD, MB, MI, MS) _ALUBim(X86_CMP, IM, MD, MB, MI, MS) - -#define CMPWrr(RS, RD) _ALUWrr(X86_CMP, RS, RD) -#define CMPWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_CMP, MD, MB, MI, MS, RD) -#define CMPWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_CMP, RS, MD, MB, MI, MS) -#define CMPWir(IM, RD) _ALUWir(X86_CMP, IM, RD) -#define CMPWim(IM, MD, MB, MI, MS) _ALUWim(X86_CMP, IM, MD, MB, MI, MS) - -#define CMPLrr(RS, RD) _ALULrr(X86_CMP, RS, RD) -#define CMPLmr(MD, MB, MI, MS, RD) _ALULmr(X86_CMP, MD, MB, MI, MS, RD) -#define CMPLrm(RS, MD, MB, MI, MS) _ALULrm(X86_CMP, RS, MD, MB, MI, MS) -#define CMPLir(IM, RD) _ALULir(X86_CMP, IM, RD) -#define CMPLim(IM, MD, MB, MI, MS) _ALULim(X86_CMP, IM, MD, MB, MI, MS) - -#define CMPQrr(RS, RD) _ALUQrr(X86_CMP, RS, RD) -#define CMPQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_CMP, MD, MB, MI, MS, RD) -#define CMPQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_CMP, RS, MD, MB, MI, MS) -#define CMPQir(IM, RD) _ALUQir(X86_CMP, IM, RD) -#define CMPQim(IM, MD, MB, MI, MS) _ALUQim(X86_CMP, IM, MD, MB, MI, MS) - -#define ORBrr(RS, RD) _ALUBrr(X86_OR, RS, RD) -#define ORBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_OR, MD, MB, MI, MS, RD) -#define ORBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_OR, RS, MD, MB, MI, MS) -#define ORBir(IM, RD) _ALUBir(X86_OR, IM, RD) -#define ORBim(IM, MD, MB, MI, MS) _ALUBim(X86_OR, IM, MD, MB, MI, MS) - -#define ORWrr(RS, RD) _ALUWrr(X86_OR, RS, RD) -#define ORWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_OR, MD, MB, MI, MS, RD) -#define ORWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_OR, RS, MD, MB, MI, MS) -#define ORWir(IM, RD) _ALUWir(X86_OR, IM, RD) -#define ORWim(IM, MD, MB, MI, MS) _ALUWim(X86_OR, IM, MD, MB, MI, MS) - -#define ORLrr(RS, RD) _ALULrr(X86_OR, RS, RD) -#define ORLmr(MD, MB, MI, MS, RD) _ALULmr(X86_OR, MD, MB, MI, MS, RD) -#define ORLrm(RS, MD, MB, MI, MS) _ALULrm(X86_OR, RS, MD, MB, MI, MS) -#define ORLir(IM, RD) _ALULir(X86_OR, IM, RD) -#define ORLim(IM, MD, MB, MI, MS) _ALULim(X86_OR, IM, MD, MB, MI, MS) - -#define ORQrr(RS, RD) _ALUQrr(X86_OR, RS, RD) -#define ORQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_OR, MD, MB, MI, MS, RD) -#define ORQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_OR, RS, MD, MB, MI, MS) -#define ORQir(IM, RD) _ALUQir(X86_OR, IM, RD) -#define ORQim(IM, MD, MB, MI, MS) _ALUQim(X86_OR, IM, MD, MB, MI, MS) - -#define SBBBrr(RS, RD) _ALUBrr(X86_SBB, RS, RD) -#define SBBBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_SBB, MD, MB, MI, MS, RD) -#define SBBBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_SBB, RS, MD, MB, MI, MS) -#define SBBBir(IM, RD) _ALUBir(X86_SBB, IM, RD) -#define SBBBim(IM, MD, MB, MI, MS) _ALUBim(X86_SBB, IM, MD, MB, MI, MS) - -#define SBBWrr(RS, RD) _ALUWrr(X86_SBB, RS, RD) -#define SBBWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_SBB, MD, MB, MI, MS, RD) -#define SBBWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_SBB, RS, MD, MB, MI, MS) -#define SBBWir(IM, RD) _ALUWir(X86_SBB, IM, RD) -#define SBBWim(IM, MD, MB, MI, MS) _ALUWim(X86_SBB, IM, MD, MB, MI, MS) - -#define SBBLrr(RS, RD) _ALULrr(X86_SBB, RS, RD) -#define SBBLmr(MD, MB, MI, MS, RD) _ALULmr(X86_SBB, MD, MB, MI, MS, RD) -#define SBBLrm(RS, MD, MB, MI, MS) _ALULrm(X86_SBB, RS, MD, MB, MI, MS) -#define SBBLir(IM, RD) _ALULir(X86_SBB, IM, RD) -#define SBBLim(IM, MD, MB, MI, MS) _ALULim(X86_SBB, IM, MD, MB, MI, MS) - -#define SBBQrr(RS, RD) _ALUQrr(X86_SBB, RS, RD) -#define SBBQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_SBB, MD, MB, MI, MS, RD) -#define SBBQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_SBB, RS, MD, MB, MI, MS) -#define SBBQir(IM, RD) _ALUQir(X86_SBB, IM, RD) -#define SBBQim(IM, MD, MB, MI, MS) _ALUQim(X86_SBB, IM, MD, MB, MI, MS) - -#define SUBBrr(RS, RD) _ALUBrr(X86_SUB, RS, RD) -#define SUBBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_SUB, MD, MB, MI, MS, RD) -#define SUBBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_SUB, RS, MD, MB, MI, MS) -#define SUBBir(IM, RD) _ALUBir(X86_SUB, IM, RD) -#define SUBBim(IM, MD, MB, MI, MS) _ALUBim(X86_SUB, IM, MD, MB, MI, MS) - -#define SUBWrr(RS, RD) _ALUWrr(X86_SUB, RS, RD) -#define SUBWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_SUB, MD, MB, MI, MS, RD) -#define SUBWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_SUB, RS, MD, MB, MI, MS) -#define SUBWir(IM, RD) _ALUWir(X86_SUB, IM, RD) -#define SUBWim(IM, MD, MB, MI, MS) _ALUWim(X86_SUB, IM, MD, MB, MI, MS) - -#define SUBLrr(RS, RD) _ALULrr(X86_SUB, RS, RD) -#define SUBLmr(MD, MB, MI, MS, RD) _ALULmr(X86_SUB, MD, MB, MI, MS, RD) -#define SUBLrm(RS, MD, MB, MI, MS) _ALULrm(X86_SUB, RS, MD, MB, MI, MS) -#define SUBLir(IM, RD) _ALULir(X86_SUB, IM, RD) -#define SUBLim(IM, MD, MB, MI, MS) _ALULim(X86_SUB, IM, MD, MB, MI, MS) - -#define SUBQrr(RS, RD) _ALUQrr(X86_SUB, RS, RD) -#define SUBQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_SUB, MD, MB, MI, MS, RD) -#define SUBQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_SUB, RS, MD, MB, MI, MS) -#define SUBQir(IM, RD) _ALUQir(X86_SUB, IM, RD) -#define SUBQim(IM, MD, MB, MI, MS) _ALUQim(X86_SUB, IM, MD, MB, MI, MS) - -#define XORBrr(RS, RD) _ALUBrr(X86_XOR, RS, RD) -#define XORBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_XOR, MD, MB, MI, MS, RD) -#define XORBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_XOR, RS, MD, MB, MI, MS) -#define XORBir(IM, RD) _ALUBir(X86_XOR, IM, RD) -#define XORBim(IM, MD, MB, MI, MS) _ALUBim(X86_XOR, IM, MD, MB, MI, MS) - -#define XORWrr(RS, RD) _ALUWrr(X86_XOR, RS, RD) -#define XORWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_XOR, MD, MB, MI, MS, RD) -#define XORWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_XOR, RS, MD, MB, MI, MS) -#define XORWir(IM, RD) _ALUWir(X86_XOR, IM, RD) -#define XORWim(IM, MD, MB, MI, MS) _ALUWim(X86_XOR, IM, MD, MB, MI, MS) - -#define XORLrr(RS, RD) _ALULrr(X86_XOR, RS, RD) -#define XORLmr(MD, MB, MI, MS, RD) _ALULmr(X86_XOR, MD, MB, MI, MS, RD) -#define XORLrm(RS, MD, MB, MI, MS) _ALULrm(X86_XOR, RS, MD, MB, MI, MS) -#define XORLir(IM, RD) _ALULir(X86_XOR, IM, RD) -#define XORLim(IM, MD, MB, MI, MS) _ALULim(X86_XOR, IM, MD, MB, MI, MS) - -#define XORQrr(RS, RD) _ALUQrr(X86_XOR, RS, RD) -#define XORQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_XOR, MD, MB, MI, MS, RD) -#define XORQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_XOR, RS, MD, MB, MI, MS) -#define XORQir(IM, RD) _ALUQir(X86_XOR, IM, RD) -#define XORQim(IM, MD, MB, MI, MS) _ALUQim(X86_XOR, IM, MD, MB, MI, MS) - - -/* --- Shift/Rotate instructions ------------------------------------------- */ - -enum { - X86_ROL = 0, - X86_ROR = 1, - X86_RCL = 2, - X86_RCR = 3, - X86_SHL = 4, - X86_SHR = 5, - X86_SAR = 7, -}; - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define _ROTSHIBir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ - (_REXBrr(0, RD), _O_Mrm (0xd0 ,_b11,OP,_r1(RD) )) : \ - (_REXBrr(0, RD), _O_Mrm_B (0xc0 ,_b11,OP,_r1(RD) ,_u8(IM))) ) -#define _ROTSHIBim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ - (_REXBrm(0, MB, MI), _O_r_X (0xd0 ,OP ,MD,MB,MI,MS )) : \ - (_REXBrm(0, MB, MI), _O_r_X_B (0xc0 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) -#define _ROTSHIBrr(OP,RS,RD) (((RS) == X86_CL) ? \ - (_REXBrr(RS, RD), _O_Mrm (0xd2 ,_b11,OP,_r1(RD) )) : \ - x86_emit_failure("source register must be CL" ) ) -#define _ROTSHIBrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ - (_REXBrm(RS, MB, MI), _O_r_X (0xd2 ,OP ,MD,MB,MI,MS )) : \ - x86_emit_failure("source register must be CL" ) ) - -#define _ROTSHIWir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ - (_d16(), _REXLrr(0, RD), _O_Mrm (0xd1 ,_b11,OP,_r2(RD) )) : \ - (_d16(), _REXLrr(0, RD), _O_Mrm_B (0xc1 ,_b11,OP,_r2(RD) ,_u8(IM))) ) -#define _ROTSHIWim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ - (_d16(), _REXLrm(0, MB, MI), _O_r_X (0xd1 ,OP ,MD,MB,MI,MS )) : \ - (_d16(), _REXLrm(0, MB, MI), _O_r_X_B (0xc1 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) -#define _ROTSHIWrr(OP,RS,RD) (((RS) == X86_CL) ? \ - (_d16(), _REXLrr(RS, RD), _O_Mrm (0xd3 ,_b11,OP,_r2(RD) )) : \ - x86_emit_failure("source register must be CL" ) ) -#define _ROTSHIWrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ - (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0xd3 ,OP ,MD,MB,MI,MS )) : \ - x86_emit_failure("source register must be CL" ) ) - -#define _ROTSHILir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ - (_REXLrr(0, RD), _O_Mrm (0xd1 ,_b11,OP,_r4(RD) )) : \ - (_REXLrr(0, RD), _O_Mrm_B (0xc1 ,_b11,OP,_r4(RD) ,_u8(IM))) ) -#define _ROTSHILim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ - (_REXLrm(0, MB, MI), _O_r_X (0xd1 ,OP ,MD,MB,MI,MS )) : \ - (_REXLrm(0, MB, MI), _O_r_X_B (0xc1 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) -#define _ROTSHILrr(OP,RS,RD) (((RS) == X86_CL) ? \ - (_REXLrr(RS, RD), _O_Mrm (0xd3 ,_b11,OP,_r4(RD) )) : \ - x86_emit_failure("source register must be CL" ) ) -#define _ROTSHILrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ - (_REXLrm(RS, MB, MI), _O_r_X (0xd3 ,OP ,MD,MB,MI,MS )) : \ - x86_emit_failure("source register must be CL" ) ) - -#define _ROTSHIQir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ - (_REXQrr(0, RD), _O_Mrm (0xd1 ,_b11,OP,_r8(RD) )) : \ - (_REXQrr(0, RD), _O_Mrm_B (0xc1 ,_b11,OP,_r8(RD) ,_u8(IM))) ) -#define _ROTSHIQim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ - (_REXQrm(0, MB, MI), _O_r_X (0xd1 ,OP ,MD,MB,MI,MS )) : \ - (_REXQrm(0, MB, MI), _O_r_X_B (0xc1 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) -#define _ROTSHIQrr(OP,RS,RD) (((RS) == X86_CL) ? \ - (_REXQrr(RS, RD), _O_Mrm (0xd3 ,_b11,OP,_r8(RD) )) : \ - x86_emit_failure("source register must be CL" ) ) -#define _ROTSHIQrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ - (_REXQrm(RS, MB, MI), _O_r_X (0xd3 ,OP ,MD,MB,MI,MS )) : \ - x86_emit_failure("source register must be CL" ) ) - -#define ROLBir(IM, RD) _ROTSHIBir(X86_ROL, IM, RD) -#define ROLBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_ROL, IM, MD, MB, MI, MS) -#define ROLBrr(RS, RD) _ROTSHIBrr(X86_ROL, RS, RD) -#define ROLBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_ROL, RS, MD, MB, MI, MS) - -#define ROLWir(IM, RD) _ROTSHIWir(X86_ROL, IM, RD) -#define ROLWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_ROL, IM, MD, MB, MI, MS) -#define ROLWrr(RS, RD) _ROTSHIWrr(X86_ROL, RS, RD) -#define ROLWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_ROL, RS, MD, MB, MI, MS) - -#define ROLLir(IM, RD) _ROTSHILir(X86_ROL, IM, RD) -#define ROLLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_ROL, IM, MD, MB, MI, MS) -#define ROLLrr(RS, RD) _ROTSHILrr(X86_ROL, RS, RD) -#define ROLLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_ROL, RS, MD, MB, MI, MS) - -#define ROLQir(IM, RD) _ROTSHIQir(X86_ROL, IM, RD) -#define ROLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_ROL, IM, MD, MB, MI, MS) -#define ROLQrr(RS, RD) _ROTSHIQrr(X86_ROL, RS, RD) -#define ROLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_ROL, RS, MD, MB, MI, MS) - -#define RORBir(IM, RD) _ROTSHIBir(X86_ROR, IM, RD) -#define RORBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_ROR, IM, MD, MB, MI, MS) -#define RORBrr(RS, RD) _ROTSHIBrr(X86_ROR, RS, RD) -#define RORBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_ROR, RS, MD, MB, MI, MS) - -#define RORWir(IM, RD) _ROTSHIWir(X86_ROR, IM, RD) -#define RORWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_ROR, IM, MD, MB, MI, MS) -#define RORWrr(RS, RD) _ROTSHIWrr(X86_ROR, RS, RD) -#define RORWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_ROR, RS, MD, MB, MI, MS) - -#define RORLir(IM, RD) _ROTSHILir(X86_ROR, IM, RD) -#define RORLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_ROR, IM, MD, MB, MI, MS) -#define RORLrr(RS, RD) _ROTSHILrr(X86_ROR, RS, RD) -#define RORLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_ROR, RS, MD, MB, MI, MS) - -#define RORQir(IM, RD) _ROTSHIQir(X86_ROR, IM, RD) -#define RORQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_ROR, IM, MD, MB, MI, MS) -#define RORQrr(RS, RD) _ROTSHIQrr(X86_ROR, RS, RD) -#define RORQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_ROR, RS, MD, MB, MI, MS) - -#define RCLBir(IM, RD) _ROTSHIBir(X86_RCL, IM, RD) -#define RCLBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_RCL, IM, MD, MB, MI, MS) -#define RCLBrr(RS, RD) _ROTSHIBrr(X86_RCL, RS, RD) -#define RCLBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_RCL, RS, MD, MB, MI, MS) - -#define RCLWir(IM, RD) _ROTSHIWir(X86_RCL, IM, RD) -#define RCLWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_RCL, IM, MD, MB, MI, MS) -#define RCLWrr(RS, RD) _ROTSHIWrr(X86_RCL, RS, RD) -#define RCLWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_RCL, RS, MD, MB, MI, MS) - -#define RCLLir(IM, RD) _ROTSHILir(X86_RCL, IM, RD) -#define RCLLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_RCL, IM, MD, MB, MI, MS) -#define RCLLrr(RS, RD) _ROTSHILrr(X86_RCL, RS, RD) -#define RCLLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_RCL, RS, MD, MB, MI, MS) - -#define RCLQir(IM, RD) _ROTSHIQir(X86_RCL, IM, RD) -#define RCLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_RCL, IM, MD, MB, MI, MS) -#define RCLQrr(RS, RD) _ROTSHIQrr(X86_RCL, RS, RD) -#define RCLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_RCL, RS, MD, MB, MI, MS) - -#define RCRBir(IM, RD) _ROTSHIBir(X86_RCR, IM, RD) -#define RCRBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_RCR, IM, MD, MB, MI, MS) -#define RCRBrr(RS, RD) _ROTSHIBrr(X86_RCR, RS, RD) -#define RCRBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_RCR, RS, MD, MB, MI, MS) - -#define RCRWir(IM, RD) _ROTSHIWir(X86_RCR, IM, RD) -#define RCRWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_RCR, IM, MD, MB, MI, MS) -#define RCRWrr(RS, RD) _ROTSHIWrr(X86_RCR, RS, RD) -#define RCRWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_RCR, RS, MD, MB, MI, MS) - -#define RCRLir(IM, RD) _ROTSHILir(X86_RCR, IM, RD) -#define RCRLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_RCR, IM, MD, MB, MI, MS) -#define RCRLrr(RS, RD) _ROTSHILrr(X86_RCR, RS, RD) -#define RCRLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_RCR, RS, MD, MB, MI, MS) - -#define RCRQir(IM, RD) _ROTSHIQir(X86_RCR, IM, RD) -#define RCRQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_RCR, IM, MD, MB, MI, MS) -#define RCRQrr(RS, RD) _ROTSHIQrr(X86_RCR, RS, RD) -#define RCRQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_RCR, RS, MD, MB, MI, MS) - -#define SHLBir(IM, RD) _ROTSHIBir(X86_SHL, IM, RD) -#define SHLBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_SHL, IM, MD, MB, MI, MS) -#define SHLBrr(RS, RD) _ROTSHIBrr(X86_SHL, RS, RD) -#define SHLBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_SHL, RS, MD, MB, MI, MS) - -#define SHLWir(IM, RD) _ROTSHIWir(X86_SHL, IM, RD) -#define SHLWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_SHL, IM, MD, MB, MI, MS) -#define SHLWrr(RS, RD) _ROTSHIWrr(X86_SHL, RS, RD) -#define SHLWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_SHL, RS, MD, MB, MI, MS) - -#define SHLLir(IM, RD) _ROTSHILir(X86_SHL, IM, RD) -#define SHLLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_SHL, IM, MD, MB, MI, MS) -#define SHLLrr(RS, RD) _ROTSHILrr(X86_SHL, RS, RD) -#define SHLLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_SHL, RS, MD, MB, MI, MS) - -#define SHLQir(IM, RD) _ROTSHIQir(X86_SHL, IM, RD) -#define SHLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SHL, IM, MD, MB, MI, MS) -#define SHLQrr(RS, RD) _ROTSHIQrr(X86_SHL, RS, RD) -#define SHLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SHL, RS, MD, MB, MI, MS) - -#define SHRBir(IM, RD) _ROTSHIBir(X86_SHR, IM, RD) -#define SHRBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_SHR, IM, MD, MB, MI, MS) -#define SHRBrr(RS, RD) _ROTSHIBrr(X86_SHR, RS, RD) -#define SHRBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_SHR, RS, MD, MB, MI, MS) - -#define SHRWir(IM, RD) _ROTSHIWir(X86_SHR, IM, RD) -#define SHRWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_SHR, IM, MD, MB, MI, MS) -#define SHRWrr(RS, RD) _ROTSHIWrr(X86_SHR, RS, RD) -#define SHRWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_SHR, RS, MD, MB, MI, MS) - -#define SHRLir(IM, RD) _ROTSHILir(X86_SHR, IM, RD) -#define SHRLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_SHR, IM, MD, MB, MI, MS) -#define SHRLrr(RS, RD) _ROTSHILrr(X86_SHR, RS, RD) -#define SHRLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_SHR, RS, MD, MB, MI, MS) - -#define SHRQir(IM, RD) _ROTSHIQir(X86_SHR, IM, RD) -#define SHRQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SHR, IM, MD, MB, MI, MS) -#define SHRQrr(RS, RD) _ROTSHIQrr(X86_SHR, RS, RD) -#define SHRQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SHR, RS, MD, MB, MI, MS) - -#define SALBir SHLBir -#define SALBim SHLBim -#define SALBrr SHLBrr -#define SALBrm SHLBrm - -#define SALWir SHLWir -#define SALWim SHLWim -#define SALWrr SHLWrr -#define SALWrm SHLWrm - -#define SALLir SHLLir -#define SALLim SHLLim -#define SALLrr SHLLrr -#define SALLrm SHLLrm - -#define SALQir SHLQir -#define SALQim SHLQim -#define SALQrr SHLQrr -#define SALQrm SHLQrm - -#define SARBir(IM, RD) _ROTSHIBir(X86_SAR, IM, RD) -#define SARBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_SAR, IM, MD, MB, MI, MS) -#define SARBrr(RS, RD) _ROTSHIBrr(X86_SAR, RS, RD) -#define SARBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_SAR, RS, MD, MB, MI, MS) - -#define SARWir(IM, RD) _ROTSHIWir(X86_SAR, IM, RD) -#define SARWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_SAR, IM, MD, MB, MI, MS) -#define SARWrr(RS, RD) _ROTSHIWrr(X86_SAR, RS, RD) -#define SARWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_SAR, RS, MD, MB, MI, MS) - -#define SARLir(IM, RD) _ROTSHILir(X86_SAR, IM, RD) -#define SARLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_SAR, IM, MD, MB, MI, MS) -#define SARLrr(RS, RD) _ROTSHILrr(X86_SAR, RS, RD) -#define SARLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_SAR, RS, MD, MB, MI, MS) - -#define SARQir(IM, RD) _ROTSHIQir(X86_SAR, IM, RD) -#define SARQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SAR, IM, MD, MB, MI, MS) -#define SARQrr(RS, RD) _ROTSHIQrr(X86_SAR, RS, RD) -#define SARQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SAR, RS, MD, MB, MI, MS) - - -/* --- Bit test instructions ----------------------------------------------- */ - -enum { - X86_BT = 4, - X86_BTS = 5, - X86_BTR = 6, - X86_BTC = 7, -}; - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define _BTWir(OP, IM, RD) (_d16(), _REXLrr(0, RD), _OO_Mrm_B (0x0fba ,_b11,OP ,_r2(RD) ,_u8(IM))) -#define _BTWim(OP, IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _OO_r_X_B (0x0fba ,OP ,MD,MB,MI,MS ,_u8(IM))) -#define _BTWrr(OP, RS, RD) (_d16(), _REXLrr(RS, RD), _OO_Mrm (0x0f83|((OP)<<3),_b11,_r2(RS),_r2(RD) )) -#define _BTWrm(OP, RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _OO_r_X (0x0f83|((OP)<<3) ,_r2(RS) ,MD,MB,MI,MS )) - -#define _BTLir(OP, IM, RD) (_REXLrr(0, RD), _OO_Mrm_B (0x0fba ,_b11,OP ,_r4(RD) ,_u8(IM))) -#define _BTLim(OP, IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _OO_r_X_B (0x0fba ,OP ,MD,MB,MI,MS ,_u8(IM))) -#define _BTLrr(OP, RS, RD) (_REXLrr(RS, RD), _OO_Mrm (0x0f83|((OP)<<3),_b11,_r4(RS),_r4(RD) )) -#define _BTLrm(OP, RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0f83|((OP)<<3) ,_r4(RS) ,MD,MB,MI,MS )) - -#define _BTQir(OP, IM, RD) (_REXQrr(0, RD), _OO_Mrm_B (0x0fba ,_b11,OP ,_r8(RD) ,_u8(IM))) -#define _BTQim(OP, IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _OO_r_X_B (0x0fba ,OP ,MD,MB,MI,MS ,_u8(IM))) -#define _BTQrr(OP, RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0f83|((OP)<<3),_b11,_r8(RS),_r8(RD) )) -#define _BTQrm(OP, RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f83|((OP)<<3) ,_r8(RS) ,MD,MB,MI,MS )) - -#define BTWir(IM, RD) _BTWir(X86_BT, IM, RD) -#define BTWim(IM, MD, MB, MI, MS) _BTWim(X86_BT, IM, MD, MB, MI, MS) -#define BTWrr(RS, RD) _BTWrr(X86_BT, RS, RD) -#define BTWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BT, RS, MD, MB, MI, MS) - -#define BTLir(IM, RD) _BTLir(X86_BT, IM, RD) -#define BTLim(IM, MD, MB, MI, MS) _BTLim(X86_BT, IM, MD, MB, MI, MS) -#define BTLrr(RS, RD) _BTLrr(X86_BT, RS, RD) -#define BTLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BT, RS, MD, MB, MI, MS) - -#define BTQir(IM, RD) _BTQir(X86_BT, IM, RD) -#define BTQim(IM, MD, MB, MI, MS) _BTQim(X86_BT, IM, MD, MB, MI, MS) -#define BTQrr(RS, RD) _BTQrr(X86_BT, RS, RD) -#define BTQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BT, RS, MD, MB, MI, MS) - -#define BTCWir(IM, RD) _BTWir(X86_BTC, IM, RD) -#define BTCWim(IM, MD, MB, MI, MS) _BTWim(X86_BTC, IM, MD, MB, MI, MS) -#define BTCWrr(RS, RD) _BTWrr(X86_BTC, RS, RD) -#define BTCWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BTC, RS, MD, MB, MI, MS) - -#define BTCLir(IM, RD) _BTLir(X86_BTC, IM, RD) -#define BTCLim(IM, MD, MB, MI, MS) _BTLim(X86_BTC, IM, MD, MB, MI, MS) -#define BTCLrr(RS, RD) _BTLrr(X86_BTC, RS, RD) -#define BTCLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BTC, RS, MD, MB, MI, MS) - -#define BTCQir(IM, RD) _BTQir(X86_BTC, IM, RD) -#define BTCQim(IM, MD, MB, MI, MS) _BTQim(X86_BTC, IM, MD, MB, MI, MS) -#define BTCQrr(RS, RD) _BTQrr(X86_BTC, RS, RD) -#define BTCQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTC, RS, MD, MB, MI, MS) - -#define BTRWir(IM, RD) _BTWir(X86_BTR, IM, RD) -#define BTRWim(IM, MD, MB, MI, MS) _BTWim(X86_BTR, IM, MD, MB, MI, MS) -#define BTRWrr(RS, RD) _BTWrr(X86_BTR, RS, RD) -#define BTRWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BTR, RS, MD, MB, MI, MS) - -#define BTRLir(IM, RD) _BTLir(X86_BTR, IM, RD) -#define BTRLim(IM, MD, MB, MI, MS) _BTLim(X86_BTR, IM, MD, MB, MI, MS) -#define BTRLrr(RS, RD) _BTLrr(X86_BTR, RS, RD) -#define BTRLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BTR, RS, MD, MB, MI, MS) - -#define BTRQir(IM, RD) _BTQir(X86_BTR, IM, RD) -#define BTRQim(IM, MD, MB, MI, MS) _BTQim(X86_BTR, IM, MD, MB, MI, MS) -#define BTRQrr(RS, RD) _BTQrr(X86_BTR, RS, RD) -#define BTRQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTR, RS, MD, MB, MI, MS) - -#define BTSWir(IM, RD) _BTWir(X86_BTS, IM, RD) -#define BTSWim(IM, MD, MB, MI, MS) _BTWim(X86_BTS, IM, MD, MB, MI, MS) -#define BTSWrr(RS, RD) _BTWrr(X86_BTS, RS, RD) -#define BTSWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BTS, RS, MD, MB, MI, MS) - -#define BTSLir(IM, RD) _BTLir(X86_BTS, IM, RD) -#define BTSLim(IM, MD, MB, MI, MS) _BTLim(X86_BTS, IM, MD, MB, MI, MS) -#define BTSLrr(RS, RD) _BTLrr(X86_BTS, RS, RD) -#define BTSLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BTS, RS, MD, MB, MI, MS) - -#define BTSQir(IM, RD) _BTQir(X86_BTS, IM, RD) -#define BTSQim(IM, MD, MB, MI, MS) _BTQim(X86_BTS, IM, MD, MB, MI, MS) -#define BTSQrr(RS, RD) _BTQrr(X86_BTS, RS, RD) -#define BTSQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTS, RS, MD, MB, MI, MS) - - -/* --- Move instructions --------------------------------------------------- */ - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define MOVBrr(RS, RD) (_REXBrr(RS, RD), _O_Mrm (0x88 ,_b11,_r1(RS),_r1(RD) )) -#define MOVBmr(MD, MB, MI, MS, RD) (_REXBmr(MB, MI, RD), _O_r_X (0x8a ,_r1(RD) ,MD,MB,MI,MS )) -#define MOVBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (0x88 ,_r1(RS) ,MD,MB,MI,MS )) -#define MOVBir(IM, R) (_REXBrr(0, R), _Or_B (0xb0,_r1(R) ,_su8(IM))) -#define MOVBim(IM, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_X_B (0xc6 ,MD,MB,MI,MS ,_su8(IM))) - -#define MOVWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (0x89 ,_b11,_r2(RS),_r2(RD) )) -#define MOVWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _O_r_X (0x8b ,_r2(RD) ,MD,MB,MI,MS )) -#define MOVWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0x89 ,_r2(RS) ,MD,MB,MI,MS )) -#define MOVWir(IM, R) (_d16(), _REXLrr(0, R), _Or_W (0xb8,_r2(R) ,_su16(IM))) -#define MOVWim(IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_X_W (0xc7 ,MD,MB,MI,MS ,_su16(IM))) - -#define MOVLrr(RS, RD) (_REXLrr(RS, RD), _O_Mrm (0x89 ,_b11,_r4(RS),_r4(RD) )) -#define MOVLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _O_r_X (0x8b ,_r4(RD) ,MD,MB,MI,MS )) -#define MOVLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (0x89 ,_r4(RS) ,MD,MB,MI,MS )) -#define MOVLir(IM, R) (_REXLrr(0, R), _Or_L (0xb8,_r4(R) ,IM )) -#define MOVLim(IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_X_L (0xc7 ,MD,MB,MI,MS ,IM )) - -#define MOVQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x89 ,_b11,_r8(RS),_r8(RD) )) -#define MOVQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (0x8b ,_r8(RD) ,MD,MB,MI,MS )) -#define MOVQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x89 ,_r8(RS) ,MD,MB,MI,MS )) -#define MOVQir(IM, R) (_REXQrr(0, R), _Or_Q (0xb8,_r8(R) ,IM )) -#define MOVQim(IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_X_L (0xc7 ,MD,MB,MI,MS ,IM )) - - -/* --- Unary and Multiply/Divide instructions ------------------------------ */ - -enum { - X86_NOT = 2, - X86_NEG = 3, - X86_MUL = 4, - X86_IMUL = 5, - X86_DIV = 6, - X86_IDIV = 7, -}; - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define _UNARYBr(OP, RS) (_REXBrr(0, RS), _O_Mrm (0xf6 ,_b11,OP ,_r1(RS) )) -#define _UNARYBm(OP, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X (0xf6 ,OP ,MD,MB,MI,MS )) -#define _UNARYWr(OP, RS) (_d16(), _REXLrr(0, RS), _O_Mrm (0xf7 ,_b11,OP ,_r2(RS) )) -#define _UNARYWm(OP, MD, MB, MI, MS) (_d16(), _REXLmr(MB, MI, 0), _O_r_X (0xf7 ,OP ,MD,MB,MI,MS )) -#define _UNARYLr(OP, RS) (_REXLrr(0, RS), _O_Mrm (0xf7 ,_b11,OP ,_r4(RS) )) -#define _UNARYLm(OP, MD, MB, MI, MS) (_REXLmr(MB, MI, 0), _O_r_X (0xf7 ,OP ,MD,MB,MI,MS )) -#define _UNARYQr(OP, RS) (_REXQrr(0, RS), _O_Mrm (0xf7 ,_b11,OP ,_r8(RS) )) -#define _UNARYQm(OP, MD, MB, MI, MS) (_REXQmr(MB, MI, 0), _O_r_X (0xf7 ,OP ,MD,MB,MI,MS )) - -#define NOTBr(RS) _UNARYBr(X86_NOT, RS) -#define NOTBm(MD, MB, MI, MS) _UNARYBm(X86_NOT, MD, MB, MI, MS) -#define NOTWr(RS) _UNARYWr(X86_NOT, RS) -#define NOTWm(MD, MB, MI, MS) _UNARYWm(X86_NOT, MD, MB, MI, MS) -#define NOTLr(RS) _UNARYLr(X86_NOT, RS) -#define NOTLm(MD, MB, MI, MS) _UNARYLm(X86_NOT, MD, MB, MI, MS) -#define NOTQr(RS) _UNARYQr(X86_NOT, RS) -#define NOTQm(MD, MB, MI, MS) _UNARYQm(X86_NOT, MD, MB, MI, MS) - -#define NEGBr(RS) _UNARYBr(X86_NEG, RS) -#define NEGBm(MD, MB, MI, MS) _UNARYBm(X86_NEG, MD, MB, MI, MS) -#define NEGWr(RS) _UNARYWr(X86_NEG, RS) -#define NEGWm(MD, MB, MI, MS) _UNARYWm(X86_NEG, MD, MB, MI, MS) -#define NEGLr(RS) _UNARYLr(X86_NEG, RS) -#define NEGLm(MD, MB, MI, MS) _UNARYLm(X86_NEG, MD, MB, MI, MS) -#define NEGQr(RS) _UNARYQr(X86_NEG, RS) -#define NEGQm(MD, MB, MI, MS) _UNARYQm(X86_NEG, MD, MB, MI, MS) - -#define MULBr(RS) _UNARYBr(X86_MUL, RS) -#define MULBm(MD, MB, MI, MS) _UNARYBm(X86_MUL, MD, MB, MI, MS) -#define MULWr(RS) _UNARYWr(X86_MUL, RS) -#define MULWm(MD, MB, MI, MS) _UNARYWm(X86_MUL, MD, MB, MI, MS) -#define MULLr(RS) _UNARYLr(X86_MUL, RS) -#define MULLm(MD, MB, MI, MS) _UNARYLm(X86_MUL, MD, MB, MI, MS) -#define MULQr(RS) _UNARYQr(X86_MUL, RS) -#define MULQm(MD, MB, MI, MS) _UNARYQm(X86_MUL, MD, MB, MI, MS) - -#define IMULBr(RS) _UNARYBr(X86_IMUL, RS) -#define IMULBm(MD, MB, MI, MS) _UNARYBm(X86_IMUL, MD, MB, MI, MS) -#define IMULWr(RS) _UNARYWr(X86_IMUL, RS) -#define IMULWm(MD, MB, MI, MS) _UNARYWm(X86_IMUL, MD, MB, MI, MS) -#define IMULLr(RS) _UNARYLr(X86_IMUL, RS) -#define IMULLm(MD, MB, MI, MS) _UNARYLm(X86_IMUL, MD, MB, MI, MS) -#define IMULQr(RS) _UNARYQr(X86_IMUL, RS) -#define IMULQm(MD, MB, MI, MS) _UNARYQm(X86_IMUL, MD, MB, MI, MS) - -#define DIVBr(RS) _UNARYBr(X86_DIV, RS) -#define DIVBm(MD, MB, MI, MS) _UNARYBm(X86_DIV, MD, MB, MI, MS) -#define DIVWr(RS) _UNARYWr(X86_DIV, RS) -#define DIVWm(MD, MB, MI, MS) _UNARYWm(X86_DIV, MD, MB, MI, MS) -#define DIVLr(RS) _UNARYLr(X86_DIV, RS) -#define DIVLm(MD, MB, MI, MS) _UNARYLm(X86_DIV, MD, MB, MI, MS) -#define DIVQr(RS) _UNARYQr(X86_DIV, RS) -#define DIVQm(MD, MB, MI, MS) _UNARYQm(X86_DIV, MD, MB, MI, MS) - -#define IDIVBr(RS) _UNARYBr(X86_IDIV, RS) -#define IDIVBm(MD, MB, MI, MS) _UNARYBm(X86_IDIV, MD, MB, MI, MS) -#define IDIVWr(RS) _UNARYWr(X86_IDIV, RS) -#define IDIVWm(MD, MB, MI, MS) _UNARYWm(X86_IDIV, MD, MB, MI, MS) -#define IDIVLr(RS) _UNARYLr(X86_IDIV, RS) -#define IDIVLm(MD, MB, MI, MS) _UNARYLm(X86_IDIV, MD, MB, MI, MS) -#define IDIVQr(RS) _UNARYQr(X86_IDIV, RS) -#define IDIVQm(MD, MB, MI, MS) _UNARYQm(X86_IDIV, MD, MB, MI, MS) - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define IMULWrr(RS, RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0faf ,_b11,_r2(RD),_r2(RS) )) -#define IMULWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0faf ,_r2(RD) ,MD,MB,MI,MS )) - -#define IMULWirr(IM,RS,RD) (_d16(), _REXLrr(RS, RD), _Os_Mrm_sW (0x69 ,_b11,_r2(RS),_r2(RD) ,_su16(IM) )) -#define IMULWimr(IM,MD,MB,MI,MS,RD) (_d16(), _REXLmr(MB, MI, RD), _Os_r_X_sW (0x69 ,_r2(RD) ,MD,MB,MI,MS ,_su16(IM) )) - -#define IMULLir(IM, RD) (_REXLrr(0, RD), _Os_Mrm_sL (0x69 ,_b11,_r4(RD),_r4(RD) ,IM )) -#define IMULLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0faf ,_b11,_r4(RD),_r4(RS) )) -#define IMULLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0faf ,_r4(RD) ,MD,MB,MI,MS )) - -#define IMULQir(IM, RD) (_REXQrr(0, RD), _Os_Mrm_sL (0x69 ,_b11,_r8(RD),_r8(RD) ,IM )) -#define IMULQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0faf ,_b11,_r8(RD),_r8(RS) )) -#define IMULQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0faf ,_r8(RD) ,MD,MB,MI,MS )) - -#define IMULLirr(IM,RS,RD) (_REXLrr(RS, RD), _Os_Mrm_sL (0x69 ,_b11,_r4(RS),_r4(RD) ,IM )) -#define IMULLimr(IM,MD,MB,MI,MS,RD) (_REXLmr(MB, MI, RD), _Os_r_X_sL (0x69 ,_r4(RD) ,MD,MB,MI,MS ,IM )) - -#define IMULQirr(IM,RS,RD) (_REXQrr(RS, RD), _Os_Mrm_sL (0x69 ,_b11,_r8(RS),_r8(RD) ,IM )) -#define IMULQimr(IM,MD,MB,MI,MS,RD) (_REXQmr(MB, MI, RD), _Os_r_X_sL (0x69 ,_r8(RD) ,MD,MB,MI,MS ,IM )) - - -/* --- Control Flow related instructions ----------------------------------- */ - -enum { - X86_CC_O = 0x0, - X86_CC_NO = 0x1, - X86_CC_NAE = 0x2, - X86_CC_B = 0x2, - X86_CC_C = 0x2, - X86_CC_AE = 0x3, - X86_CC_NB = 0x3, - X86_CC_NC = 0x3, - X86_CC_E = 0x4, - X86_CC_Z = 0x4, - X86_CC_NE = 0x5, - X86_CC_NZ = 0x5, - X86_CC_BE = 0x6, - X86_CC_NA = 0x6, - X86_CC_A = 0x7, - X86_CC_NBE = 0x7, - X86_CC_S = 0x8, - X86_CC_NS = 0x9, - X86_CC_P = 0xa, - X86_CC_PE = 0xa, - X86_CC_NP = 0xb, - X86_CC_PO = 0xb, - X86_CC_L = 0xc, - X86_CC_NGE = 0xc, - X86_CC_GE = 0xd, - X86_CC_NL = 0xd, - X86_CC_LE = 0xe, - X86_CC_NG = 0xe, - X86_CC_G = 0xf, - X86_CC_NLE = 0xf, -}; - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -// FIXME: no prefix is availble to encode a 32-bit operand size in 64-bit mode -#define CALLm(M) _O_D32 (0xe8 ,(int)(M) ) -#define _CALLLsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b010,_r4(R) )) -#define _CALLQsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b010,_r8(R) )) -#define CALLsr(R) ( X86_TARGET_64BIT ? _CALLQsr(R) : _CALLLsr(R)) -#define CALLsm(D,B,I,S) (_REXLrm(0, B, I), _O_r_X (0xff ,_b010 ,(int)(D),B,I,S )) - -// FIXME: no prefix is availble to encode a 32-bit operand size in 64-bit mode -#define JMPSm(M) _O_D8 (0xeb ,(int)(M) ) -#define JMPm(M) _O_D32 (0xe9 ,(int)(M) ) -#define _JMPLsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b100,_r4(R) )) -#define _JMPQsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b100,_r8(R) )) -#define JMPsr(R) ( X86_TARGET_64BIT ? _JMPQsr(R) : _JMPLsr(R)) -#define JMPsm(D,B,I,S) (_REXLrm(0, B, I), _O_r_X (0xff ,_b100 ,(int)(D),B,I,S )) - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ -#define JCCSii(CC, D) _O_B (0x70|(CC) ,(_sc)(int)(D) ) -#define JCCSim(CC, D) _O_D8 (0x70|(CC) ,(int)(D) ) -#define JOSm(D) JCCSim(X86_CC_O, D) -#define JNOSm(D) JCCSim(X86_CC_NO, D) -#define JBSm(D) JCCSim(X86_CC_B, D) -#define JNAESm(D) JCCSim(X86_CC_NAE, D) -#define JNBSm(D) JCCSim(X86_CC_NB, D) -#define JAESm(D) JCCSim(X86_CC_AE, D) -#define JESm(D) JCCSim(X86_CC_E, D) -#define JZSm(D) JCCSim(X86_CC_Z, D) -#define JNESm(D) JCCSim(X86_CC_NE, D) -#define JNZSm(D) JCCSim(X86_CC_NZ, D) -#define JBESm(D) JCCSim(X86_CC_BE, D) -#define JNASm(D) JCCSim(X86_CC_NA, D) -#define JNBESm(D) JCCSim(X86_CC_NBE, D) -#define JASm(D) JCCSim(X86_CC_A, D) -#define JSSm(D) JCCSim(X86_CC_S, D) -#define JNSSm(D) JCCSim(X86_CC_NS, D) -#define JPSm(D) JCCSim(X86_CC_P, D) -#define JPESm(D) JCCSim(X86_CC_PE, D) -#define JNPSm(D) JCCSim(X86_CC_NP, D) -#define JPOSm(D) JCCSim(X86_CC_PO, D) -#define JLSm(D) JCCSim(X86_CC_L, D) -#define JNGESm(D) JCCSim(X86_CC_NGE, D) -#define JNLSm(D) JCCSim(X86_CC_NL, D) -#define JGESm(D) JCCSim(X86_CC_GE, D) -#define JLESm(D) JCCSim(X86_CC_LE, D) -#define JNGSm(D) JCCSim(X86_CC_NG, D) -#define JNLESm(D) JCCSim(X86_CC_NLE, D) -#define JGSm(D) JCCSim(X86_CC_G, D) - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ -#define JCCii(CC, D) _OO_L (0x0f80|(CC) ,(int)(D) ) -#define JCCim(CC, D) _OO_D32 (0x0f80|(CC) ,(int)(D) ) -#define JOm(D) JCCim(X86_CC_O, D) -#define JNOm(D) JCCim(X86_CC_NO, D) -#define JBm(D) JCCim(X86_CC_B, D) -#define JNAEm(D) JCCim(X86_CC_NAE, D) -#define JNBm(D) JCCim(X86_CC_NB, D) -#define JAEm(D) JCCim(X86_CC_AE, D) -#define JEm(D) JCCim(X86_CC_E, D) -#define JZm(D) JCCim(X86_CC_Z, D) -#define JNEm(D) JCCim(X86_CC_NE, D) -#define JNZm(D) JCCim(X86_CC_NZ, D) -#define JBEm(D) JCCim(X86_CC_BE, D) -#define JNAm(D) JCCim(X86_CC_NA, D) -#define JNBEm(D) JCCim(X86_CC_NBE, D) -#define JAm(D) JCCim(X86_CC_A, D) -#define JSm(D) JCCim(X86_CC_S, D) -#define JNSm(D) JCCim(X86_CC_NS, D) -#define JPm(D) JCCim(X86_CC_P, D) -#define JPEm(D) JCCim(X86_CC_PE, D) -#define JNPm(D) JCCim(X86_CC_NP, D) -#define JPOm(D) JCCim(X86_CC_PO, D) -#define JLm(D) JCCim(X86_CC_L, D) -#define JNGEm(D) JCCim(X86_CC_NGE, D) -#define JNLm(D) JCCim(X86_CC_NL, D) -#define JGEm(D) JCCim(X86_CC_GE, D) -#define JLEm(D) JCCim(X86_CC_LE, D) -#define JNGm(D) JCCim(X86_CC_NG, D) -#define JNLEm(D) JCCim(X86_CC_NLE, D) -#define JGm(D) JCCim(X86_CC_G, D) - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ -#define SETCCir(CC, RD) (_REXBrr(0, RD), _OO_Mrm (0x0f90|(CC) ,_b11,_b000,_r1(RD) )) -#define SETOr(RD) SETCCir(X86_CC_O, RD) -#define SETNOr(RD) SETCCir(X86_CC_NO, RD) -#define SETBr(RD) SETCCir(X86_CC_B, RD) -#define SETNAEr(RD) SETCCir(X86_CC_NAE, RD) -#define SETNBr(RD) SETCCir(X86_CC_NB, RD) -#define SETAEr(RD) SETCCir(X86_CC_AE, RD) -#define SETEr(RD) SETCCir(X86_CC_E, RD) -#define SETZr(RD) SETCCir(X86_CC_Z, RD) -#define SETNEr(RD) SETCCir(X86_CC_NE, RD) -#define SETNZr(RD) SETCCir(X86_CC_NZ, RD) -#define SETBEr(RD) SETCCir(X86_CC_BE, RD) -#define SETNAr(RD) SETCCir(X86_CC_NA, RD) -#define SETNBEr(RD) SETCCir(X86_CC_NBE, RD) -#define SETAr(RD) SETCCir(X86_CC_A, RD) -#define SETSr(RD) SETCCir(X86_CC_S, RD) -#define SETNSr(RD) SETCCir(X86_CC_NS, RD) -#define SETPr(RD) SETCCir(X86_CC_P, RD) -#define SETPEr(RD) SETCCir(X86_CC_PE, RD) -#define SETNPr(RD) SETCCir(X86_CC_NP, RD) -#define SETPOr(RD) SETCCir(X86_CC_PO, RD) -#define SETLr(RD) SETCCir(X86_CC_L, RD) -#define SETNGEr(RD) SETCCir(X86_CC_NGE, RD) -#define SETNLr(RD) SETCCir(X86_CC_NL, RD) -#define SETGEr(RD) SETCCir(X86_CC_GE, RD) -#define SETLEr(RD) SETCCir(X86_CC_LE, RD) -#define SETNGr(RD) SETCCir(X86_CC_NG, RD) -#define SETNLEr(RD) SETCCir(X86_CC_NLE, RD) -#define SETGr(RD) SETCCir(X86_CC_G, RD) - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ -#define SETCCim(CC,MD,MB,MI,MS) (_REXBrm(0, MB, MI), _OO_r_X (0x0f90|(CC) ,_b000 ,MD,MB,MI,MS )) -#define SETOm(D, B, I, S) SETCCim(X86_CC_O, D, B, I, S) -#define SETNOm(D, B, I, S) SETCCim(X86_CC_NO, D, B, I, S) -#define SETBm(D, B, I, S) SETCCim(X86_CC_B, D, B, I, S) -#define SETNAEm(D, B, I, S) SETCCim(X86_CC_NAE, D, B, I, S) -#define SETNBm(D, B, I, S) SETCCim(X86_CC_NB, D, B, I, S) -#define SETAEm(D, B, I, S) SETCCim(X86_CC_AE, D, B, I, S) -#define SETEm(D, B, I, S) SETCCim(X86_CC_E, D, B, I, S) -#define SETZm(D, B, I, S) SETCCim(X86_CC_Z, D, B, I, S) -#define SETNEm(D, B, I, S) SETCCim(X86_CC_NE, D, B, I, S) -#define SETNZm(D, B, I, S) SETCCim(X86_CC_NZ, D, B, I, S) -#define SETBEm(D, B, I, S) SETCCim(X86_CC_BE, D, B, I, S) -#define SETNAm(D, B, I, S) SETCCim(X86_CC_NA, D, B, I, S) -#define SETNBEm(D, B, I, S) SETCCim(X86_CC_NBE, D, B, I, S) -#define SETAm(D, B, I, S) SETCCim(X86_CC_A, D, B, I, S) -#define SETSm(D, B, I, S) SETCCim(X86_CC_S, D, B, I, S) -#define SETNSm(D, B, I, S) SETCCim(X86_CC_NS, D, B, I, S) -#define SETPm(D, B, I, S) SETCCim(X86_CC_P, D, B, I, S) -#define SETPEm(D, B, I, S) SETCCim(X86_CC_PE, D, B, I, S) -#define SETNPm(D, B, I, S) SETCCim(X86_CC_NP, D, B, I, S) -#define SETPOm(D, B, I, S) SETCCim(X86_CC_PO, D, B, I, S) -#define SETLm(D, B, I, S) SETCCim(X86_CC_L, D, B, I, S) -#define SETNGEm(D, B, I, S) SETCCim(X86_CC_NGE, D, B, I, S) -#define SETNLm(D, B, I, S) SETCCim(X86_CC_NL, D, B, I, S) -#define SETGEm(D, B, I, S) SETCCim(X86_CC_GE, D, B, I, S) -#define SETLEm(D, B, I, S) SETCCim(X86_CC_LE, D, B, I, S) -#define SETNGm(D, B, I, S) SETCCim(X86_CC_NG, D, B, I, S) -#define SETNLEm(D, B, I, S) SETCCim(X86_CC_NLE, D, B, I, S) -#define SETGm(D, B, I, S) SETCCim(X86_CC_G, D, B, I, S) - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ -#define CMOVWrr(CC,RS,RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0f40|(CC) ,_b11,_r2(RD),_r2(RS) )) -#define CMOVWmr(CC,MD,MB,MI,MS,RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0f40|(CC) ,_r2(RD) ,MD,MB,MI,MS )) -#define CMOVLrr(CC,RS,RD) (_REXLrr(RD, RS), _OO_Mrm (0x0f40|(CC) ,_b11,_r4(RD),_r4(RS) )) -#define CMOVLmr(CC,MD,MB,MI,MS,RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0f40|(CC) ,_r4(RD) ,MD,MB,MI,MS )) -#define CMOVQrr(CC,RS,RD) (_REXQrr(RD, RS), _OO_Mrm (0x0f40|(CC) ,_b11,_r8(RD),_r8(RS) )) -#define CMOVQmr(CC,MD,MB,MI,MS,RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f40|(CC) ,_r8(RD) ,MD,MB,MI,MS )) - - -/* --- Push/Pop instructions ----------------------------------------------- */ - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define POPWr(RD) _m32only((_d16(), _Or (0x58,_r2(RD) ))) -#define POPWm(MD, MB, MI, MS) _m32only((_d16(), _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS ))) - -#define POPLr(RD) _m32only( _Or (0x58,_r4(RD) )) -#define POPLm(MD, MB, MI, MS) _m32only( _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS )) - -#define POPQr(RD) _m64only((_REXQr(RD), _Or (0x58,_r8(RD) ))) -#define POPQm(MD, MB, MI, MS) _m64only((_REXQm(MB, MI), _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS ))) - -#define PUSHWr(RS) _m32only((_d16(), _Or (0x50,_r2(RS) ))) -#define PUSHWm(MD, MB, MI, MS) _m32only((_d16(), _O_r_X (0xff, ,_b110 ,MD,MB,MI,MS ))) -#define PUSHWi(IM) _m32only((_d16(), _Os_sW (0x68 ,IM ))) - -#define PUSHLr(RS) _m32only( _Or (0x50,_r4(RS) )) -#define PUSHLm(MD, MB, MI, MS) _m32only( _O_r_X (0xff ,_b110 ,MD,MB,MI,MS )) -#define PUSHLi(IM) _m32only( _Os_sL (0x68 ,IM )) - -#define PUSHQr(RS) _m64only((_REXQr(RS), _Or (0x50,_r8(RS) ))) -#define PUSHQm(MD, MB, MI, MS) _m64only((_REXQm(MB, MI), _O_r_X (0xff ,_b110 ,MD,MB,MI,MS ))) -#define PUSHQi(IM) _m64only( _Os_sL (0x68 ,IM )) - -#define POPA() (_d16(), _O (0x61 )) -#define POPAD() _O (0x61 ) - -#define PUSHA() (_d16(), _O (0x60 )) -#define PUSHAD() _O (0x60 ) - -#define POPF() _O (0x9d ) -#define PUSHF() _O (0x9c ) - - -/* --- Test instructions --------------------------------------------------- */ - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define TESTBrr(RS, RD) (_REXBrr(RS, RD), _O_Mrm (0x84 ,_b11,_r1(RS),_r1(RD) )) -#define TESTBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (0x84 ,_r1(RS) ,MD,MB,MI,MS )) -#define TESTBir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AL) ? \ - (_REXBrr(0, RD), _O_B (0xa8 ,_u8(IM))) : \ - (_REXBrr(0, RD), _O_Mrm_B (0xf6 ,_b11,_b000 ,_r1(RD) ,_u8(IM))) ) -#define TESTBim(IM, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X_B (0xf6 ,_b000 ,MD,MB,MI,MS ,_u8(IM))) - -#define TESTWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (0x85 ,_b11,_r2(RS),_r2(RD) )) -#define TESTWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0x85 ,_r2(RS) ,MD,MB,MI,MS )) -#define TESTWir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AX) ? \ - (_d16(), _REXLrr(0, RD), _O_W (0xa9 ,_u16(IM))) : \ - (_d16(), _REXLrr(0, RD), _O_Mrm_W (0xf7 ,_b11,_b000 ,_r2(RD) ,_u16(IM))) ) -#define TESTWim(IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_r_X_W (0xf7 ,_b000 ,MD,MB,MI,MS ,_u16(IM))) - -#define TESTLrr(RS, RD) (_REXLrr(RS, RD), _O_Mrm (0x85 ,_b11,_r4(RS),_r4(RD) )) -#define TESTLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (0x85 ,_r4(RS) ,MD,MB,MI,MS )) -#define TESTLir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_EAX) ? \ - (_REXLrr(0, RD), _O_L (0xa9 ,IM )) : \ - (_REXLrr(0, RD), _O_Mrm_L (0xf7 ,_b11,_b000 ,_r4(RD) ,IM )) ) -#define TESTLim(IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_r_X_L (0xf7 ,_b000 ,MD,MB,MI,MS ,IM )) - -#define TESTQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x85 ,_b11,_r8(RS),_r8(RD) )) -#define TESTQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x85 ,_r8(RS) ,MD,MB,MI,MS )) -#define TESTQir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_RAX) ? \ - (_REXQrr(0, RD), _O_L (0xa9 ,IM )) : \ - (_REXQrr(0, RD), _O_Mrm_L (0xf7 ,_b11,_b000 ,_r8(RD) ,IM )) ) -#define TESTQim(IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X_L (0xf7 ,_b000 ,MD,MB,MI,MS ,IM )) - - -/* --- Exchange instructions ----------------------------------------------- */ - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define CMPXCHGBrr(RS, RD) (_REXBrr(RS, RD), _OO_Mrm (0x0fb0 ,_b11,_r1(RS),_r1(RD) )) -#define CMPXCHGBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _OO_r_X (0x0fb0 ,_r1(RS) ,MD,MB,MI,MS )) - -#define CMPXCHGWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _OO_Mrm (0x0fb1 ,_b11,_r2(RS),_r2(RD) )) -#define CMPXCHGWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _OO_r_X (0x0fb1 ,_r2(RS) ,MD,MB,MI,MS )) - -#define CMPXCHGLrr(RS, RD) (_REXLrr(RS, RD), _OO_Mrm (0x0fb1 ,_b11,_r4(RS),_r4(RD) )) -#define CMPXCHGLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0fb1 ,_r4(RS) ,MD,MB,MI,MS )) - -#define CMPXCHGQrr(RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0fb1 ,_b11,_r8(RS),_r8(RD) )) -#define CMPXCHGQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0fb1 ,_r8(RS) ,MD,MB,MI,MS )) - -#define XADDBrr(RS, RD) (_REXBrr(RS, RD), _OO_Mrm (0x0fc0 ,_b11,_r1(RS),_r1(RD) )) -#define XADDBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _OO_r_X (0x0fc0 ,_r1(RS) ,MD,MB,MI,MS )) - -#define XADDWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _OO_Mrm (0x0fc1 ,_b11,_r2(RS),_r2(RD) )) -#define XADDWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _OO_r_X (0x0fc1 ,_r2(RS) ,MD,MB,MI,MS )) - -#define XADDLrr(RS, RD) (_REXLrr(RS, RD), _OO_Mrm (0x0fc1 ,_b11,_r4(RS),_r4(RD) )) -#define XADDLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0fc1 ,_r4(RS) ,MD,MB,MI,MS )) - -#define XADDQrr(RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0fc1 ,_b11,_r8(RS),_r8(RD) )) -#define XADDQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0fc1 ,_r8(RS) ,MD,MB,MI,MS )) - -#define XCHGBrr(RS, RD) (_REXBrr(RS, RD), _O_Mrm (0x86 ,_b11,_r1(RS),_r1(RD) )) -#define XCHGBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (0x86 ,_r1(RS) ,MD,MB,MI,MS )) - -#define XCHGWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (0x87 ,_b11,_r2(RS),_r2(RD) )) -#define XCHGWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0x87 ,_r2(RS) ,MD,MB,MI,MS )) - -#define XCHGLrr(RS, RD) (_REXLrr(RS, RD), _O_Mrm (0x87 ,_b11,_r4(RS),_r4(RD) )) -#define XCHGLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (0x87 ,_r4(RS) ,MD,MB,MI,MS )) - -#define XCHGQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x87 ,_b11,_r8(RS),_r8(RD) )) -#define XCHGQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x87 ,_r8(RS) ,MD,MB,MI,MS )) - - -/* --- Increment/Decrement instructions ------------------------------------ */ - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define DECBm(MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X (0xfe ,_b001 ,MD,MB,MI,MS )) -#define DECBr(RD) (_REXBrr(0, RD), _O_Mrm (0xfe ,_b11,_b001 ,_r1(RD) )) - -#define DECWm(MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_r_X (0xff ,_b001 ,MD,MB,MI,MS )) -#define DECWr(RD) (! X86_TARGET_64BIT ? (_d16(), _Or (0x48,_r2(RD) )) : \ - (_d16(), _REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r2(RD) ))) - -#define DECLm(MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_r_X (0xff ,_b001 ,MD,MB,MI,MS )) -#define DECLr(RD) (! X86_TARGET_64BIT ? _Or (0x48,_r4(RD) ) : \ - (_REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r4(RD) ))) - -#define DECQm(MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X (0xff ,_b001 ,MD,MB,MI,MS )) -#define DECQr(RD) (_REXQrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r8(RD) )) - -#define INCBm(MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X (0xfe ,_b000 ,MD,MB,MI,MS )) -#define INCBr(RD) (_REXBrr(0, RD), _O_Mrm (0xfe ,_b11,_b000 ,_r1(RD) )) - -#define INCWm(MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_r_X (0xff ,_b000 ,MD,MB,MI,MS )) -#define INCWr(RD) (! X86_TARGET_64BIT ? (_d16(), _Or (0x40,_r2(RD) )) : \ - (_d16(), _REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r2(RD) )) ) - -#define INCLm(MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_r_X (0xff ,_b000 ,MD,MB,MI,MS )) -#define INCLr(RD) (! X86_TARGET_64BIT ? _Or (0x40,_r4(RD) ) : \ - (_REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r4(RD) ))) - -#define INCQm(MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X (0xff ,_b000 ,MD,MB,MI,MS )) -#define INCQr(RD) (_REXQrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r8(RD) )) - - -/* --- Misc instructions --------------------------------------------------- */ - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define BSFWrr(RS, RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0fbc ,_b11,_r2(RD),_r2(RS) )) -#define BSFWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fbc ,_r2(RD) ,MD,MB,MI,MS )) -#define BSRWrr(RS, RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0fbd ,_b11,_r2(RD),_r2(RS) )) -#define BSRWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fbd ,_r2(RD) ,MD,MB,MI,MS )) - -#define BSFLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fbc ,_b11,_r4(RD),_r4(RS) )) -#define BSFLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbc ,_r4(RD) ,MD,MB,MI,MS )) -#define BSRLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fbd ,_b11,_r4(RD),_r4(RS) )) -#define BSRLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbd ,_r4(RD) ,MD,MB,MI,MS )) - -#define BSFQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbc ,_b11,_r8(RD),_r8(RS) )) -#define BSFQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbc ,_r8(RD) ,MD,MB,MI,MS )) -#define BSRQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbd ,_b11,_r8(RD),_r8(RS) )) -#define BSRQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbd ,_r8(RD) ,MD,MB,MI,MS )) - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define MOVSBWrr(RS, RD) (_d16(), _REXBLrr(RD, RS), _OO_Mrm (0x0fbe ,_b11,_r2(RD),_r1(RS) )) -#define MOVSBWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fbe ,_r2(RD) ,MD,MB,MI,MS )) -#define MOVZBWrr(RS, RD) (_d16(), _REXBLrr(RD, RS), _OO_Mrm (0x0fb6 ,_b11,_r2(RD),_r1(RS) )) -#define MOVZBWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fb6 ,_r2(RD) ,MD,MB,MI,MS )) - -#define MOVSBLrr(RS, RD) (_REXBLrr(RD, RS), _OO_Mrm (0x0fbe ,_b11,_r4(RD),_r1(RS) )) -#define MOVSBLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbe ,_r4(RD) ,MD,MB,MI,MS )) -#define MOVZBLrr(RS, RD) (_REXBLrr(RD, RS), _OO_Mrm (0x0fb6 ,_b11,_r4(RD),_r1(RS) )) -#define MOVZBLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fb6 ,_r4(RD) ,MD,MB,MI,MS )) - -#define MOVSBQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbe ,_b11,_r8(RD),_r1(RS) )) -#define MOVSBQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbe ,_r8(RD) ,MD,MB,MI,MS )) -#define MOVZBQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fb6 ,_b11,_r8(RD),_r1(RS) )) -#define MOVZBQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fb6 ,_r8(RD) ,MD,MB,MI,MS )) - -#define MOVSWLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fbf ,_b11,_r4(RD),_r2(RS) )) -#define MOVSWLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbf ,_r4(RD) ,MD,MB,MI,MS )) -#define MOVZWLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fb7 ,_b11,_r4(RD),_r2(RS) )) -#define MOVZWLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fb7 ,_r4(RD) ,MD,MB,MI,MS )) - -#define MOVSWQrr(RS, RD) _m64only((_REXQrr(RD, RS), _OO_Mrm (0x0fbf ,_b11,_r8(RD),_r2(RS) ))) -#define MOVSWQmr(MD, MB, MI, MS, RD) _m64only((_REXQmr(MB, MI, RD), _OO_r_X (0x0fbf ,_r8(RD) ,MD,MB,MI,MS ))) -#define MOVZWQrr(RS, RD) _m64only((_REXQrr(RD, RS), _OO_Mrm (0x0fb7 ,_b11,_r8(RD),_r2(RS) ))) -#define MOVZWQmr(MD, MB, MI, MS, RD) _m64only((_REXQmr(MB, MI, RD), _OO_r_X (0x0fb7 ,_r8(RD) ,MD,MB,MI,MS ))) - -#define MOVSLQrr(RS, RD) _m64only((_REXQrr(RD, RS), _O_Mrm (0x63 ,_b11,_r8(RD),_r4(RS) ))) -#define MOVSLQmr(MD, MB, MI, MS, RD) _m64only((_REXQmr(MB, MI, RD), _O_r_X (0x63 ,_r8(RD) ,MD,MB,MI,MS ))) - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define LEALmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _O_r_X (0x8d ,_r4(RD) ,MD,MB,MI,MS )) -#define LEAQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (0x8d ,_r4(RD) ,MD,MB,MI,MS )) - -#define BSWAPLr(R) (_REXLrr(0, R), _OOr (0x0fc8,_r4(R) )) -#define BSWAPQr(R) (_REXQrr(0, R), _OOr (0x0fc8,_r8(R) )) - -#define CLC() _O (0xf8 ) -#define STC() _O (0xf9 ) -#define CMC() _O (0xf5 ) - -#define CLD() _O (0xfc ) -#define STD() _O (0xfd ) - -#define CBTW() (_d16(), _O (0x98 )) -#define CWTL() _O (0x98 ) -#define CLTQ() _m64only(_REXQrr(0, 0), _O (0x98 )) - -#define CBW CBTW -#define CWDE CWTL -#define CDQE CLTQ - -#define CWTD() (_d16(), _O (0x99 )) -#define CLTD() _O (0x99 ) -#define CQTO() _m64only(_REXQrr(0, 0), _O (0x99 )) - -#define CWD CWTD -#define CDQ CLTD -#define CQO CQTO - -#define LAHF() _O (0x9f ) -#define SAHF() _O (0x9e ) - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define CPUID() _OO (0x0fa2 ) -#define RDTSC() _OO (0xff31 ) - -#define ENTERii(W, B) _O_W_B (0xc8 ,_su16(W),_su8(B)) - -#define LEAVE() _O (0xc9 ) -#define RET() _O (0xc3 ) -#define RETi(IM) _O_W (0xc2 ,_su16(IM)) - -#define NOP() _O (0x90 ) - - -/* --- Media 64-bit instructions ------------------------------------------- */ - -enum { - X86_MMX_PABSB = 0x1c, // 2P - X86_MMX_PABSW = 0x1d, // 2P - X86_MMX_PABSD = 0x1e, // 2P - X86_MMX_PACKSSWB = 0x63, - X86_MMX_PACKSSDW = 0x6b, - X86_MMX_PACKUSWB = 0x67, - X86_MMX_PADDB = 0xfc, - X86_MMX_PADDW = 0xfd, - X86_MMX_PADDD = 0xfe, - X86_MMX_PADDQ = 0xd4, - X86_MMX_PADDSB = 0xec, - X86_MMX_PADDSW = 0xed, - X86_MMX_PADDUSB = 0xdc, - X86_MMX_PADDUSW = 0xdd, - X86_MMX_PAND = 0xdb, - X86_MMX_PANDN = 0xdf, - X86_MMX_PAVGB = 0xe0, - X86_MMX_PAVGW = 0xe3, - X86_MMX_PCMPEQB = 0x74, - X86_MMX_PCMPEQW = 0x75, - X86_MMX_PCMPEQD = 0x76, - X86_MMX_PCMPGTB = 0x64, - X86_MMX_PCMPGTW = 0x65, - X86_MMX_PCMPGTD = 0x66, - X86_MMX_PEXTRW = 0xc5, // 64, /r ib - X86_MMX_PHADDW = 0x01, // 2P - X86_MMX_PHADDD = 0x02, // 2P - X86_MMX_PHADDSW = 0x03, // 2P - X86_MMX_PHSUBW = 0x05, // 2P - X86_MMX_PHSUBD = 0x06, // 2P - X86_MMX_PHSUBSW = 0x07, // 2P - X86_MMX_PINSRW = 0xc4, // 64, /r ib - X86_MMX_PMADDUBSW = 0x04, // 2P - X86_MMX_PMADDWD = 0xf5, - X86_MMX_PMAXSW = 0xee, - X86_MMX_PMAXUB = 0xde, - X86_MMX_PMINSW = 0xea, - X86_MMX_PMINUB = 0xda, - X86_MMX_PMOVMSKB = 0xd7, // 64 - X86_MMX_PMULHRSW = 0x0b, // 2P - X86_MMX_PMULHUW = 0xe4, - X86_MMX_PMULHW = 0xe5, - X86_MMX_PMULLW = 0xd5, - X86_MMX_PMULUDQ = 0xf4, - X86_MMX_POR = 0xeb, - X86_MMX_PSADBW = 0xf6, - X86_MMX_PSHUFB = 0x00, // 2P - X86_MMX_PSHUFW = 0x70, // /r ib - X86_MMX_PSIGNB = 0x08, // 2P - X86_MMX_PSIGNW = 0x09, // 2P - X86_MMX_PSIGND = 0x0a, // 2P - X86_MMX_PSLLW = 0xf1, - X86_MMX_PSLLWi = 0x71, // /6 ib - X86_MMX_PSLLD = 0xf2, - X86_MMX_PSLLDi = 0x72, // /6 ib - X86_MMX_PSLLQ = 0xf3, - X86_MMX_PSLLQi = 0x73, // /6 ib - X86_MMX_PSRAW = 0xe1, - X86_MMX_PSRAWi = 0x71, // /4 ib - X86_MMX_PSRAD = 0xe2, - X86_MMX_PSRADi = 0x72, // /4 ib - X86_MMX_PSRLW = 0xd1, - X86_MMX_PSRLWi = 0x71, // /2 ib - X86_MMX_PSRLD = 0xd2, - X86_MMX_PSRLDi = 0x72, // /2 ib - X86_MMX_PSRLQ = 0xd3, - X86_MMX_PSRLQi = 0x73, // /2 ib - X86_MMX_PSUBB = 0xf8, - X86_MMX_PSUBW = 0xf9, - X86_MMX_PSUBD = 0xfa, - X86_MMX_PSUBQ = 0xfb, - X86_MMX_PSUBSB = 0xe8, - X86_MMX_PSUBSW = 0xe9, - X86_MMX_PSUBUSB = 0xd8, - X86_MMX_PSUBUSW = 0xd9, - X86_MMX_PUNPCKHBW = 0x68, - X86_MMX_PUNPCKHWD = 0x69, - X86_MMX_PUNPCKHDQ = 0x6a, - X86_MMX_PUNPCKLBW = 0x60, - X86_MMX_PUNPCKLWD = 0x61, - X86_MMX_PUNPCKLDQ = 0x62, - X86_MMX_PXOR = 0xef, -}; - -#define __MMXLrr(OP,RS,RSA,RD,RDA) (_REXLrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) )) -#define __MMXLmr(OP,MD,MB,MI,MS,RD,RDA) (_REXLmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS )) -#define __MMXLrm(OP,RS,RSA,MD,MB,MI,MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS )) -#define __MMXLirr(OP,IM,RS,RSA,RD,RDA) (_REXLrr(RD, RS), _OO_Mrm_B (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) ,_u8(IM))) -#define __MMXLimr(OP,IM,MD,MB,MI,MS,RD,RDA) (_REXLmr(MB, MI, RS), _OO_r_X_B (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS ,_u8(IM))) -#define __MMXQrr(OP,RS,RSA,RD,RDA) (_REXQrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) )) -#define __MMXQmr(OP,MD,MB,MI,MS,RD,RDA) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS )) -#define __MMXQrm(OP,RS,RSA,MD,MB,MI,MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS )) -#define __MMXQirr(OP,IM,RS,RSA,RD,RDA) (_REXQrr(RD, RS), _OO_Mrm_B (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) ,_u8(IM))) -#define __MMXQimr(OP,IM,MD,MB,MI,MS,RD,RDA) (_REXQmr(MB, MI, RS), _OO_r_X_B (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS ,_u8(IM))) -#define __MMX1Lrr(PX,OP,RS,RSA,RD,RDA) (_REXLrr(RD, RS), _B(0x0f),_OO_Mrm(((PX)<<8)|(OP) ,_b11,RDA(RD),RSA(RS) )) -#define __MMX1Lmr(PX,OP,MD,MB,MI,MS,RD,RDA) (_REXLmr(MB, MI, RD), _B(0x0f),_OO_r_X(((PX)<<8)|(OP) ,RDA(RD) ,MD,MB,MI,MS )) -#define __MMX1Lrm(PX,OP,RS,RSA,MD,MB,MI,MS) (_REXLrm(RS, MB, MI), _B(0x0f),_OO_r_X(((PX)<<8)|(OP) ,RSA(RS) ,MD,MB,MI,MS )) - -#define _MMXLrr(OP,RS,RD) __MMXLrr(OP,RS,_rM,RD,_rM) -#define _MMXLmr(OP,MD,MB,MI,MS,RD) __MMXLmr(OP,MD,MB,MI,MS,RD,_rM) -#define _MMXLrm(OP,RS,MD,MB,MI,MS) __MMXLrm(OP,RS,_rM,MD,MB,MI,MS) -#define _MMXQrr(OP,RS,RD) __MMXQrr(OP,RS,_rM,RD,_rM) -#define _MMXQmr(OP,MD,MB,MI,MS,RD) __MMXQmr(OP,MD,MB,MI,MS,RD,_rM) -#define _MMXQrm(OP,RS,MD,MB,MI,MS) __MMXQrm(OP,RS,_rM,MD,MB,MI,MS) -#define _2P_MMXLrr(OP,RS,RD) __MMX1Lrr(0x38, OP,RS,_rM,RD,_rM) -#define _2P_MMXLmr(OP,MD,MB,MI,MS,RD) __MMX1Lmr(0x38, OP,MD,MB,MI,MS,RD,_rM) -#define _2P_MMXLrm(OP,RS,MD,MB,MI,MS) __MMX1Lrm(0x38, OP,RS,_rM,MD,MB,MI,MS) - -#define MMX_MOVDMDrr(RS, RD) __MMXLrr(0x6e, RS,_r4, RD,_rM) -#define MMX_MOVQMDrr(RS, RD) __MMXQrr(0x6e, RS,_r8, RD,_rM) -#define MMX_MOVDMSrr(RS, RD) __MMXLrr(0x7e, RD,_r4, RS,_rM) -#define MMX_MOVQMSrr(RS, RD) __MMXQrr(0x7e, RD,_r8, RS,_rM) - -#define MMX_MOVDmr(MD, MB, MI, MS, RD) _MMXLmr(0x6e, MD, MB, MI, MS, RD) -#define MMX_MOVDrm(RS, MD, MB, MI, MS) _MMXLrm(0x7e, RS, MD, MB, MI, MS) -#define MMX_MOVQrr(RS, RD) _MMXLrr(0x6f, RS, RD) -#define MMX_MOVQmr(MD, MB, MI, MS, RD) _MMXLmr(0x6f, MD, MB, MI, MS, RD) -#define MMX_MOVQrm(RS, MD, MB, MI, MS) _MMXLrm(0x7f, RS, MD, MB, MI, MS) - -// Original MMX instructions -#define MMX_PACKSSWBrr(RS, RD) _MMXLrr(X86_MMX_PACKSSWB,RS,RD) -#define MMX_PACKSSWBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PACKSSWB, MD, MB, MI, MS, RD) -#define MMX_PACKSSDWrr(RS, RD) _MMXLrr(X86_MMX_PACKSSDW,RS,RD) -#define MMX_PACKSSDWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PACKSSDW, MD, MB, MI, MS, RD) -#define MMX_PACKUSWBrr(RS, RD) _MMXLrr(X86_MMX_PACKUSWB,RS,RD) -#define MMX_PACKUSWBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PACKUSWB, MD, MB, MI, MS, RD) -#define MMX_PADDBrr(RS, RD) _MMXLrr(X86_MMX_PADDB,RS,RD) -#define MMX_PADDBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDB, MD, MB, MI, MS, RD) -#define MMX_PADDWrr(RS, RD) _MMXLrr(X86_MMX_PADDW,RS,RD) -#define MMX_PADDWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDW, MD, MB, MI, MS, RD) -#define MMX_PADDDrr(RS, RD) _MMXLrr(X86_MMX_PADDD,RS,RD) -#define MMX_PADDDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDD, MD, MB, MI, MS, RD) -#define MMX_PADDQrr(RS, RD) _MMXLrr(X86_MMX_PADDQ,RS,RD) -#define MMX_PADDQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDQ, MD, MB, MI, MS, RD) -#define MMX_PADDSBrr(RS, RD) _MMXLrr(X86_MMX_PADDSB,RS,RD) -#define MMX_PADDSBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDSB, MD, MB, MI, MS, RD) -#define MMX_PADDSWrr(RS, RD) _MMXLrr(X86_MMX_PADDSW,RS,RD) -#define MMX_PADDSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDSW, MD, MB, MI, MS, RD) -#define MMX_PADDUSBrr(RS, RD) _MMXLrr(X86_MMX_PADDUSB,RS,RD) -#define MMX_PADDUSBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDUSB, MD, MB, MI, MS, RD) -#define MMX_PADDUSWrr(RS, RD) _MMXLrr(X86_MMX_PADDUSW,RS,RD) -#define MMX_PADDUSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDUSW, MD, MB, MI, MS, RD) -#define MMX_PANDrr(RS, RD) _MMXLrr(X86_MMX_PAND,RS,RD) -#define MMX_PANDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PAND, MD, MB, MI, MS, RD) -#define MMX_PANDNrr(RS, RD) _MMXLrr(X86_MMX_PANDN,RS,RD) -#define MMX_PANDNmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PANDN, MD, MB, MI, MS, RD) -#define MMX_PAVGBrr(RS, RD) _MMXLrr(X86_MMX_PAVGB,RS,RD) -#define MMX_PAVGBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PAVGB, MD, MB, MI, MS, RD) -#define MMX_PAVGWrr(RS, RD) _MMXLrr(X86_MMX_PAVGW,RS,RD) -#define MMX_PAVGWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PAVGW, MD, MB, MI, MS, RD) -#define MMX_PCMPEQBrr(RS, RD) _MMXLrr(X86_MMX_PCMPEQB,RS,RD) -#define MMX_PCMPEQBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPEQB, MD, MB, MI, MS, RD) -#define MMX_PCMPEQWrr(RS, RD) _MMXLrr(X86_MMX_PCMPEQW,RS,RD) -#define MMX_PCMPEQWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPEQW, MD, MB, MI, MS, RD) -#define MMX_PCMPEQDrr(RS, RD) _MMXLrr(X86_MMX_PCMPEQD,RS,RD) -#define MMX_PCMPEQDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPEQD, MD, MB, MI, MS, RD) -#define MMX_PCMPGTBrr(RS, RD) _MMXLrr(X86_MMX_PCMPGTB,RS,RD) -#define MMX_PCMPGTBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPGTB, MD, MB, MI, MS, RD) -#define MMX_PCMPGTWrr(RS, RD) _MMXLrr(X86_MMX_PCMPGTW,RS,RD) -#define MMX_PCMPGTWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPGTW, MD, MB, MI, MS, RD) -#define MMX_PCMPGTDrr(RS, RD) _MMXLrr(X86_MMX_PCMPGTD,RS,RD) -#define MMX_PCMPGTDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPGTD, MD, MB, MI, MS, RD) -#define MMX_PMADDWDrr(RS, RD) _MMXLrr(X86_MMX_PMADDWD,RS,RD) -#define MMX_PMADDWDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMADDWD, MD, MB, MI, MS, RD) -#define MMX_PMAXSWrr(RS, RD) _MMXLrr(X86_MMX_PMAXSW,RS,RD) -#define MMX_PMAXSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMAXSW, MD, MB, MI, MS, RD) -#define MMX_PMAXUBrr(RS, RD) _MMXLrr(X86_MMX_PMAXUB,RS,RD) -#define MMX_PMAXUBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMAXUB, MD, MB, MI, MS, RD) -#define MMX_PMINSWrr(RS, RD) _MMXLrr(X86_MMX_PMINSW,RS,RD) -#define MMX_PMINSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMINSW, MD, MB, MI, MS, RD) -#define MMX_PMINUBrr(RS, RD) _MMXLrr(X86_MMX_PMINUB,RS,RD) -#define MMX_PMINUBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMINUB, MD, MB, MI, MS, RD) -#define MMX_PMULHUWrr(RS, RD) _MMXLrr(X86_MMX_PMULHUW,RS,RD) -#define MMX_PMULHUWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMULHUW, MD, MB, MI, MS, RD) -#define MMX_PMULHWrr(RS, RD) _MMXLrr(X86_MMX_PMULHW,RS,RD) -#define MMX_PMULHWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMULHW, MD, MB, MI, MS, RD) -#define MMX_PMULLWrr(RS, RD) _MMXLrr(X86_MMX_PMULLW,RS,RD) -#define MMX_PMULLWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMULLW, MD, MB, MI, MS, RD) -#define MMX_PMULUDQrr(RS, RD) _MMXLrr(X86_MMX_PMULUDQ,RS,RD) -#define MMX_PMULUDQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMULUDQ, MD, MB, MI, MS, RD) -#define MMX_PORrr(RS, RD) _MMXLrr(X86_MMX_POR,RS,RD) -#define MMX_PORmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_POR, MD, MB, MI, MS, RD) -#define MMX_PSADBWrr(RS, RD) _MMXLrr(X86_MMX_PSADBW,RS,RD) -#define MMX_PSADBWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSADBW, MD, MB, MI, MS, RD) -#define MMX_PSLLWir(IM, RD) __MMXLirr(X86_MMX_PSLLWi, IM, RD,_rM, _b110,_rN) -#define MMX_PSLLWrr(RS, RD) _MMXLrr(X86_MMX_PSLLW,RS,RD) -#define MMX_PSLLWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSLLW, MD, MB, MI, MS, RD) -#define MMX_PSLLDir(IM, RD) __MMXLirr(X86_MMX_PSLLDi, IM, RD,_rM, _b110,_rN) -#define MMX_PSLLDrr(RS, RD) _MMXLrr(X86_MMX_PSLLD,RS,RD) -#define MMX_PSLLDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSLLD, MD, MB, MI, MS, RD) -#define MMX_PSLLQir(IM, RD) __MMXLirr(X86_MMX_PSLLQi, IM, RD,_rM, _b110,_rN) -#define MMX_PSLLQrr(RS, RD) _MMXLrr(X86_MMX_PSLLQ,RS,RD) -#define MMX_PSLLQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSLLQ, MD, MB, MI, MS, RD) -#define MMX_PSRAWir(IM, RD) __MMXLirr(X86_MMX_PSRAWi, IM, RD,_rM, _b100,_rN) -#define MMX_PSRAWrr(RS, RD) _MMXLrr(X86_MMX_PSRAW,RS,RD) -#define MMX_PSRAWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSRAW, MD, MB, MI, MS, RD) -#define MMX_PSRADir(IM, RD) __MMXLirr(X86_MMX_PSRADi, IM, RD,_rM, _b100,_rN) -#define MMX_PSRADrr(RS, RD) _MMXLrr(X86_MMX_PSRAD,RS,RD) -#define MMX_PSRADmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSRAD, MD, MB, MI, MS, RD) -#define MMX_PSRLWir(IM, RD) __MMXLirr(X86_MMX_PSRLWi, IM, RD,_rM, _b010,_rN) -#define MMX_PSRLWrr(RS, RD) _MMXLrr(X86_MMX_PSRLW,RS,RD) -#define MMX_PSRLWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSRLW, MD, MB, MI, MS, RD) -#define MMX_PSRLDir(IM, RD) __MMXLirr(X86_MMX_PSRLDi, IM, RD,_rM, _b010,_rN) -#define MMX_PSRLDrr(RS, RD) _MMXLrr(X86_MMX_PSRLD,RS,RD) -#define MMX_PSRLDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSRLD, MD, MB, MI, MS, RD) -#define MMX_PSRLQir(IM, RD) __MMXLirr(X86_MMX_PSRLQi, IM, RD,_rM, _b010,_rN) -#define MMX_PSRLQrr(RS, RD) _MMXLrr(X86_MMX_PSRLQ,RS,RD) -#define MMX_PSRLQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSRLQ, MD, MB, MI, MS, RD) -#define MMX_PSUBBrr(RS, RD) _MMXLrr(X86_MMX_PSUBB,RS,RD) -#define MMX_PSUBBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBB, MD, MB, MI, MS, RD) -#define MMX_PSUBWrr(RS, RD) _MMXLrr(X86_MMX_PSUBW,RS,RD) -#define MMX_PSUBWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBW, MD, MB, MI, MS, RD) -#define MMX_PSUBDrr(RS, RD) _MMXLrr(X86_MMX_PSUBD,RS,RD) -#define MMX_PSUBDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBD, MD, MB, MI, MS, RD) -#define MMX_PSUBQrr(RS, RD) _MMXLrr(X86_MMX_PSUBQ,RS,RD) -#define MMX_PSUBQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBQ, MD, MB, MI, MS, RD) -#define MMX_PSUBSBrr(RS, RD) _MMXLrr(X86_MMX_PSUBSB,RS,RD) -#define MMX_PSUBSBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBSB, MD, MB, MI, MS, RD) -#define MMX_PSUBSWrr(RS, RD) _MMXLrr(X86_MMX_PSUBSW,RS,RD) -#define MMX_PSUBSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBSW, MD, MB, MI, MS, RD) -#define MMX_PSUBUSBrr(RS, RD) _MMXLrr(X86_MMX_PSUBUSB,RS,RD) -#define MMX_PSUBUSBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBUSB, MD, MB, MI, MS, RD) -#define MMX_PSUBUSWrr(RS, RD) _MMXLrr(X86_MMX_PSUBUSW,RS,RD) -#define MMX_PSUBUSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBUSW, MD, MB, MI, MS, RD) -#define MMX_PUNPCKHBWrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKHBW,RS,RD) -#define MMX_PUNPCKHBWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKHBW, MD, MB, MI, MS, RD) -#define MMX_PUNPCKHWDrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKHWD,RS,RD) -#define MMX_PUNPCKHWDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKHWD, MD, MB, MI, MS, RD) -#define MMX_PUNPCKHDQrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKHDQ,RS,RD) -#define MMX_PUNPCKHDQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKHDQ, MD, MB, MI, MS, RD) -#define MMX_PUNPCKLBWrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKLBW,RS,RD) -#define MMX_PUNPCKLBWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKLBW, MD, MB, MI, MS, RD) -#define MMX_PUNPCKLWDrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKLWD,RS,RD) -#define MMX_PUNPCKLWDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKLWD, MD, MB, MI, MS, RD) -#define MMX_PUNPCKLDQrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKLDQ,RS,RD) -#define MMX_PUNPCKLDQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKLDQ, MD, MB, MI, MS, RD) -#define MMX_PXORrr(RS, RD) _MMXLrr(X86_MMX_PXOR,RS,RD) -#define MMX_PXORmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PXOR, MD, MB, MI, MS, RD) - -#define MMX_PSHUFWirr(IM, RS, RD) __MMXLirr(X86_MMX_PSHUFW, IM, RS,_rM, RD,_rM) -#define MMX_PSHUFWimr(IM, MD, MB, MI, MS, RD) __MMXLimr(X86_MMX_PSHUFW, IM, MD, MB, MI, MS, RD,_rM) -#define MMX_PEXTRWLirr(IM, RS, RD) __MMXLirr(X86_MMX_PEXTRW, IM, RS,_rM, RD,_r4) -#define MMX_PEXTRWQirr(IM, RS, RD) __MMXQirr(X86_MMX_PEXTRW, IM, RS,_rM, RD,_r8) -#define MMX_PINSRWLirr(IM, RS, RD) __MMXLirr(X86_MMX_PINSRW, IM, RS,_r4, RD,_rM) -#define MMX_PINSRWLimr(IM, MD, MB, MI, MS, RD) __MMXLimr(X86_MMX_PINSRW, IM, MD, MB, MI, MS, RD,_r4) -#define MMX_PINSRWQirr(IM, RS, RD) __MMXQirr(X86_MMX_PINSRW, IM, RS,_r4, RD,_rM) -#define MMX_PINSRWQimr(IM, MD, MB, MI, MS, RD) __MMXQimr(X86_MMX_PINSRW, IM, MD, MB, MI, MS, RD,_r8) - -// Additionnal MMX instructions, brought by SSSE3 ISA -#define MMX_PABSBrr(RS, RD) _2P_MMXLrr(X86_MMX_PABSB,RS,RD) -#define MMX_PABSBmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PABSB, MD, MB, MI, MS, RD) -#define MMX_PABSWrr(RS, RD) _2P_MMXLrr(X86_MMX_PABSW,RS,RD) -#define MMX_PABSWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PABSW, MD, MB, MI, MS, RD) -#define MMX_PABSDrr(RS, RD) _2P_MMXLrr(X86_MMX_PABSD,RS,RD) -#define MMX_PABSDmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PABSD, MD, MB, MI, MS, RD) -#define MMX_PHADDWrr(RS, RD) _2P_MMXLrr(X86_MMX_PHADDW,RS,RD) -#define MMX_PHADDWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHADDW, MD, MB, MI, MS, RD) -#define MMX_PHADDDrr(RS, RD) _2P_MMXLrr(X86_MMX_PHADDD,RS,RD) -#define MMX_PHADDDmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHADDD, MD, MB, MI, MS, RD) -#define MMX_PHADDSWrr(RS, RD) _2P_MMXLrr(X86_MMX_PHADDSW,RS,RD) -#define MMX_PHADDSWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHADDSW, MD, MB, MI, MS, RD) -#define MMX_PHSUBWrr(RS, RD) _2P_MMXLrr(X86_MMX_PHSUBW,RS,RD) -#define MMX_PHSUBWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHSUBW, MD, MB, MI, MS, RD) -#define MMX_PHSUBDrr(RS, RD) _2P_MMXLrr(X86_MMX_PHSUBD,RS,RD) -#define MMX_PHSUBDmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHSUBD, MD, MB, MI, MS, RD) -#define MMX_PHSUBSWrr(RS, RD) _2P_MMXLrr(X86_MMX_PHSUBSW,RS,RD) -#define MMX_PHSUBSWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHSUBSW, MD, MB, MI, MS, RD) -#define MMX_PMADDUBSWrr(RS, RD) _2P_MMXLrr(X86_MMX_PMADDUBSW,RS,RD) -#define MMX_PMADDUBSWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PMADDUBSW, MD, MB, MI, MS, RD) -#define MMX_PMULHRSWrr(RS, RD) _2P_MMXLrr(X86_MMX_PMULHRSW,RS,RD) -#define MMX_PMULHRSWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PMULHRSW, MD, MB, MI, MS, RD) -#define MMX_PSHUFBrr(RS, RD) _2P_MMXLrr(X86_MMX_PSHUFB,RS,RD) -#define MMX_PSHUFBmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PSHUFB, MD, MB, MI, MS, RD) -#define MMX_PSIGNBrr(RS, RD) _2P_MMXLrr(X86_MMX_PSIGNB,RS,RD) -#define MMX_PSIGNBmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PSIGNB, MD, MB, MI, MS, RD) -#define MMX_PSIGNWrr(RS, RD) _2P_MMXLrr(X86_MMX_PSIGNW,RS,RD) -#define MMX_PSIGNWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PSIGNW, MD, MB, MI, MS, RD) -#define MMX_PSIGNDrr(RS, RD) _2P_MMXLrr(X86_MMX_PSIGND,RS,RD) -#define MMX_PSIGNDmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PSIGND, MD, MB, MI, MS, RD) - -#define EMMS() _OO (0x0f77 ) - - -/* --- Media 128-bit instructions ------------------------------------------ */ - -enum { - X86_SSE_CC_EQ = 0, - X86_SSE_CC_LT = 1, - X86_SSE_CC_GT = 1, - X86_SSE_CC_LE = 2, - X86_SSE_CC_GE = 2, - X86_SSE_CC_U = 3, - X86_SSE_CC_NEQ = 4, - X86_SSE_CC_NLT = 5, - X86_SSE_CC_NGT = 5, - X86_SSE_CC_NLE = 6, - X86_SSE_CC_NGE = 6, - X86_SSE_CC_O = 7 -}; - -enum { - X86_SSE_UCOMI = 0x2e, - X86_SSE_COMI = 0x2f, - X86_SSE_CMP = 0xc2, - X86_SSE_SQRT = 0x51, - X86_SSE_RSQRT = 0x52, - X86_SSE_RCP = 0x53, - X86_SSE_AND = 0x54, - X86_SSE_ANDN = 0x55, - X86_SSE_OR = 0x56, - X86_SSE_XOR = 0x57, - X86_SSE_ADD = 0x58, - X86_SSE_MUL = 0x59, - X86_SSE_SUB = 0x5c, - X86_SSE_MIN = 0x5d, - X86_SSE_DIV = 0x5e, - X86_SSE_MAX = 0x5f, - X86_SSE_CVTDQ2PD = 0xe6, - X86_SSE_CVTDQ2PS = 0x5b, - X86_SSE_CVTPD2DQ = 0xe6, - X86_SSE_CVTPD2PI = 0x2d, - X86_SSE_CVTPD2PS = 0x5a, - X86_SSE_CVTPI2PD = 0x2a, - X86_SSE_CVTPI2PS = 0x2a, - X86_SSE_CVTPS2DQ = 0x5b, - X86_SSE_CVTPS2PD = 0x5a, - X86_SSE_CVTPS2PI = 0x2d, - X86_SSE_CVTSD2SI = 0x2d, - X86_SSE_CVTSD2SS = 0x5a, - X86_SSE_CVTSI2SD = 0x2a, - X86_SSE_CVTSI2SS = 0x2a, - X86_SSE_CVTSS2SD = 0x5a, - X86_SSE_CVTSS2SI = 0x2d, - X86_SSE_CVTTPD2PI = 0x2c, - X86_SSE_CVTTPD2DQ = 0xe6, - X86_SSE_CVTTPS2DQ = 0x5b, - X86_SSE_CVTTPS2PI = 0x2c, - X86_SSE_CVTTSD2SI = 0x2c, - X86_SSE_CVTTSS2SI = 0x2c, - X86_SSE_MOVMSK = 0x50, - X86_SSE_PACKSSDW = 0x6b, - X86_SSE_PACKSSWB = 0x63, - X86_SSE_PACKUSWB = 0x67, - X86_SSE_PADDB = 0xfc, - X86_SSE_PADDD = 0xfe, - X86_SSE_PADDQ = 0xd4, - X86_SSE_PADDSB = 0xec, - X86_SSE_PADDSW = 0xed, - X86_SSE_PADDUSB = 0xdc, - X86_SSE_PADDUSW = 0xdd, - X86_SSE_PADDW = 0xfd, - X86_SSE_PAND = 0xdb, - X86_SSE_PANDN = 0xdf, - X86_SSE_PAVGB = 0xe0, - X86_SSE_PAVGW = 0xe3, - X86_SSE_PCMPEQB = 0x74, - X86_SSE_PCMPEQD = 0x76, - X86_SSE_PCMPEQW = 0x75, - X86_SSE_PCMPGTB = 0x64, - X86_SSE_PCMPGTD = 0x66, - X86_SSE_PCMPGTW = 0x65, - X86_SSE_PMADDWD = 0xf5, - X86_SSE_PMAXSW = 0xee, - X86_SSE_PMAXUB = 0xde, - X86_SSE_PMINSW = 0xea, - X86_SSE_PMINUB = 0xda, - X86_SSE_PMOVMSKB = 0xd7, - X86_SSE_PMULHUW = 0xe4, - X86_SSE_PMULHW = 0xe5, - X86_SSE_PMULLW = 0xd5, - X86_SSE_PMULUDQ = 0xf4, - X86_SSE_POR = 0xeb, - X86_SSE_PSADBW = 0xf6, - X86_SSE_PSLLD = 0xf2, - X86_SSE_PSLLQ = 0xf3, - X86_SSE_PSLLW = 0xf1, - X86_SSE_PSRAD = 0xe2, - X86_SSE_PSRAW = 0xe1, - X86_SSE_PSRLD = 0xd2, - X86_SSE_PSRLQ = 0xd3, - X86_SSE_PSRLW = 0xd1, - X86_SSE_PSUBB = 0xf8, - X86_SSE_PSUBD = 0xfa, - X86_SSE_PSUBQ = 0xfb, - X86_SSE_PSUBSB = 0xe8, - X86_SSE_PSUBSW = 0xe9, - X86_SSE_PSUBUSB = 0xd8, - X86_SSE_PSUBUSW = 0xd9, - X86_SSE_PSUBW = 0xf9, - X86_SSE_PUNPCKHBW = 0x68, - X86_SSE_PUNPCKHDQ = 0x6a, - X86_SSE_PUNPCKHQDQ = 0x6d, - X86_SSE_PUNPCKHWD = 0x69, - X86_SSE_PUNPCKLBW = 0x60, - X86_SSE_PUNPCKLDQ = 0x62, - X86_SSE_PUNPCKLQDQ = 0x6c, - X86_SSE_PUNPCKLWD = 0x61, - X86_SSE_PXOR = 0xef, - X86_SSSE3_PSHUFB = 0x00, -}; - -/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ - -#define _SSSE3Lrr(OP1,OP2,RS,RSA,RD,RDA) (_B(0x66), _REXLrr(RD,RD), _B(0x0f), _OO_Mrm (((OP1)<<8)|(OP2) ,_b11,RDA(RD),RSA(RS) )) -#define _SSSE3Lmr(OP1,OP2,MD,MB,MI,MS,RD,RDA) (_B(0x66), _REXLmr(MB, MI, RD), _B(0x0f), _OO_r_X (((OP1)<<8)|(OP2) ,RDA(RD) ,MD,MB,MI,MS )) -#define _SSSE3Lirr(OP1,OP2,IM,RS,RD) (_B(0x66), _REXLrr(RD, RS), _B(0x0f), _OO_Mrm_B (((OP1)<<8)|(OP2) ,_b11,_rX(RD),_rX(RS) ,_u8(IM))) -#define _SSSE3Limr(OP1,OP2,IM,MD,MB,MI,MS,RD) (_B(0x66), _REXLmr(MB, MI, RD), _B(0x0f), _OO_r_X_B (((OP1)<<8)|(OP2) ,_rX(RD) ,MD,MB,MI,MS ,_u8(IM))) - -#define __SSELir(OP,MO,IM,RD) (_REXLrr(0, RD), _OO_Mrm_B (0x0f00|(OP) ,_b11,MO ,_rX(RD) ,_u8(IM))) -#define __SSELim(OP,MO,IM,MD,MB,MI,MS) (_REXLrm(0, MB, MI), _OO_r_X_B (0x0f00|(OP) ,MO ,MD,MB,MI,MS ,_u8(IM))) -#define __SSELrr(OP,RS,RSA,RD,RDA) (_REXLrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) )) -#define __SSELmr(OP,MD,MB,MI,MS,RD,RDA) (_REXLmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS )) -#define __SSELrm(OP,RS,RSA,MD,MB,MI,MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS )) -#define __SSELirr(OP,IM,RS,RD) (_REXLrr(RD, RS), _OO_Mrm_B (0x0f00|(OP) ,_b11,_rX(RD),_rX(RS) ,_u8(IM))) -#define __SSELimr(OP,IM,MD,MB,MI,MS,RD) (_REXLmr(MB, MI, RD), _OO_r_X_B (0x0f00|(OP) ,_rX(RD) ,MD,MB,MI,MS ,_u8(IM))) - -#define __SSEQrr(OP,RS,RSA,RD,RDA) (_REXQrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) )) -#define __SSEQmr(OP,MD,MB,MI,MS,RD,RDA) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS )) -#define __SSEQrm(OP,RS,RSA,MD,MB,MI,MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS )) - -#define _SSELrr(PX,OP,RS,RSA,RD,RDA) (_B(PX), __SSELrr(OP, RS, RSA, RD, RDA)) -#define _SSELmr(PX,OP,MD,MB,MI,MS,RD,RDA) (_B(PX), __SSELmr(OP, MD, MB, MI, MS, RD, RDA)) -#define _SSELrm(PX,OP,RS,RSA,MD,MB,MI,MS) (_B(PX), __SSELrm(OP, RS, RSA, MD, MB, MI, MS)) -#define _SSELir(PX,OP,MO,IM,RD) (_B(PX), __SSELir(OP, MO, IM, RD)) -#define _SSELim(PX,OP,MO,IM,MD,MB,MI,MS) (_B(PX), __SSELim(OP, MO, IM, MD, MB, MI, MS)) -#define _SSELirr(PX,OP,IM,RS,RD) (_B(PX), __SSELirr(OP, IM, RS, RD)) -#define _SSELimr(PX,OP,IM,MD,MB,MI,MS,RD) (_B(PX), __SSELimr(OP, IM, MD, MB, MI, MS, RD)) - -#define _SSEQrr(PX,OP,RS,RSA,RD,RDA) (_B(PX), __SSEQrr(OP, RS, RSA, RD, RDA)) -#define _SSEQmr(PX,OP,MD,MB,MI,MS,RD,RDA) (_B(PX), __SSEQmr(OP, MD, MB, MI, MS, RD, RDA)) -#define _SSEQrm(PX,OP,RS,RSA,MD,MB,MI,MS) (_B(PX), __SSEQrm(OP, RS, RSA, MD, MB, MI, MS)) - -#define _SSEPSrr(OP,RS,RD) __SSELrr( OP, RS,_rX, RD,_rX) -#define _SSEPSmr(OP,MD,MB,MI,MS,RD) __SSELmr( OP, MD, MB, MI, MS, RD,_rX) -#define _SSEPSrm(OP,RS,MD,MB,MI,MS) __SSELrm( OP, RS,_rX, MD, MB, MI, MS) -#define _SSEPSirr(OP,IM,RS,RD) __SSELirr( OP, IM, RS, RD) -#define _SSEPSimr(OP,IM,MD,MB,MI,MS,RD) __SSELimr( OP, IM, MD, MB, MI, MS, RD) - -#define _SSEPDrr(OP,RS,RD) _SSELrr(0x66, OP, RS,_rX, RD,_rX) -#define _SSEPDmr(OP,MD,MB,MI,MS,RD) _SSELmr(0x66, OP, MD, MB, MI, MS, RD,_rX) -#define _SSEPDrm(OP,RS,MD,MB,MI,MS) _SSELrm(0x66, OP, RS,_rX, MD, MB, MI, MS) -#define _SSEPDirr(OP,IM,RS,RD) _SSELirr(0x66, OP, IM, RS, RD) -#define _SSEPDimr(OP,IM,MD,MB,MI,MS,RD) _SSELimr(0x66, OP, IM, MD, MB, MI, MS, RD) - -#define _SSESSrr(OP,RS,RD) _SSELrr(0xf3, OP, RS,_rX, RD,_rX) -#define _SSESSmr(OP,MD,MB,MI,MS,RD) _SSELmr(0xf3, OP, MD, MB, MI, MS, RD,_rX) -#define _SSESSrm(OP,RS,MD,MB,MI,MS) _SSELrm(0xf3, OP, RS,_rX, MD, MB, MI, MS) -#define _SSESSirr(OP,IM,RS,RD) _SSELirr(0xf3, OP, IM, RS, RD) -#define _SSESSimr(OP,IM,MD,MB,MI,MS,RD) _SSELimr(0xf3, OP, IM, MD, MB, MI, MS, RD) - -#define _SSESDrr(OP,RS,RD) _SSELrr(0xf2, OP, RS,_rX, RD,_rX) -#define _SSESDmr(OP,MD,MB,MI,MS,RD) _SSELmr(0xf2, OP, MD, MB, MI, MS, RD,_rX) -#define _SSESDrm(OP,RS,MD,MB,MI,MS) _SSELrm(0xf2, OP, RS,_rX, MD, MB, MI, MS) -#define _SSESDirr(OP,IM,RS,RD) _SSELirr(0xf2, OP, IM, RS, RD) -#define _SSESDimr(OP,IM,MD,MB,MI,MS,RD) _SSELimr(0xf2, OP, IM, MD, MB, MI, MS, RD) - -#define ADDPSrr(RS, RD) _SSEPSrr(X86_SSE_ADD, RS, RD) -#define ADDPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_ADD, MD, MB, MI, MS, RD) -#define ADDPDrr(RS, RD) _SSEPDrr(X86_SSE_ADD, RS, RD) -#define ADDPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_ADD, MD, MB, MI, MS, RD) - -#define ADDSSrr(RS, RD) _SSESSrr(X86_SSE_ADD, RS, RD) -#define ADDSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_ADD, MD, MB, MI, MS, RD) -#define ADDSDrr(RS, RD) _SSESDrr(X86_SSE_ADD, RS, RD) -#define ADDSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_ADD, MD, MB, MI, MS, RD) - -#define ANDNPSrr(RS, RD) _SSEPSrr(X86_SSE_ANDN, RS, RD) -#define ANDNPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_ANDN, MD, MB, MI, MS, RD) -#define ANDNPDrr(RS, RD) _SSEPDrr(X86_SSE_ANDN, RS, RD) -#define ANDNPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_ANDN, MD, MB, MI, MS, RD) - -#define ANDPSrr(RS, RD) _SSEPSrr(X86_SSE_AND, RS, RD) -#define ANDPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_AND, MD, MB, MI, MS, RD) -#define ANDPDrr(RS, RD) _SSEPDrr(X86_SSE_AND, RS, RD) -#define ANDPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_AND, MD, MB, MI, MS, RD) - -#define CMPPSrr(IM, RS, RD) _SSEPSirr(X86_SSE_CMP, IM, RS, RD) -#define CMPPSmr(IM, MD, MB, MI, MS, RD) _SSEPSimr(X86_SSE_CMP, IM, MD, MB, MI, MS, RD) -#define CMPPDrr(IM, RS, RD) _SSEPDirr(X86_SSE_CMP, IM, RS, RD) -#define CMPPDmr(IM, MD, MB, MI, MS, RD) _SSEPDimr(X86_SSE_CMP, IM, MD, MB, MI, MS, RD) - -#define CMPSSrr(IM, RS, RD) _SSESSirr(X86_SSE_CMP, IM, RS, RD) -#define CMPSSmr(IM, MD, MB, MI, MS, RD) _SSESSimr(X86_SSE_CMP, IM, MD, MB, MI, MS, RD) -#define CMPSDrr(IM, RS, RD) _SSESDirr(X86_SSE_CMP, IM, RS, RD) -#define CMPSDmr(IM, MD, MB, MI, MS, RD) _SSESDimr(X86_SSE_CMP, IM, MD, MB, MI, MS, RD) - -#define DIVPSrr(RS, RD) _SSEPSrr(X86_SSE_DIV, RS, RD) -#define DIVPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_DIV, MD, MB, MI, MS, RD) -#define DIVPDrr(RS, RD) _SSEPDrr(X86_SSE_DIV, RS, RD) -#define DIVPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_DIV, MD, MB, MI, MS, RD) - -#define DIVSSrr(RS, RD) _SSESSrr(X86_SSE_DIV, RS, RD) -#define DIVSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_DIV, MD, MB, MI, MS, RD) -#define DIVSDrr(RS, RD) _SSESDrr(X86_SSE_DIV, RS, RD) -#define DIVSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_DIV, MD, MB, MI, MS, RD) - -#define MAXPSrr(RS, RD) _SSEPSrr(X86_SSE_MAX, RS, RD) -#define MAXPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_MAX, MD, MB, MI, MS, RD) -#define MAXPDrr(RS, RD) _SSEPDrr(X86_SSE_MAX, RS, RD) -#define MAXPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_MAX, MD, MB, MI, MS, RD) - -#define MAXSSrr(RS, RD) _SSESSrr(X86_SSE_MAX, RS, RD) -#define MAXSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_MAX, MD, MB, MI, MS, RD) -#define MAXSDrr(RS, RD) _SSESDrr(X86_SSE_MAX, RS, RD) -#define MAXSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_MAX, MD, MB, MI, MS, RD) - -#define MINPSrr(RS, RD) _SSEPSrr(X86_SSE_MIN, RS, RD) -#define MINPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_MIN, MD, MB, MI, MS, RD) -#define MINPDrr(RS, RD) _SSEPDrr(X86_SSE_MIN, RS, RD) -#define MINPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_MIN, MD, MB, MI, MS, RD) - -#define MINSSrr(RS, RD) _SSESSrr(X86_SSE_MIN, RS, RD) -#define MINSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_MIN, MD, MB, MI, MS, RD) -#define MINSDrr(RS, RD) _SSESDrr(X86_SSE_MIN, RS, RD) -#define MINSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_MIN, MD, MB, MI, MS, RD) - -#define MULPSrr(RS, RD) _SSEPSrr(X86_SSE_MUL, RS, RD) -#define MULPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_MUL, MD, MB, MI, MS, RD) -#define MULPDrr(RS, RD) _SSEPDrr(X86_SSE_MUL, RS, RD) -#define MULPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_MUL, MD, MB, MI, MS, RD) - -#define MULSSrr(RS, RD) _SSESSrr(X86_SSE_MUL, RS, RD) -#define MULSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_MUL, MD, MB, MI, MS, RD) -#define MULSDrr(RS, RD) _SSESDrr(X86_SSE_MUL, RS, RD) -#define MULSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_MUL, MD, MB, MI, MS, RD) - -#define ORPSrr(RS, RD) _SSEPSrr(X86_SSE_OR, RS, RD) -#define ORPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_OR, MD, MB, MI, MS, RD) -#define ORPDrr(RS, RD) _SSEPDrr(X86_SSE_OR, RS, RD) -#define ORPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_OR, MD, MB, MI, MS, RD) - -#define RCPPSrr(RS, RD) _SSEPSrr(X86_SSE_RCP, RS, RD) -#define RCPPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_RCP, MD, MB, MI, MS, RD) -#define RCPSSrr(RS, RD) _SSESSrr(X86_SSE_RCP, RS, RD) -#define RCPSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_RCP, MD, MB, MI, MS, RD) - -#define RSQRTPSrr(RS, RD) _SSEPSrr(X86_SSE_RSQRT, RS, RD) -#define RSQRTPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_RSQRT, MD, MB, MI, MS, RD) -#define RSQRTSSrr(RS, RD) _SSESSrr(X86_SSE_RSQRT, RS, RD) -#define RSQRTSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_RSQRT, MD, MB, MI, MS, RD) - -#define SQRTPSrr(RS, RD) _SSEPSrr(X86_SSE_SQRT, RS, RD) -#define SQRTPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) -#define SQRTPDrr(RS, RD) _SSEPDrr(X86_SSE_SQRT, RS, RD) -#define SQRTPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) - -#define SQRTSSrr(RS, RD) _SSESSrr(X86_SSE_SQRT, RS, RD) -#define SQRTSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) -#define SQRTSDrr(RS, RD) _SSESDrr(X86_SSE_SQRT, RS, RD) -#define SQRTSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) - -#define SUBPSrr(RS, RD) _SSEPSrr(X86_SSE_SUB, RS, RD) -#define SUBPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_SUB, MD, MB, MI, MS, RD) -#define SUBPDrr(RS, RD) _SSEPDrr(X86_SSE_SUB, RS, RD) -#define SUBPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_SUB, MD, MB, MI, MS, RD) - -#define SUBSSrr(RS, RD) _SSESSrr(X86_SSE_SUB, RS, RD) -#define SUBSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_SUB, MD, MB, MI, MS, RD) -#define SUBSDrr(RS, RD) _SSESDrr(X86_SSE_SUB, RS, RD) -#define SUBSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_SUB, MD, MB, MI, MS, RD) - -#define XORPSrr(RS, RD) _SSEPSrr(X86_SSE_XOR, RS, RD) -#define XORPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_XOR, MD, MB, MI, MS, RD) -#define XORPDrr(RS, RD) _SSEPDrr(X86_SSE_XOR, RS, RD) -#define XORPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_XOR, MD, MB, MI, MS, RD) - -#define COMISSrr(RS, RD) _SSEPSrr(X86_SSE_COMI, RS, RD) -#define COMISSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_COMI, MD, MB, MI, MS, RD) -#define COMISDrr(RS, RD) _SSEPDrr(X86_SSE_COMI, RS, RD) -#define COMISDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_COMI, MD, MB, MI, MS, RD) - -#define UCOMISSrr(RS, RD) _SSEPSrr(X86_SSE_UCOMI, RS, RD) -#define UCOMISSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_UCOMI, MD, MB, MI, MS, RD) -#define UCOMISDrr(RS, RD) _SSEPDrr(X86_SSE_UCOMI, RS, RD) -#define UCOMISDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_UCOMI, MD, MB, MI, MS, RD) - -#define MOVAPSrr(RS, RD) _SSEPSrr(0x28, RS, RD) -#define MOVAPSmr(MD, MB, MI, MS, RD) _SSEPSmr(0x28, MD, MB, MI, MS, RD) -#define MOVAPSrm(RS, MD, MB, MI, MS) _SSEPSrm(0x29, RS, MD, MB, MI, MS) - -#define MOVAPDrr(RS, RD) _SSEPDrr(0x28, RS, RD) -#define MOVAPDmr(MD, MB, MI, MS, RD) _SSEPDmr(0x28, MD, MB, MI, MS, RD) -#define MOVAPDrm(RS, MD, MB, MI, MS) _SSEPDrm(0x29, RS, MD, MB, MI, MS) - -#define CVTDQ2PDrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTDQ2PD, RS,_rX, RD,_rX) -#define CVTDQ2PDmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTDQ2PD, MD, MB, MI, MS, RD,_rX) -#define CVTDQ2PSrr(RS, RD) __SSELrr( X86_SSE_CVTDQ2PS, RS,_rX, RD,_rX) -#define CVTDQ2PSmr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTDQ2PS, MD, MB, MI, MS, RD,_rX) -#define CVTPD2DQrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTPD2DQ, RS,_rX, RD,_rX) -#define CVTPD2DQmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTPD2DQ, MD, MB, MI, MS, RD,_rX) -#define CVTPD2PIrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTPD2PI, RS,_rX, RD,_rM) -#define CVTPD2PImr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTPD2PI, MD, MB, MI, MS, RD,_rM) -#define CVTPD2PSrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTPD2PS, RS,_rX, RD,_rX) -#define CVTPD2PSmr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTPD2PS, MD, MB, MI, MS, RD,_rX) -#define CVTPI2PDrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTPI2PD, RS,_rM, RD,_rX) -#define CVTPI2PDmr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTPI2PD, MD, MB, MI, MS, RD,_rX) -#define CVTPI2PSrr(RS, RD) __SSELrr( X86_SSE_CVTPI2PS, RS,_rM, RD,_rX) -#define CVTPI2PSmr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTPI2PS, MD, MB, MI, MS, RD,_rX) -#define CVTPS2DQrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTPS2DQ, RS,_rX, RD,_rX) -#define CVTPS2DQmr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTPS2DQ, MD, MB, MI, MS, RD,_rX) -#define CVTPS2PDrr(RS, RD) __SSELrr( X86_SSE_CVTPS2PD, RS,_rX, RD,_rX) -#define CVTPS2PDmr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTPS2PD, MD, MB, MI, MS, RD,_rX) -#define CVTPS2PIrr(RS, RD) __SSELrr( X86_SSE_CVTPS2PI, RS,_rX, RD,_rM) -#define CVTPS2PImr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTPS2PI, MD, MB, MI, MS, RD,_rM) -#define CVTSD2SILrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTSD2SI, RS,_rX, RD,_r4) -#define CVTSD2SILmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTSD2SI, MD, MB, MI, MS, RD,_r4) -#define CVTSD2SIQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTSD2SI, RS,_rX, RD,_r8) -#define CVTSD2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTSD2SI, MD, MB, MI, MS, RD,_r8) -#define CVTSD2SSrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTSD2SS, RS,_rX, RD,_rX) -#define CVTSD2SSmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTSD2SS, MD, MB, MI, MS, RD,_rX) -#define CVTSI2SDLrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTSI2SD, RS,_r4, RD,_rX) -#define CVTSI2SDLmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTSI2SD, MD, MB, MI, MS, RD,_rX) -#define CVTSI2SDQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTSI2SD, RS,_r8, RD,_rX) -#define CVTSI2SDQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTSI2SD, MD, MB, MI, MS, RD,_rX) -#define CVTSI2SSLrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTSI2SS, RS,_r4, RD,_rX) -#define CVTSI2SSLmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTSI2SS, MD, MB, MI, MS, RD,_rX) -#define CVTSI2SSQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTSI2SS, RS,_r8, RD,_rX) -#define CVTSI2SSQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTSI2SS, MD, MB, MI, MS, RD,_rX) -#define CVTSS2SDrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTSS2SD, RS,_rX, RD,_rX) -#define CVTSS2SDmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTSS2SD, MD, MB, MI, MS, RD,_rX) -#define CVTSS2SILrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTSS2SI, RS,_rX, RD,_r4) -#define CVTSS2SILmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTSS2SI, MD, MB, MI, MS, RD,_r4) -#define CVTSS2SIQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTSS2SI, RS,_rX, RD,_r8) -#define CVTSS2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTSS2SI, MD, MB, MI, MS, RD,_r8) -#define CVTTPD2PIrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTTPD2PI, RS,_rX, RD,_rM) -#define CVTTPD2PImr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTTPD2PI, MD, MB, MI, MS, RD,_rM) -#define CVTTPD2DQrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTTPD2DQ, RS,_rX, RD,_rX) -#define CVTTPD2DQmr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTTPD2DQ, MD, MB, MI, MS, RD,_rX) -#define CVTTPS2DQrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTTPS2DQ, RS,_rX, RD,_rX) -#define CVTTPS2DQmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTTPS2DQ, MD, MB, MI, MS, RD,_rX) -#define CVTTPS2PIrr(RS, RD) __SSELrr( X86_SSE_CVTTPS2PI, RS,_rX, RD,_rM) -#define CVTTPS2PImr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTTPS2PI, MD, MB, MI, MS, RD,_rM) -#define CVTTSD2SILrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTTSD2SI, RS,_rX, RD,_r4) -#define CVTTSD2SILmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTTSD2SI, MD, MB, MI, MS, RD,_r4) -#define CVTTSD2SIQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTTSD2SI, RS,_rX, RD,_r8) -#define CVTTSD2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTTSD2SI, MD, MB, MI, MS, RD,_r8) -#define CVTTSS2SILrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTTSS2SI, RS,_rX, RD,_r4) -#define CVTTSS2SILmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTTSS2SI, MD, MB, MI, MS, RD,_r4) -#define CVTTSS2SIQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTTSS2SI, RS,_rX, RD,_r8) -#define CVTTSS2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTTSS2SI, MD, MB, MI, MS, RD,_r8) - -#define MOVDXDrr(RS, RD) _SSELrr(0x66, 0x6e, RS,_r4, RD,_rX) -#define MOVDXDmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x6e, MD, MB, MI, MS, RD,_rX) -#define MOVQXDrr(RS, RD) _SSEQrr(0x66, 0x6e, RS,_r8, RD,_rX) -#define MOVQXDmr(MD, MB, MI, MS, RD) _SSEQmr(0x66, 0x6e, MD, MB, MI, MS, RD,_rX) - -#define MOVDXSrr(RS, RD) _SSELrr(0x66, 0x7e, RD,_r4, RS,_rX) -#define MOVDXSrm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x7e, RS,_rX, MD, MB, MI, MS) -#define MOVQXSrr(RS, RD) _SSEQrr(0x66, 0x7e, RD,_r8, RS,_rX) -#define MOVQXSrm(RS, MD, MB, MI, MS) _SSEQrm(0x66, 0x7e, RS,_rX, MD, MB, MI, MS) - -#define MOVDLMrr(RS, RD) __SSELrr( 0x6e, RS,_r4, RD,_rM) -#define MOVDLMmr(MD, MB, MI, MS, RD) __SSELmr( 0x6e, MD, MB, MI, MS, RD,_rM) -#define MOVDQMrr(RS, RD) __SSEQrr( 0x6e, RS,_r8, RD,_rM) -#define MOVDQMmr(MD, MB, MI, MS, RD) __SSEQmr( 0x6e, MD, MB, MI, MS, RD,_rM) - -#define MOVDMLrr(RS, RD) __SSELrr( 0x7e, RS,_rM, RD,_r4) -#define MOVDMLrm(RS, MD, MB, MI, MS) __SSELrm( 0x7e, RS,_rM, MD, MB, MI, MS) -#define MOVDMQrr(RS, RD) __SSEQrr( 0x7e, RS,_rM, RD,_r8) -#define MOVDMQrm(RS, MD, MB, MI, MS) __SSEQrm( 0x7e, RS,_rM, MD, MB, MI, MS) - -#define MOVDQ2Qrr(RS, RD) _SSELrr(0xf2, 0xd6, RS,_rX, RD,_rM) -#define MOVMSKPSrr(RS, RD) __SSELrr( 0x50, RS,_rX, RD,_r4) -#define MOVMSKPDrr(RS, RD) _SSELrr(0x66, 0x50, RS,_rX, RD,_r4) - -#define MOVHLPSrr(RS, RD) __SSELrr( 0x12, RS,_rX, RD,_rX) -#define MOVLHPSrr(RS, RD) __SSELrr( 0x16, RS,_rX, RD,_rX) - -#define MOVDQArr(RS, RD) _SSELrr(0x66, 0x6f, RS,_rX, RD,_rX) -#define MOVDQAmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x6f, MD, MB, MI, MS, RD,_rX) -#define MOVDQArm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x7f, RS,_rX, MD, MB, MI, MS) - -#define MOVDQUrr(RS, RD) _SSELrr(0xf3, 0x6f, RS,_rX, RD,_rX) -#define MOVDQUmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, 0x6f, MD, MB, MI, MS, RD,_rX) -#define MOVDQUrm(RS, MD, MB, MI, MS) _SSELrm(0xf3, 0x7f, RS,_rX, MD, MB, MI, MS) - -#define MOVHPDmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x16, MD, MB, MI, MS, RD,_rX) -#define MOVHPDrm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x17, RS,_rX, MD, MB, MI, MS) -#define MOVHPSmr(MD, MB, MI, MS, RD) __SSELmr( 0x16, MD, MB, MI, MS, RD,_rX) -#define MOVHPSrm(RS, MD, MB, MI, MS) __SSELrm( 0x17, RS,_rX, MD, MB, MI, MS) - -#define MOVLPDmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x12, MD, MB, MI, MS, RD,_rX) -#define MOVLPDrm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x13, RS,_rX, MD, MB, MI, MS) -#define MOVLPSmr(MD, MB, MI, MS, RD) __SSELmr( 0x12, MD, MB, MI, MS, RD,_rX) -#define MOVLPSrm(RS, MD, MB, MI, MS) __SSELrm( 0x13, RS,_rX, MD, MB, MI, MS) - - -/* --- Floating-Point instructions ----------------------------------------- */ - -enum { - X86_F2XM1 = 0xd9f0, - X86_FABS = 0xd9e1, - X86_FADD = 0xd8c0, // m32fp, m64fp, sti0, st0i, pst0i - X86_FIADD = 0xda00, // m32int, m16int - X86_FBLD = 0xdf04, // mem - X86_FBSTP = 0xdf06, // mem - X86_FCHS = 0xd9e0, - X86_FCMOVB = 0xdac0, // sti0 - X86_FCMOVE = 0xdac8, // sti0 - X86_FCMOVBE = 0xdad0, // sti0 - X86_FCMOVU = 0xdad8, // sti0 - X86_FCMOVNB = 0xdbc0, // sti0 - X86_FCMOVNE = 0xdbc8, // sti0 - X86_FCMOVNBE = 0xdbd0, // sti0 - X86_FCMOVNU = 0xdbd8, // sti0 - X86_FCOM = 0xd8d2, // m32fp, m64fp, sti - X86_FCOMP = 0xd8db, // m32fp, m64fp, sti - X86_FCOMPP = 0xded9, - X86_FCOMI = 0xdbf0, // sti0 - X86_FCOMIP = 0xdff0, // sti0 - X86_FUCOMI = 0xdbe8, // sti0 - X86_FUCOMIP = 0xdfe8, // sti0 - X86_FCOS = 0xd9ff, - X86_FDECSTP = 0xd9f6, - X86_FDIV = 0xd8f6, // m32fp, m64fp, sti0, st0i, pst0i - X86_FIDIV = 0xda06, // m32int, m16int - X86_FDIVR = 0xd8ff, // m32fp, m64fp, sti0, st0i, pst0i - X86_FIDIVR = 0xda07, // m32int, m16int - X86_FFREE = 0xddc0, // sti - X86_FICOM = 0xda02, // m32int, m16int - X86_FICOMP = 0xda03, // m32int, m16int - X86_FILD = 0xdb00, // m32int, m16int - X86_FILDQ = 0xdf05, // mem - X86_FINCSTP = 0xd9f7, - X86_FIST = 0xdb02, // m32int, m16int - X86_FISTP = 0xdb03, // m32int, m16int - X86_FISTPQ = 0xdf07, // mem - X86_FISTTP = 0xdb01, // m32int, m16int - X86_FISTTPQ = 0xdd01, // mem - X86_FLD = 0xd900, // m32fp, m64fp - X86_FLDT = 0xdb05, // mem - X86_FLD1 = 0xd9e8, - X86_FLDL2T = 0xd9e9, - X86_FLDL2E = 0xd9ea, - X86_FLDPI = 0xd9eb, - X86_FLDLG2 = 0xd9ec, - X86_FLDLN2 = 0xd9ed, - X86_FLDZ = 0xd9ee, - X86_FMUL = 0xd8c9, // m32fp, m64fp, sti0, st0i, pst0i - X86_FIMUL = 0xda01, // m32int, m16int - X86_FNOP = 0xd9d0, - X86_FPATAN = 0xd9f3, - X86_FPREM = 0xd9f8, - X86_FPREM1 = 0xd9f5, - X86_FPTAN = 0xd9f2, - X86_FRNDINT = 0xd9fc, - X86_FSCALE = 0xd9fd, - X86_FSIN = 0xd9fe, - X86_FSINCOS = 0xd9fb, - X86_FSQRT = 0xd9fa, - X86_FSTS = 0xd902, // mem - X86_FSTD = 0xdd02, // mem - X86_FST = 0xddd0, // sti - X86_FSTPS = 0xd903, // mem - X86_FSTPD = 0xdd03, // mem - X86_FSTPT = 0xdb07, // mem - X86_FSTP = 0xddd8, // sti - X86_FSUB = 0xd8e4, // m32fp, m64fp, sti0, st0i, pst0i - X86_FISUB = 0xda04, // m32int, m16int - X86_FSUBR = 0xd8ed, // m32fp, m64fp, sti0, st0i, pst0i - X86_FISUBR = 0xda05, // m32int, m16int - X86_FTST = 0xd9e4, - X86_FUCOM = 0xdde0, // sti - X86_FUCOMP = 0xdde8, // sti - X86_FUCOMPP = 0xdae9, - X86_FXAM = 0xd9e5, - X86_FXCH = 0xd9c8, // sti - X86_FXTRACT = 0xd9f4, - X86_FYL2X = 0xd9f1, - X86_FYL2XP1 = 0xd9f9, -}; - -#define _FPU(OP) _OO(OP) -#define _FPUm(OP, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_r_X((OP)>>8, (OP)&7, MD, MB, MI, MS)) -#define _FPUSm(OP, MD, MB, MI, MS) _FPUm(OP, MD, MB, MI, MS) -#define _FPUDm(OP, MD, MB, MI, MS) _FPUm((OP)|0x400, MD, MB, MI, MS) -#define _FPULm(OP, MD, MB, MI, MS) _FPUm(OP, MD, MB, MI, MS) -#define _FPUWm(OP, MD, MB, MI, MS) _FPUm((OP)|0x400, MD, MB, MI, MS) -#define _FPUr(OP, RR) _OOr((OP)&0xfff8, _rF(RR)) -#define _FPU0r(OP, RD) _FPUr((OP)|0x400, RD) -#define _FPUr0(OP, RS) _FPUr((OP) , RS) -#define _FPUrr(OP, RS, RD) (_rST0P(RS) ? _FPU0r(OP, RD) : (_rST0P(RD) ? _FPUr0(OP, RS) : x86_emit_failure("FPU instruction without st0"))) -#define _FPUP0r(OP, RD) _FPU0r((OP)|0x200, RD) - -#define F2XM1() _FPU(X86_F2XM1) -#define FABS() _FPU(X86_FABS) -#define FADDSm(MD, MB, MI, MS) _FPUSm(X86_FADD, MD, MB, MI, MS) -#define FADDDm(MD, MB, MI, MS) _FPUDm(X86_FADD, MD, MB, MI, MS) -#define FADDP0r(RD) _FPUP0r(X86_FADD, RD) -#define FADDrr(RS, RD) _FPUrr(X86_FADD, RS, RD) -#define FADD0r(RD) _FPU0r(X86_FADD, RD) -#define FADDr0(RS) _FPUr0(X86_FADD, RS) -#define FIADDWm(MD, MB, MI, MS) _FPUWm(X86_FIADD, MD, MB, MI, MS) -#define FIADDLm(MD, MB, MI, MS) _FPULm(X86_FIADD, MD, MB, MI, MS) -#define FBLDm(MD, MB, MI, MS) _FPUm(X86_FBLD, MD, MB, MI, MS) -#define FBSTPm(MD, MB, MI, MS) _FPUm(X86_FBSTP, MD, MB, MI, MS) -#define FCHS() _FPU(X86_FCHS) -#define FCMOVBr0(RS) _FPUr0(X86_FCMOVB, RS) -#define FCMOVEr0(RS) _FPUr0(X86_FCMOVE, RS) -#define FCMOVBEr0(RS) _FPUr0(X86_FCMOVBE, RS) -#define FCMOVUr0(RS) _FPUr0(X86_FCMOVU, RS) -#define FCMOVNBr0(RS) _FPUr0(X86_FCMOVNB, RS) -#define FCMOVNEr0(RS) _FPUr0(X86_FCMOVNE, RS) -#define FCMOVNBEr0(RS) _FPUr0(X86_FCMOVNBE, RS) -#define FCMOVNUr0(RS) _FPUr0(X86_FCMOVNU, RS) -#define FCOMSm(MD, MB, MI, MS) _FPUSm(X86_FCOM, MD, MB, MI, MS) -#define FCOMDm(MD, MB, MI, MS) _FPUDm(X86_FCOM, MD, MB, MI, MS) -#define FCOMr(RD) _FPUr(X86_FCOM, RD) -#define FCOMPSm(MD, MB, MI, MS) _FPUSm(X86_FCOMP, MD, MB, MI, MS) -#define FCOMPDm(MD, MB, MI, MS) _FPUDm(X86_FCOMP, MD, MB, MI, MS) -#define FCOMPr(RD) _FPUr(X86_FCOMP, RD) -#define FCOMPP() _FPU(X86_FCOMPP) -#define FCOMIr0(RS) _FPUr0(X86_FCOMI, RS) -#define FCOMIPr0(RS) _FPUr0(X86_FCOMIP, RS) -#define FUCOMIr0(RS) _FPUr0(X86_FUCOMI, RS) -#define FUCOMIPr0(RS) _FPUr0(X86_FUCOMIP, RS) -#define FCOS() _FPU(X86_FCOS) -#define FDECSTP() _FPU(X86_FDECSTP) -#define FDIVSm(MD, MB, MI, MS) _FPUSm(X86_FDIV, MD, MB, MI, MS) -#define FDIVDm(MD, MB, MI, MS) _FPUDm(X86_FDIV, MD, MB, MI, MS) -#define FDIVP0r(RD) _FPUP0r(X86_FDIV, RD) -#define FDIVrr(RS, RD) _FPUrr(X86_FDIV, RS, RD) -#define FDIV0r(RD) _FPU0r(X86_FDIV, RD) -#define FDIVr0(RS) _FPUr0(X86_FDIV, RS) -#define FIDIVWm(MD, MB, MI, MS) _FPUWm(X86_FIDIV, MD, MB, MI, MS) -#define FIDIVLm(MD, MB, MI, MS) _FPULm(X86_FIDIV, MD, MB, MI, MS) -#define FDIVRSm(MD, MB, MI, MS) _FPUSm(X86_FDIVR, MD, MB, MI, MS) -#define FDIVRDm(MD, MB, MI, MS) _FPUDm(X86_FDIVR, MD, MB, MI, MS) -#define FDIVRP0r(RD) _FPUP0r(X86_FDIVR, RD) -#define FDIVRrr(RS, RD) _FPUrr(X86_FDIVR, RS, RD) -#define FDIVR0r(RD) _FPU0r(X86_FDIVR, RD) -#define FDIVRr0(RS) _FPUr0(X86_FDIVR, RS) -#define FIDIVRWm(MD, MB, MI, MS) _FPUWm(X86_FIDIVR, MD, MB, MI, MS) -#define FIDIVRLm(MD, MB, MI, MS) _FPULm(X86_FIDIVR, MD, MB, MI, MS) -#define FFREEr(RD) _FPUr(X86_FFREE, RD) -#define FICOMWm(MD, MB, MI, MS) _FPUWm(X86_FICOM, MD, MB, MI, MS) -#define FICOMLm(MD, MB, MI, MS) _FPULm(X86_FICOM, MD, MB, MI, MS) -#define FICOMPWm(MD, MB, MI, MS) _FPUWm(X86_FICOMP, MD, MB, MI, MS) -#define FICOMPLm(MD, MB, MI, MS) _FPULm(X86_FICOMP, MD, MB, MI, MS) -#define FILDWm(MD, MB, MI, MS) _FPUWm(X86_FILD, MD, MB, MI, MS) -#define FILDLm(MD, MB, MI, MS) _FPULm(X86_FILD, MD, MB, MI, MS) -#define FILDQm(MD, MB, MI, MS) _FPUm(X86_FILDQ, MD, MB, MI, MS) -#define FINCSTP() _FPU(X86_FINCSTP) -#define FISTWm(MD, MB, MI, MS) _FPUWm(X86_FIST, MD, MB, MI, MS) -#define FISTLm(MD, MB, MI, MS) _FPULm(X86_FIST, MD, MB, MI, MS) -#define FISTPWm(MD, MB, MI, MS) _FPUWm(X86_FISTP, MD, MB, MI, MS) -#define FISTPLm(MD, MB, MI, MS) _FPULm(X86_FISTP, MD, MB, MI, MS) -#define FISTPQm(MD, MB, MI, MS) _FPUm(X86_FISTPQ, MD, MB, MI, MS) -#define FISTTPWm(MD, MB, MI, MS) _FPUWm(X86_FISTTP, MD, MB, MI, MS) -#define FISTTPLm(MD, MB, MI, MS) _FPULm(X86_FISTTP, MD, MB, MI, MS) -#define FISTTPQm(MD, MB, MI, MS) _FPUm(X86_FISTTPQ, MD, MB, MI, MS) -#define FLDSm(MD, MB, MI, MS) _FPUSm(X86_FLD, MD, MB, MI, MS) -#define FLDDm(MD, MB, MI, MS) _FPUDm(X86_FLD, MD, MB, MI, MS) -#define FLDTm(MD, MB, MI, MS) _FPUm(X86_FLDT, MD, MB, MI, MS) -#define FLD1() _FPU(X86_FLD1) -#define FLDL2T() _FPU(X86_FLDL2T) -#define FLDL2E() _FPU(X86_FLDL2E) -#define FLDPI() _FPU(X86_FLDPI) -#define FLDLG2() _FPU(X86_FLDLG2) -#define FLDLN2() _FPU(X86_FLDLN2) -#define FLDZ() _FPU(X86_FLDZ) -#define FMULSm(MD, MB, MI, MS) _FPUSm(X86_FMUL, MD, MB, MI, MS) -#define FMULDm(MD, MB, MI, MS) _FPUDm(X86_FMUL, MD, MB, MI, MS) -#define FMULP0r(RD) _FPUP0r(X86_FMUL, RD) -#define FMULrr(RS, RD) _FPUrr(X86_FMUL, RS, RD) -#define FMUL0r(RD) _FPU0r(X86_FMUL, RD) -#define FMULr0(RS) _FPUr0(X86_FMUL, RS) -#define FIMULWm(MD, MB, MI, MS) _FPUWm(X86_FIMUL, MD, MB, MI, MS) -#define FIMULLm(MD, MB, MI, MS) _FPULm(X86_FIMUL, MD, MB, MI, MS) -#define FNOP() _FPU(X86_FNOP) -#define FPATAN() _FPU(X86_FPATAN) -#define FPREM() _FPU(X86_FPREM) -#define FPREM1() _FPU(X86_FPREM1) -#define FPTAN() _FPU(X86_FPTAN) -#define FRNDINT() _FPU(X86_FRNDINT) -#define FSCALE() _FPU(X86_FSCALE) -#define FSIN() _FPU(X86_FSIN) -#define FSINCOS() _FPU(X86_FSINCOS) -#define FSQRT() _FPU(X86_FSQRT) -#define FSTSm(MD, MB, MI, MS) _FPUm(X86_FSTS, MD, MB, MI, MS) -#define FSTDm(MD, MB, MI, MS) _FPUm(X86_FSTD, MD, MB, MI, MS) -#define FSTr(RD) _FPUr(X86_FST, RD) -#define FSTPSm(MD, MB, MI, MS) _FPUm(X86_FSTPS, MD, MB, MI, MS) -#define FSTPDm(MD, MB, MI, MS) _FPUm(X86_FSTPD, MD, MB, MI, MS) -#define FSTPTm(MD, MB, MI, MS) _FPUm(X86_FSTPT, MD, MB, MI, MS) -#define FSTPr(RD) _FPUr(X86_FSTP, RD) -#define FSUBSm(MD, MB, MI, MS) _FPUSm(X86_FSUB, MD, MB, MI, MS) -#define FSUBDm(MD, MB, MI, MS) _FPUDm(X86_FSUB, MD, MB, MI, MS) -#define FSUBP0r(RD) _FPUP0r(X86_FSUB, RD) -#define FSUBrr(RS, RD) _FPUrr(X86_FSUB, RS, RD) -#define FSUB0r(RD) _FPU0r(X86_FSUB, RD) -#define FSUBr0(RS) _FPUr0(X86_FSUB, RS) -#define FISUBWm(MD, MB, MI, MS) _FPUWm(X86_FISUB, MD, MB, MI, MS) -#define FISUBLm(MD, MB, MI, MS) _FPULm(X86_FISUB, MD, MB, MI, MS) -#define FSUBRSm(MD, MB, MI, MS) _FPUSm(X86_FSUBR, MD, MB, MI, MS) -#define FSUBRDm(MD, MB, MI, MS) _FPUDm(X86_FSUBR, MD, MB, MI, MS) -#define FSUBRP0r(RD) _FPUP0r(X86_FSUBR, RD) -#define FSUBRrr(RS, RD) _FPUrr(X86_FSUBR, RS, RD) -#define FSUBR0r(RD) _FPU0r(X86_FSUBR, RD) -#define FSUBRr0(RS) _FPUr0(X86_FSUBR, RS) -#define FISUBRWm(MD, MB, MI, MS) _FPUWm(X86_FISUBR, MD, MB, MI, MS) -#define FISUBRLm(MD, MB, MI, MS) _FPULm(X86_FISUBR, MD, MB, MI, MS) -#define FTST() _FPU(X86_FTST) -#define FUCOMr(RD) _FPUr(X86_FUCOM, RD) -#define FUCOMPr(RD) _FPUr(X86_FUCOMP, RD) -#define FUCOMPP() _FPU(X86_FUCOMPP) -#define FXAM() _FPU(X86_FXAM) -#define FXCHr(RD) _FPUr(X86_FXCH, RD) -#define FXTRACT() _FPU(X86_FXTRACT) -#define FYL2X() _FPU(X86_FYL2X) -#define FYL2XP1() _FPU(X86_FYL2XP1) - -#endif /* X86_RTASM_H */ diff --git a/BasiliskII/src/uae_cpu/compiler/compemu.h b/BasiliskII/src/uae_cpu/compiler/compemu.h deleted file mode 100644 index 9a612fb2..00000000 --- a/BasiliskII/src/uae_cpu/compiler/compemu.h +++ /dev/null @@ -1,609 +0,0 @@ -/* - * compiler/compemu.h - Public interface and definitions - * - * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer - * - * Adaptation for Basilisk II and improvements, copyright 2000-2005 - * Gwenole Beauchesne - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef COMPEMU_H -#define COMPEMU_H - -#include "newcpu.h" - -#if USE_JIT - -#if defined __i386__ || defined __x86_64__ -#include "flags_x86.h" -#else -#error "Unsupported JIT compiler for this architecture" -#endif - -#if JIT_DEBUG -/* dump some information (m68k block, x86 block addresses) about the compiler state */ -extern void compiler_dumpstate(void); -#endif - -/* Now that we do block chaining, and also have linked lists on each tag, - TAGMASK can be much smaller and still do its job. Saves several megs - of memory! */ -#define TAGMASK 0x0000ffff -#define TAGSIZE (TAGMASK+1) -#define MAXRUN 1024 -#define cacheline(x) (((uintptr)x)&TAGMASK) - -extern uae_u8* start_pc_p; -extern uae_u32 start_pc; - -struct blockinfo_t; - -struct cpu_history { - uae_u16 * location; -}; - -union cacheline { - cpuop_func * handler; - blockinfo_t * bi; -}; - -/* Use new spill/reload strategy when calling external functions */ -#define USE_OPTIMIZED_CALLS 0 -#if USE_OPTIMIZED_CALLS -#error implementation in progress -#endif - -/* (gb) When on, this option can save save up to 30% compilation time - * when many lazy flushes occur (e.g. apps in MacOS 8.x). - */ -#define USE_SEPARATE_BIA 1 - -/* Use chain of checksum_info_t to compute the block checksum */ -#define USE_CHECKSUM_INFO 1 - -/* Use code inlining, aka follow-up of constant jumps */ -#define USE_INLINING 1 - -/* Inlining requires the chained checksuming information */ -#if USE_INLINING -#undef USE_CHECKSUM_INFO -#define USE_CHECKSUM_INFO 1 -#endif - -/* Does flush_icache_range() only check for blocks falling in the requested range? */ -#define LAZY_FLUSH_ICACHE_RANGE 0 - -#define USE_F_ALIAS 1 -#define USE_OFFSET 1 -#define COMP_DEBUG 1 - -#if COMP_DEBUG -#define Dif(x) if (x) -#else -#define Dif(x) if (0) -#endif - -#define SCALE 2 - -#define BYTES_PER_INST 10240 /* paranoid ;-) */ -#define LONGEST_68K_INST 16 /* The number of bytes the longest possible - 68k instruction takes */ -#define MAX_CHECKSUM_LEN 2048 /* The maximum size we calculate checksums - for. Anything larger will be flushed - unconditionally even with SOFT_FLUSH */ -#define MAX_HOLD_BI 3 /* One for the current block, and up to two - for jump targets */ - -#define INDIVIDUAL_INST 0 -#if 1 -// gb-- my format from readcpu.cpp is not the same -#define FLAG_X 0x0010 -#define FLAG_N 0x0008 -#define FLAG_Z 0x0004 -#define FLAG_V 0x0002 -#define FLAG_C 0x0001 -#else -#define FLAG_C 0x0010 -#define FLAG_V 0x0008 -#define FLAG_Z 0x0004 -#define FLAG_N 0x0002 -#define FLAG_X 0x0001 -#endif -#define FLAG_CZNV (FLAG_C | FLAG_Z | FLAG_N | FLAG_V) -#define FLAG_ZNV (FLAG_Z | FLAG_N | FLAG_V) - -#define KILLTHERAT 1 /* Set to 1 to avoid some partial_rat_stalls */ - -#if defined(__x86_64__) -#define N_REGS 16 /* really only 15, but they are numbered 0-3,5-15 */ -#else -#define N_REGS 8 /* really only 7, but they are numbered 0,1,2,3,5,6,7 */ -#endif -#define N_FREGS 6 /* That leaves us two positions on the stack to play with */ - -/* Functions exposed to newcpu, or to what was moved from newcpu.c to - * compemu_support.c */ -extern void compiler_init(void); -extern void compiler_exit(void); -extern bool compiler_use_jit(void); -extern void init_comp(void); -extern void flush(int save_regs); -extern void small_flush(int save_regs); -extern void set_target(uae_u8* t); -extern uae_u8* get_target(void); -extern void freescratch(void); -extern void build_comp(void); -extern void set_cache_state(int enabled); -extern int get_cache_state(void); -extern uae_u32 get_jitted_size(void); -extern void (*flush_icache)(int n); -extern void alloc_cache(void); -extern int check_for_cache_miss(void); - -/* JIT FPU compilation */ -extern void comp_fpp_opp (uae_u32 opcode, uae_u16 extra); -extern void comp_fbcc_opp (uae_u32 opcode); -extern void comp_fscc_opp (uae_u32 opcode, uae_u16 extra); - -extern uae_u32 needed_flags; -extern cacheline cache_tags[]; -extern uae_u8* comp_pc_p; -extern void* pushall_call_handler; - -#define VREGS 32 -#define VFREGS 16 - -#define INMEM 1 -#define CLEAN 2 -#define DIRTY 3 -#define UNDEF 4 -#define ISCONST 5 - -typedef struct { - uae_u32* mem; - uae_u32 val; - uae_u8 is_swapped; - uae_u8 status; - uae_s8 realreg; /* gb-- realreg can hold -1 */ - uae_u8 realind; /* The index in the holds[] array */ - uae_u8 needflush; - uae_u8 validsize; - uae_u8 dirtysize; - uae_u8 dummy; -} reg_status; - -typedef struct { - uae_u32* mem; - double val; - uae_u8 status; - uae_s8 realreg; /* gb-- realreg can hold -1 */ - uae_u8 realind; - uae_u8 needflush; -} freg_status; - -#define PC_P 16 -#define FLAGX 17 -#define FLAGTMP 18 -#define NEXT_HANDLER 19 -#define S1 20 -#define S2 21 -#define S3 22 -#define S4 23 -#define S5 24 -#define S6 25 -#define S7 26 -#define S8 27 -#define S9 28 -#define S10 29 -#define S11 30 -#define S12 31 - -#define FP_RESULT 8 -#define FS1 9 -#define FS2 10 -#define FS3 11 - -typedef struct { - uae_u32 touched; - uae_s8 holds[VREGS]; - uae_u8 nholds; - uae_u8 canbyte; - uae_u8 canword; - uae_u8 locked; -} n_status; - -typedef struct { - uae_u32 touched; - uae_s8 holds[VFREGS]; - uae_u8 nholds; - uae_u8 locked; -} fn_status; - -/* For flag handling */ -#define NADA 1 -#define TRASH 2 -#define VALID 3 - -/* needflush values */ -#define NF_SCRATCH 0 -#define NF_TOMEM 1 -#define NF_HANDLER 2 - -typedef struct { - /* Integer part */ - reg_status state[VREGS]; - n_status nat[N_REGS]; - uae_u32 flags_on_stack; - uae_u32 flags_in_flags; - uae_u32 flags_are_important; - /* FPU part */ - freg_status fate[VFREGS]; - fn_status fat[N_FREGS]; - - /* x86 FPU part */ - uae_s8 spos[N_FREGS]; - uae_s8 onstack[6]; - uae_s8 tos; -} bigstate; - -typedef struct { - /* Integer part */ - char virt[VREGS]; - char nat[N_REGS]; -} smallstate; - -extern bigstate live; -extern int touchcnt; - - -#define IMM uae_s32 -#define R1 uae_u32 -#define R2 uae_u32 -#define R4 uae_u32 -#define W1 uae_u32 -#define W2 uae_u32 -#define W4 uae_u32 -#define RW1 uae_u32 -#define RW2 uae_u32 -#define RW4 uae_u32 -#define MEMR uae_u32 -#define MEMW uae_u32 -#define MEMRW uae_u32 - -#define FW uae_u32 -#define FR uae_u32 -#define FRW uae_u32 - -#define MIDFUNC(nargs,func,args) void func args -#define MENDFUNC(nargs,func,args) -#define COMPCALL(func) func - -#define LOWFUNC(flags,mem,nargs,func,args) static __inline__ void func args -#define LENDFUNC(flags,mem,nargs,func,args) - -/* What we expose to the outside */ -#define DECLARE_MIDFUNC(func) extern void func -DECLARE_MIDFUNC(bt_l_ri(R4 r, IMM i)); -DECLARE_MIDFUNC(bt_l_rr(R4 r, R4 b)); -DECLARE_MIDFUNC(btc_l_ri(RW4 r, IMM i)); -DECLARE_MIDFUNC(btc_l_rr(RW4 r, R4 b)); -DECLARE_MIDFUNC(bts_l_ri(RW4 r, IMM i)); -DECLARE_MIDFUNC(bts_l_rr(RW4 r, R4 b)); -DECLARE_MIDFUNC(btr_l_ri(RW4 r, IMM i)); -DECLARE_MIDFUNC(btr_l_rr(RW4 r, R4 b)); -DECLARE_MIDFUNC(mov_l_rm(W4 d, IMM s)); -DECLARE_MIDFUNC(call_r(R4 r)); -DECLARE_MIDFUNC(sub_l_mi(IMM d, IMM s)); -DECLARE_MIDFUNC(mov_l_mi(IMM d, IMM s)); -DECLARE_MIDFUNC(mov_w_mi(IMM d, IMM s)); -DECLARE_MIDFUNC(mov_b_mi(IMM d, IMM s)); -DECLARE_MIDFUNC(rol_b_ri(RW1 r, IMM i)); -DECLARE_MIDFUNC(rol_w_ri(RW2 r, IMM i)); -DECLARE_MIDFUNC(rol_l_ri(RW4 r, IMM i)); -DECLARE_MIDFUNC(rol_l_rr(RW4 d, R1 r)); -DECLARE_MIDFUNC(rol_w_rr(RW2 d, R1 r)); -DECLARE_MIDFUNC(rol_b_rr(RW1 d, R1 r)); -DECLARE_MIDFUNC(shll_l_rr(RW4 d, R1 r)); -DECLARE_MIDFUNC(shll_w_rr(RW2 d, R1 r)); -DECLARE_MIDFUNC(shll_b_rr(RW1 d, R1 r)); -DECLARE_MIDFUNC(ror_b_ri(R1 r, IMM i)); -DECLARE_MIDFUNC(ror_w_ri(R2 r, IMM i)); -DECLARE_MIDFUNC(ror_l_ri(R4 r, IMM i)); -DECLARE_MIDFUNC(ror_l_rr(R4 d, R1 r)); -DECLARE_MIDFUNC(ror_w_rr(R2 d, R1 r)); -DECLARE_MIDFUNC(ror_b_rr(R1 d, R1 r)); -DECLARE_MIDFUNC(shrl_l_rr(RW4 d, R1 r)); -DECLARE_MIDFUNC(shrl_w_rr(RW2 d, R1 r)); -DECLARE_MIDFUNC(shrl_b_rr(RW1 d, R1 r)); -DECLARE_MIDFUNC(shra_l_rr(RW4 d, R1 r)); -DECLARE_MIDFUNC(shra_w_rr(RW2 d, R1 r)); -DECLARE_MIDFUNC(shra_b_rr(RW1 d, R1 r)); -DECLARE_MIDFUNC(shll_l_ri(RW4 r, IMM i)); -DECLARE_MIDFUNC(shll_w_ri(RW2 r, IMM i)); -DECLARE_MIDFUNC(shll_b_ri(RW1 r, IMM i)); -DECLARE_MIDFUNC(shrl_l_ri(RW4 r, IMM i)); -DECLARE_MIDFUNC(shrl_w_ri(RW2 r, IMM i)); -DECLARE_MIDFUNC(shrl_b_ri(RW1 r, IMM i)); -DECLARE_MIDFUNC(shra_l_ri(RW4 r, IMM i)); -DECLARE_MIDFUNC(shra_w_ri(RW2 r, IMM i)); -DECLARE_MIDFUNC(shra_b_ri(RW1 r, IMM i)); -DECLARE_MIDFUNC(setcc(W1 d, IMM cc)); -DECLARE_MIDFUNC(setcc_m(IMM d, IMM cc)); -DECLARE_MIDFUNC(cmov_b_rr(RW1 d, R1 s, IMM cc)); -DECLARE_MIDFUNC(cmov_w_rr(RW2 d, R2 s, IMM cc)); -DECLARE_MIDFUNC(cmov_l_rr(RW4 d, R4 s, IMM cc)); -DECLARE_MIDFUNC(cmov_l_rm(RW4 d, IMM s, IMM cc)); -DECLARE_MIDFUNC(bsf_l_rr(W4 d, R4 s)); -DECLARE_MIDFUNC(pop_m(IMM d)); -DECLARE_MIDFUNC(push_m(IMM d)); -DECLARE_MIDFUNC(pop_l(W4 d)); -DECLARE_MIDFUNC(push_l_i(IMM i)); -DECLARE_MIDFUNC(push_l(R4 s)); -DECLARE_MIDFUNC(clear_16(RW4 r)); -DECLARE_MIDFUNC(clear_8(RW4 r)); -DECLARE_MIDFUNC(sign_extend_16_rr(W4 d, R2 s)); -DECLARE_MIDFUNC(sign_extend_8_rr(W4 d, R1 s)); -DECLARE_MIDFUNC(zero_extend_16_rr(W4 d, R2 s)); -DECLARE_MIDFUNC(zero_extend_8_rr(W4 d, R1 s)); -DECLARE_MIDFUNC(imul_64_32(RW4 d, RW4 s)); -DECLARE_MIDFUNC(mul_64_32(RW4 d, RW4 s)); -DECLARE_MIDFUNC(imul_32_32(RW4 d, R4 s)); -DECLARE_MIDFUNC(mul_32_32(RW4 d, R4 s)); -DECLARE_MIDFUNC(mov_b_rr(W1 d, R1 s)); -DECLARE_MIDFUNC(mov_w_rr(W2 d, R2 s)); -DECLARE_MIDFUNC(mov_l_rrm_indexed(W4 d,R4 baser, R4 index, IMM factor)); -DECLARE_MIDFUNC(mov_w_rrm_indexed(W2 d, R4 baser, R4 index, IMM factor)); -DECLARE_MIDFUNC(mov_b_rrm_indexed(W1 d, R4 baser, R4 index, IMM factor)); -DECLARE_MIDFUNC(mov_l_mrr_indexed(R4 baser, R4 index, IMM factor, R4 s)); -DECLARE_MIDFUNC(mov_w_mrr_indexed(R4 baser, R4 index, IMM factor, R2 s)); -DECLARE_MIDFUNC(mov_b_mrr_indexed(R4 baser, R4 index, IMM factor, R1 s)); -DECLARE_MIDFUNC(mov_l_bmrr_indexed(IMM base, R4 baser, R4 index, IMM factor, R4 s)); -DECLARE_MIDFUNC(mov_w_bmrr_indexed(IMM base, R4 baser, R4 index, IMM factor, R2 s)); -DECLARE_MIDFUNC(mov_b_bmrr_indexed(IMM base, R4 baser, R4 index, IMM factor, R1 s)); -DECLARE_MIDFUNC(mov_l_brrm_indexed(W4 d, IMM base, R4 baser, R4 index, IMM factor)); -DECLARE_MIDFUNC(mov_w_brrm_indexed(W2 d, IMM base, R4 baser, R4 index, IMM factor)); -DECLARE_MIDFUNC(mov_b_brrm_indexed(W1 d, IMM base, R4 baser, R4 index, IMM factor)); -DECLARE_MIDFUNC(mov_l_rm_indexed(W4 d, IMM base, R4 index, IMM factor)); -DECLARE_MIDFUNC(mov_l_rR(W4 d, R4 s, IMM offset)); -DECLARE_MIDFUNC(mov_w_rR(W2 d, R4 s, IMM offset)); -DECLARE_MIDFUNC(mov_b_rR(W1 d, R4 s, IMM offset)); -DECLARE_MIDFUNC(mov_l_brR(W4 d, R4 s, IMM offset)); -DECLARE_MIDFUNC(mov_w_brR(W2 d, R4 s, IMM offset)); -DECLARE_MIDFUNC(mov_b_brR(W1 d, R4 s, IMM offset)); -DECLARE_MIDFUNC(mov_l_Ri(R4 d, IMM i, IMM offset)); -DECLARE_MIDFUNC(mov_w_Ri(R4 d, IMM i, IMM offset)); -DECLARE_MIDFUNC(mov_b_Ri(R4 d, IMM i, IMM offset)); -DECLARE_MIDFUNC(mov_l_Rr(R4 d, R4 s, IMM offset)); -DECLARE_MIDFUNC(mov_w_Rr(R4 d, R2 s, IMM offset)); -DECLARE_MIDFUNC(mov_b_Rr(R4 d, R1 s, IMM offset)); -DECLARE_MIDFUNC(lea_l_brr(W4 d, R4 s, IMM offset)); -DECLARE_MIDFUNC(lea_l_brr_indexed(W4 d, R4 s, R4 index, IMM factor, IMM offset)); -DECLARE_MIDFUNC(lea_l_rr_indexed(W4 d, R4 s, R4 index, IMM factor)); -DECLARE_MIDFUNC(mov_l_bRr(R4 d, R4 s, IMM offset)); -DECLARE_MIDFUNC(mov_w_bRr(R4 d, R2 s, IMM offset)); -DECLARE_MIDFUNC(mov_b_bRr(R4 d, R1 s, IMM offset)); -DECLARE_MIDFUNC(bswap_32(RW4 r)); -DECLARE_MIDFUNC(bswap_16(RW2 r)); -DECLARE_MIDFUNC(mov_l_rr(W4 d, R4 s)); -DECLARE_MIDFUNC(mov_l_mr(IMM d, R4 s)); -DECLARE_MIDFUNC(mov_w_mr(IMM d, R2 s)); -DECLARE_MIDFUNC(mov_w_rm(W2 d, IMM s)); -DECLARE_MIDFUNC(mov_b_mr(IMM d, R1 s)); -DECLARE_MIDFUNC(mov_b_rm(W1 d, IMM s)); -DECLARE_MIDFUNC(mov_l_ri(W4 d, IMM s)); -DECLARE_MIDFUNC(mov_w_ri(W2 d, IMM s)); -DECLARE_MIDFUNC(mov_b_ri(W1 d, IMM s)); -DECLARE_MIDFUNC(add_l_mi(IMM d, IMM s) ); -DECLARE_MIDFUNC(add_w_mi(IMM d, IMM s) ); -DECLARE_MIDFUNC(add_b_mi(IMM d, IMM s) ); -DECLARE_MIDFUNC(test_l_ri(R4 d, IMM i)); -DECLARE_MIDFUNC(test_l_rr(R4 d, R4 s)); -DECLARE_MIDFUNC(test_w_rr(R2 d, R2 s)); -DECLARE_MIDFUNC(test_b_rr(R1 d, R1 s)); -DECLARE_MIDFUNC(and_l_ri(RW4 d, IMM i)); -DECLARE_MIDFUNC(and_l(RW4 d, R4 s)); -DECLARE_MIDFUNC(and_w(RW2 d, R2 s)); -DECLARE_MIDFUNC(and_b(RW1 d, R1 s)); -DECLARE_MIDFUNC(or_l_rm(RW4 d, IMM s)); -DECLARE_MIDFUNC(or_l_ri(RW4 d, IMM i)); -DECLARE_MIDFUNC(or_l(RW4 d, R4 s)); -DECLARE_MIDFUNC(or_w(RW2 d, R2 s)); -DECLARE_MIDFUNC(or_b(RW1 d, R1 s)); -DECLARE_MIDFUNC(adc_l(RW4 d, R4 s)); -DECLARE_MIDFUNC(adc_w(RW2 d, R2 s)); -DECLARE_MIDFUNC(adc_b(RW1 d, R1 s)); -DECLARE_MIDFUNC(add_l(RW4 d, R4 s)); -DECLARE_MIDFUNC(add_w(RW2 d, R2 s)); -DECLARE_MIDFUNC(add_b(RW1 d, R1 s)); -DECLARE_MIDFUNC(sub_l_ri(RW4 d, IMM i)); -DECLARE_MIDFUNC(sub_w_ri(RW2 d, IMM i)); -DECLARE_MIDFUNC(sub_b_ri(RW1 d, IMM i)); -DECLARE_MIDFUNC(add_l_ri(RW4 d, IMM i)); -DECLARE_MIDFUNC(add_w_ri(RW2 d, IMM i)); -DECLARE_MIDFUNC(add_b_ri(RW1 d, IMM i)); -DECLARE_MIDFUNC(sbb_l(RW4 d, R4 s)); -DECLARE_MIDFUNC(sbb_w(RW2 d, R2 s)); -DECLARE_MIDFUNC(sbb_b(RW1 d, R1 s)); -DECLARE_MIDFUNC(sub_l(RW4 d, R4 s)); -DECLARE_MIDFUNC(sub_w(RW2 d, R2 s)); -DECLARE_MIDFUNC(sub_b(RW1 d, R1 s)); -DECLARE_MIDFUNC(cmp_l(R4 d, R4 s)); -DECLARE_MIDFUNC(cmp_l_ri(R4 r, IMM i)); -DECLARE_MIDFUNC(cmp_w(R2 d, R2 s)); -DECLARE_MIDFUNC(cmp_b(R1 d, R1 s)); -DECLARE_MIDFUNC(xor_l(RW4 d, R4 s)); -DECLARE_MIDFUNC(xor_w(RW2 d, R2 s)); -DECLARE_MIDFUNC(xor_b(RW1 d, R1 s)); -DECLARE_MIDFUNC(live_flags(void)); -DECLARE_MIDFUNC(dont_care_flags(void)); -DECLARE_MIDFUNC(duplicate_carry(void)); -DECLARE_MIDFUNC(restore_carry(void)); -DECLARE_MIDFUNC(start_needflags(void)); -DECLARE_MIDFUNC(end_needflags(void)); -DECLARE_MIDFUNC(make_flags_live(void)); -DECLARE_MIDFUNC(call_r_11(R4 r, W4 out1, R4 in1, IMM osize, IMM isize)); -DECLARE_MIDFUNC(call_r_02(R4 r, R4 in1, R4 in2, IMM isize1, IMM isize2)); -DECLARE_MIDFUNC(forget_about(W4 r)); -DECLARE_MIDFUNC(nop(void)); - -DECLARE_MIDFUNC(f_forget_about(FW r)); -DECLARE_MIDFUNC(fmov_pi(FW r)); -DECLARE_MIDFUNC(fmov_log10_2(FW r)); -DECLARE_MIDFUNC(fmov_log2_e(FW r)); -DECLARE_MIDFUNC(fmov_loge_2(FW r)); -DECLARE_MIDFUNC(fmov_1(FW r)); -DECLARE_MIDFUNC(fmov_0(FW r)); -DECLARE_MIDFUNC(fmov_rm(FW r, MEMR m)); -DECLARE_MIDFUNC(fmovi_rm(FW r, MEMR m)); -DECLARE_MIDFUNC(fmovi_mr(MEMW m, FR r)); -DECLARE_MIDFUNC(fmovs_rm(FW r, MEMR m)); -DECLARE_MIDFUNC(fmovs_mr(MEMW m, FR r)); -DECLARE_MIDFUNC(fmov_mr(MEMW m, FR r)); -DECLARE_MIDFUNC(fmov_ext_mr(MEMW m, FR r)); -DECLARE_MIDFUNC(fmov_ext_rm(FW r, MEMR m)); -DECLARE_MIDFUNC(fmov_rr(FW d, FR s)); -DECLARE_MIDFUNC(fldcw_m_indexed(R4 index, IMM base)); -DECLARE_MIDFUNC(ftst_r(FR r)); -DECLARE_MIDFUNC(dont_care_fflags(void)); -DECLARE_MIDFUNC(fsqrt_rr(FW d, FR s)); -DECLARE_MIDFUNC(fabs_rr(FW d, FR s)); -DECLARE_MIDFUNC(frndint_rr(FW d, FR s)); -DECLARE_MIDFUNC(fsin_rr(FW d, FR s)); -DECLARE_MIDFUNC(fcos_rr(FW d, FR s)); -DECLARE_MIDFUNC(ftwotox_rr(FW d, FR s)); -DECLARE_MIDFUNC(fetox_rr(FW d, FR s)); -DECLARE_MIDFUNC(flog2_rr(FW d, FR s)); -DECLARE_MIDFUNC(fneg_rr(FW d, FR s)); -DECLARE_MIDFUNC(fadd_rr(FRW d, FR s)); -DECLARE_MIDFUNC(fsub_rr(FRW d, FR s)); -DECLARE_MIDFUNC(fmul_rr(FRW d, FR s)); -DECLARE_MIDFUNC(frem_rr(FRW d, FR s)); -DECLARE_MIDFUNC(frem1_rr(FRW d, FR s)); -DECLARE_MIDFUNC(fdiv_rr(FRW d, FR s)); -DECLARE_MIDFUNC(fcmp_rr(FR d, FR s)); -DECLARE_MIDFUNC(fflags_into_flags(W2 tmp)); -#undef DECLARE_MIDFUNC - -extern int failure; -#define FAIL(x) do { failure|=x; } while (0) - -/* Convenience functions exposed to gencomp */ -extern uae_u32 m68k_pc_offset; -extern void readbyte(int address, int dest, int tmp); -extern void readword(int address, int dest, int tmp); -extern void readlong(int address, int dest, int tmp); -extern void writebyte(int address, int source, int tmp); -extern void writeword(int address, int source, int tmp); -extern void writelong(int address, int source, int tmp); -extern void writeword_clobber(int address, int source, int tmp); -extern void writelong_clobber(int address, int source, int tmp); -extern void get_n_addr(int address, int dest, int tmp); -extern void get_n_addr_jmp(int address, int dest, int tmp); -extern void calc_disp_ea_020(int base, uae_u32 dp, int target, int tmp); -/* Set native Z flag only if register is zero */ -extern void set_zero(int r, int tmp); -extern int kill_rodent(int r); -extern void sync_m68k_pc(void); -extern uae_u32 get_const(int r); -extern int is_const(int r); -extern void register_branch(uae_u32 not_taken, uae_u32 taken, uae_u8 cond); - -#define comp_get_ibyte(o) do_get_mem_byte((uae_u8 *)(comp_pc_p + (o) + 1)) -#define comp_get_iword(o) do_get_mem_word((uae_u16 *)(comp_pc_p + (o))) -#define comp_get_ilong(o) do_get_mem_long((uae_u32 *)(comp_pc_p + (o))) - -struct blockinfo_t; - -typedef struct dep_t { - uae_u32* jmp_off; - struct blockinfo_t* target; - struct blockinfo_t* source; - struct dep_t** prev_p; - struct dep_t* next; -} dependency; - -typedef struct checksum_info_t { - uae_u8 *start_p; - uae_u32 length; - struct checksum_info_t *next; -} checksum_info; - -typedef struct blockinfo_t { - uae_s32 count; - cpuop_func* direct_handler_to_use; - cpuop_func* handler_to_use; - /* The direct handler does not check for the correct address */ - - cpuop_func* handler; - cpuop_func* direct_handler; - - cpuop_func* direct_pen; - cpuop_func* direct_pcc; - - uae_u8* pc_p; - - uae_u32 c1; - uae_u32 c2; -#if USE_CHECKSUM_INFO - checksum_info *csi; -#else - uae_u32 len; - uae_u32 min_pcp; -#endif - - struct blockinfo_t* next_same_cl; - struct blockinfo_t** prev_same_cl_p; - struct blockinfo_t* next; - struct blockinfo_t** prev_p; - - uae_u8 optlevel; - uae_u8 needed_flags; - uae_u8 status; - uae_u8 havestate; - - dependency dep[2]; /* Holds things we depend on */ - dependency* deplist; /* List of things that depend on this */ - smallstate env; - -#if JIT_DEBUG - /* (gb) size of the compiled block (direct handler) */ - uae_u32 direct_handler_size; -#endif -} blockinfo; - -#define BI_INVALID 0 -#define BI_ACTIVE 1 -#define BI_NEED_RECOMP 2 -#define BI_NEED_CHECK 3 -#define BI_CHECKING 4 -#define BI_COMPILING 5 -#define BI_FINALIZING 6 - -void execute_normal(void); -void exec_nostats(void); -void do_nothing(void); - -#else - -static __inline__ void flush_icache(int) { } -static __inline__ void build_comp() { } - -#endif /* !USE_JIT */ - -#endif /* COMPEMU_H */ diff --git a/BasiliskII/src/uae_cpu/compiler/compemu_fpp.cpp b/BasiliskII/src/uae_cpu/compiler/compemu_fpp.cpp deleted file mode 100644 index bb536634..00000000 --- a/BasiliskII/src/uae_cpu/compiler/compemu_fpp.cpp +++ /dev/null @@ -1,1637 +0,0 @@ -/* - * compiler/compemu_fpp.cpp - Dynamic translation of FPU instructions - * - * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer - * - * Adaptation for Basilisk II and improvements, copyright 2000-2005 - * Gwenole Beauchesne - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * UAE - The Un*x Amiga Emulator - * - * MC68881 emulation - * - * Copyright 1996 Herman ten Brugge - * Adapted for JIT compilation (c) Bernd Meyer, 2000 - */ - -#include "sysdeps.h" - -#include -#include - -#include "memory.h" -#include "readcpu.h" -#include "newcpu.h" -#include "main.h" -#include "compiler/compemu.h" -#include "fpu/fpu.h" -#include "fpu/flags.h" -#include "fpu/exceptions.h" -#include "fpu/rounding.h" - -#define DEBUG 0 -#include "debug.h" - -// gb-- WARNING: get_fpcr() and set_fpcr() support is experimental -#define HANDLE_FPCR 0 - -// - IEEE-based fpu core must be used -#if defined(FPU_IEEE) -# define CAN_HANDLE_FPCR -#endif - -// - Generic rounding mode and precision modes are supported if set together -#if defined(FPU_USE_GENERIC_ROUNDING_MODE) && defined(FPU_USE_GENERIC_ROUNDING_PRECISION) -# define CAN_HANDLE_FPCR -#endif - -// - X86 rounding mode and precision modes are *not* supported but might work (?!) -#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION) -# define CAN_HANDLE_FPCR -#endif - -#if HANDLE_FPCR && !defined(CAN_HANDLE_FPCR) -# warning "Can't handle FPCR, will FAIL(1) at runtime" -# undef HANDLE_FPCR -# define HANDLE_FPCR 0 -#endif - -#define STATIC_INLINE static inline -#define MAKE_FPSR(r) do { fmov_rr(FP_RESULT,r); } while (0) - -#define delay nop() ;nop() -#define delay2 nop() ;nop() - -#define UNKNOWN_EXTRA 0xFFFFFFFF -static void fpuop_illg(uae_u32 opcode, uae_u32 extra) -{ -/* - if (extra == UNKNOWN_EXTRA) - printf("FPU opcode %x, extra UNKNOWN_EXTRA\n",opcode & 0xFFFF); - else - printf("FPU opcode %x, extra %x\n",opcode & 0xFFFF,extra & 0xFFFF); -*/ - op_illg(opcode); -} - -static uae_s32 temp_fp[4]; /* To convert between FP/integer */ - -/* return register number, or -1 for failure */ -STATIC_INLINE int get_fp_value (uae_u32 opcode, uae_u16 extra) -{ - uaecptr tmppc; - uae_u16 tmp; - int size; - int mode; - int reg; - double* src; - uae_u32 ad = 0; - static int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 }; - static int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 }; - - if ((extra & 0x4000) == 0) { - return ((extra >> 10) & 7); - } - - mode = (opcode >> 3) & 7; - reg = opcode & 7; - size = (extra >> 10) & 7; - switch (mode) { - case 0: - switch (size) { - case 6: - sign_extend_8_rr(S1,reg); - mov_l_mr((uintptr)temp_fp,S1); - delay2; - fmovi_rm(FS1,(uintptr)temp_fp); - return FS1; - case 4: - sign_extend_16_rr(S1,reg); - mov_l_mr((uintptr)temp_fp,S1); - delay2; - fmovi_rm(FS1,(uintptr)temp_fp); - return FS1; - case 0: - mov_l_mr((uintptr)temp_fp,reg); - delay2; - fmovi_rm(FS1,(uintptr)temp_fp); - return FS1; - case 1: - mov_l_mr((uintptr)temp_fp,reg); - delay2; - fmovs_rm(FS1,(uintptr)temp_fp); - return FS1; - default: - return -1; - } - return -1; /* Should be unreachable */ - case 1: - return -1; /* Genuine invalid instruction */ - default: - break; - } - /* OK, we *will* have to load something from an address. Let's make - sure we know how to handle that, or quit early --- i.e. *before* - we do any postincrement/predecrement that we may regret */ - - switch (size) { - case 3: - return -1; - case 0: - case 1: - case 2: - case 4: - case 5: - case 6: - break; - default: - return -1; - } - - switch (mode) { - case 2: - ad=S1; /* We will change it, anyway ;-) */ - mov_l_rr(ad,reg+8); - break; - case 3: - ad=S1; - mov_l_rr(ad,reg+8); - lea_l_brr(reg+8,reg+8,(reg == 7?sz2[size]:sz1[size])); - break; - case 4: - ad=S1; - - lea_l_brr(reg+8,reg+8,-(reg == 7?sz2[size]:sz1[size])); - mov_l_rr(ad,reg+8); - break; - case 5: - { - uae_u32 off=(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); - ad=S1; - mov_l_rr(ad,reg+8); - lea_l_brr(ad,ad,off); - break; - } - case 6: - { - uae_u32 dp=comp_get_iword((m68k_pc_offset+=2)-2); - ad=S1; - calc_disp_ea_020(reg+8,dp,ad,S2); - break; - } - case 7: - switch (reg) { - case 0: - { - uae_u32 off=(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); - ad=S1; - mov_l_ri(ad,off); - break; - } - case 1: - { - uae_u32 off=comp_get_ilong((m68k_pc_offset+=4)-4); - ad=S1; - mov_l_ri(ad,off); - break; - } - case 2: - { - uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+ - m68k_pc_offset; - uae_s32 PC16off =(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2) --2); - ad=S1; - mov_l_ri(ad,address+PC16off); - break; - } - case 3: - return -1; - tmppc = m68k_getpc (); - tmp = next_iword (); - ad = get_disp_ea_020 (tmppc, tmp); - break; - case 4: - { - uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+ m68k_pc_offset; - ad=S1; - // Immediate addressing mode && Operation Length == Byte -> - // Use the low-order byte of the extension word. - if (size == 6) address++; - mov_l_ri(ad,address); - m68k_pc_offset+=sz2[size]; - break; - } - default: - return -1; - } - } - - switch (size) { - case 0: - readlong(ad,S2,S3); - mov_l_mr((uintptr)temp_fp,S2); - delay2; - fmovi_rm(FS1,(uintptr)temp_fp); - break; - case 1: - readlong(ad,S2,S3); - mov_l_mr((uintptr)temp_fp,S2); - delay2; - fmovs_rm(FS1,(uintptr)temp_fp); - break; - case 2: - readword(ad,S2,S3); - mov_w_mr(((uintptr)temp_fp)+8,S2); - add_l_ri(ad,4); - readlong(ad,S2,S3); - mov_l_mr((uintptr)(temp_fp)+4,S2); - add_l_ri(ad,4); - readlong(ad,S2,S3); - mov_l_mr((uintptr)(temp_fp),S2); - delay2; - fmov_ext_rm(FS1,(uintptr)(temp_fp)); - break; - case 3: - return -1; /* Some silly "packed" stuff */ - case 4: - readword(ad,S2,S3); - sign_extend_16_rr(S2,S2); - mov_l_mr((uintptr)temp_fp,S2); - delay2; - fmovi_rm(FS1,(uintptr)temp_fp); - break; - case 5: - readlong(ad,S2,S3); - mov_l_mr(((uintptr)temp_fp)+4,S2); - add_l_ri(ad,4); - readlong(ad,S2,S3); - mov_l_mr((uintptr)(temp_fp),S2); - delay2; - fmov_rm(FS1,(uintptr)(temp_fp)); - break; - case 6: - readbyte(ad,S2,S3); - sign_extend_8_rr(S2,S2); - mov_l_mr((uintptr)temp_fp,S2); - delay2; - fmovi_rm(FS1,(uintptr)temp_fp); - break; - default: - return -1; - } - return FS1; -} - -/* return of -1 means failure, >=0 means OK */ -STATIC_INLINE int put_fp_value (int val, uae_u32 opcode, uae_u16 extra) -{ - uae_u16 tmp; - uaecptr tmppc; - int size; - int mode; - int reg; - uae_u32 ad; - static int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 }; - static int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 }; - - if ((extra & 0x4000) == 0) { - const int dest_reg = (extra >> 10) & 7; - fmov_rr(dest_reg, val); - // gb-- status register is affected - MAKE_FPSR(dest_reg); - return 0; - } - - mode = (opcode >> 3) & 7; - reg = opcode & 7; - size = (extra >> 10) & 7; - ad = (uae_u32)-1; - switch (mode) { - case 0: - switch (size) { - case 6: - fmovi_mr((uintptr)temp_fp,val); - delay; - mov_b_rm(reg,(uintptr)temp_fp); - return 0; - case 4: - fmovi_mr((uintptr)temp_fp,val); - delay; - mov_w_rm(reg,(uintptr)temp_fp); - return 0; - case 0: - fmovi_mr((uintptr)temp_fp,val); - delay; - mov_l_rm(reg,(uintptr)temp_fp); - return 0; - case 1: - fmovs_mr((uintptr)temp_fp,val); - delay; - mov_l_rm(reg,(uintptr)temp_fp); - return 0; - default: - return -1; - } - case 1: - return -1; /* genuine invalid instruction */ - default: break; - } - - /* Let's make sure we get out *before* doing something silly if - we can't handle the size */ - switch (size) { - case 0: - case 4: - case 5: - case 6: - case 2: - case 1: - break; - case 3: - default: - return -1; - } - - switch (mode) { - case 2: - ad=S1; - mov_l_rr(ad,reg+8); - break; - case 3: - ad=S1; - mov_l_rr(ad,reg+8); - lea_l_brr(reg+8,reg+8,(reg == 7?sz2[size]:sz1[size])); - break; - case 4: - ad=S1; - lea_l_brr(reg+8,reg+8,-(reg == 7?sz2[size]:sz1[size])); - mov_l_rr(ad,reg+8); - break; - case 5: - { - uae_u32 off=(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); - ad=S1; - mov_l_rr(ad,reg+8); - add_l_ri(ad,off); - break; - } - case 6: - { - uae_u32 dp=comp_get_iword((m68k_pc_offset+=2)-2); - ad=S1; - calc_disp_ea_020(reg+8,dp,ad,S2); - break; - } - case 7: - switch (reg) { - case 0: - { - uae_u32 off=(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); - ad=S1; - mov_l_ri(ad,off); - break; - } - case 1: - { - uae_u32 off=comp_get_ilong((m68k_pc_offset+=4)-4); - ad=S1; - mov_l_ri(ad,off); - break; - } - case 2: - { - uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+ - m68k_pc_offset; - uae_s32 PC16off =(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); - ad=S1; - mov_l_ri(ad,address+PC16off); - break; - } - case 3: - return -1; - tmppc = m68k_getpc (); - tmp = next_iword (); - ad = get_disp_ea_020 (tmppc, tmp); - break; - case 4: - { - uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+ - m68k_pc_offset; - ad=S1; - mov_l_ri(ad,address); - m68k_pc_offset+=sz2[size]; - break; - } - default: - return -1; - } - } - switch (size) { - case 0: - fmovi_mr((uintptr)temp_fp,val); - delay; - mov_l_rm(S2,(uintptr)temp_fp); - writelong_clobber(ad,S2,S3); - break; - case 1: - fmovs_mr((uintptr)temp_fp,val); - delay; - mov_l_rm(S2,(uintptr)temp_fp); - writelong_clobber(ad,S2,S3); - break; - case 2: - fmov_ext_mr((uintptr)temp_fp,val); - delay; - mov_w_rm(S2,(uintptr)temp_fp+8); - writeword_clobber(ad,S2,S3); - add_l_ri(ad,4); - mov_l_rm(S2,(uintptr)temp_fp+4); - writelong_clobber(ad,S2,S3); - add_l_ri(ad,4); - mov_l_rm(S2,(uintptr)temp_fp); - writelong_clobber(ad,S2,S3); - break; - case 3: return -1; /* Packed */ - - case 4: - fmovi_mr((uintptr)temp_fp,val); - delay; - mov_l_rm(S2,(uintptr)temp_fp); - writeword_clobber(ad,S2,S3); - break; - case 5: - fmov_mr((uintptr)temp_fp,val); - delay; - mov_l_rm(S2,(uintptr)temp_fp+4); - writelong_clobber(ad,S2,S3); - add_l_ri(ad,4); - mov_l_rm(S2,(uintptr)temp_fp); - writelong_clobber(ad,S2,S3); - break; - case 6: - fmovi_mr((uintptr)temp_fp,val); - delay; - mov_l_rm(S2,(uintptr)temp_fp); - writebyte(ad,S2,S3); - break; - default: - return -1; - } - return 0; -} - -/* return -1 for failure, or register number for success */ -STATIC_INLINE int get_fp_ad (uae_u32 opcode, uae_u32 * ad) -{ - uae_u16 tmp; - uaecptr tmppc; - int mode; - int reg; - uae_s32 off; - - mode = (opcode >> 3) & 7; - reg = opcode & 7; - switch (mode) { - case 0: - case 1: - return -1; - case 2: - case 3: - case 4: - mov_l_rr(S1,8+reg); - return S1; - *ad = m68k_areg (regs, reg); - break; - case 5: - off=(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); - - mov_l_rr(S1,8+reg); - add_l_ri(S1,off); - return S1; - case 6: - return -1; - break; - case 7: - switch (reg) { - case 0: - off=(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); - mov_l_ri(S1,off); - return S1; - case 1: - off=comp_get_ilong((m68k_pc_offset+=4)-4); - mov_l_ri(S1,off); - return S1; - case 2: - return -1; -// *ad = m68k_getpc (); -// *ad += (uae_s32) (uae_s16) next_iword (); - off=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset; - off+=(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); - mov_l_ri(S1,off); - return S1; - case 3: - return -1; - tmppc = m68k_getpc (); - tmp = next_iword (); - *ad = get_disp_ea_020 (tmppc, tmp); - break; - default: - return -1; - } - } - abort(); -} - -void comp_fdbcc_opp (uae_u32 opcode, uae_u16 extra) -{ - FAIL(1); - return; -} - -void comp_fscc_opp (uae_u32 opcode, uae_u16 extra) -{ - uae_u32 ad; - int cc; - int reg; - -#if DEBUG_FPP - printf ("fscc_opp at %08lx\n", m68k_getpc ()); - fflush (stdout); -#endif - - - if (extra&0x20) { /* only cc from 00 to 1f are defined */ - FAIL(1); - return; - } - if ((opcode & 0x38) != 0) { /* We can only do to integer register */ - FAIL(1); - return; - } - - fflags_into_flags(S2); - reg=(opcode&7); - - mov_l_ri(S1,255); - mov_l_ri(S4,0); - switch(extra&0x0f) { /* according to fpp.c, the 0x10 bit is ignored - */ - case 0: break; /* set never */ - case 1: mov_l_rr(S2,S4); - cmov_l_rr(S4,S1,4); - cmov_l_rr(S4,S2,10); break; - case 2: cmov_l_rr(S4,S1,7); break; - case 3: cmov_l_rr(S4,S1,3); break; - case 4: mov_l_rr(S2,S4); - cmov_l_rr(S4,S1,2); - cmov_l_rr(S4,S2,10); break; - case 5: mov_l_rr(S2,S4); - cmov_l_rr(S4,S1,6); - cmov_l_rr(S4,S2,10); break; - case 6: cmov_l_rr(S4,S1,5); break; - case 7: cmov_l_rr(S4,S1,11); break; - case 8: cmov_l_rr(S4,S1,10); break; - case 9: cmov_l_rr(S4,S1,4); break; - case 10: cmov_l_rr(S4,S1,10); cmov_l_rr(S4,S1,7); break; - case 11: cmov_l_rr(S4,S1,4); cmov_l_rr(S4,S1,3); break; - case 12: cmov_l_rr(S4,S1,2); break; - case 13: cmov_l_rr(S4,S1,6); break; - case 14: cmov_l_rr(S4,S1,5); cmov_l_rr(S4,S1,10); break; - case 15: mov_l_rr(S4,S1); break; - } - - if ((opcode & 0x38) == 0) { - mov_b_rr(reg,S4); - } else { - abort(); - if (get_fp_ad (opcode, &ad) == 0) { - m68k_setpc (m68k_getpc () - 4); - fpuop_illg (opcode,extra); - } else - put_byte (ad, cc ? 0xff : 0x00); - } -} - -void comp_ftrapcc_opp (uae_u32 opcode, uaecptr oldpc) -{ - int cc; - - FAIL(1); - return; -} - -void comp_fbcc_opp (uae_u32 opcode) -{ - uae_u32 start_68k_offset=m68k_pc_offset; - uae_u32 off; - uae_u32 v1; - uae_u32 v2; - uae_u32 nh; - int cc; - - // comp_pc_p is expected to be bound to 32-bit addresses - assert((uintptr)comp_pc_p <= 0xffffffffUL); - - if (opcode&0x20) { /* only cc from 00 to 1f are defined */ - FAIL(1); - return; - } - if ((opcode&0x40)==0) { - off=(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); - } - else { - off=comp_get_ilong((m68k_pc_offset+=4)-4); - } - mov_l_ri(S1,(uintptr) - (comp_pc_p+off-(m68k_pc_offset-start_68k_offset))); - mov_l_ri(PC_P,(uintptr)comp_pc_p); - - /* Now they are both constant. Might as well fold in m68k_pc_offset */ - add_l_ri(S1,m68k_pc_offset); - add_l_ri(PC_P,m68k_pc_offset); - m68k_pc_offset=0; - - /* according to fpp.c, the 0x10 bit is ignored - (it handles exception handling, which we don't - do, anyway ;-) */ - cc=opcode&0x0f; - v1=get_const(PC_P); - v2=get_const(S1); - fflags_into_flags(S2); - - switch(cc) { - case 0: break; /* jump never */ - case 1: - mov_l_rr(S2,PC_P); - cmov_l_rr(PC_P,S1,4); - cmov_l_rr(PC_P,S2,10); break; - case 2: register_branch(v1,v2,7); break; - case 3: register_branch(v1,v2,3); break; - case 4: - mov_l_rr(S2,PC_P); - cmov_l_rr(PC_P,S1,2); - cmov_l_rr(PC_P,S2,10); break; - case 5: - mov_l_rr(S2,PC_P); - cmov_l_rr(PC_P,S1,6); - cmov_l_rr(PC_P,S2,10); break; - case 6: register_branch(v1,v2,5); break; - case 7: register_branch(v1,v2,11); break; - case 8: register_branch(v1,v2,10); break; - case 9: register_branch(v1,v2,4); break; - case 10: - cmov_l_rr(PC_P,S1,10); - cmov_l_rr(PC_P,S1,7); break; - case 11: - cmov_l_rr(PC_P,S1,4); - cmov_l_rr(PC_P,S1,3); break; - case 12: register_branch(v1,v2,2); break; - case 13: register_branch(v1,v2,6); break; - case 14: - cmov_l_rr(PC_P,S1,5); - cmov_l_rr(PC_P,S1,10); break; - case 15: mov_l_rr(PC_P,S1); break; - } -} - - /* Floating point conditions - The "NotANumber" part could be problematic; Howver, when NaN is - encountered, the ftst instruction sets bot N and Z to 1 on the x87, - so quite often things just fall into place. This is probably not - accurate wrt the 68k FPU, but it is *as* accurate as this was before. - However, some more thought should go into fixing this stuff up so - it accurately emulates the 68k FPU. ->==> 13) & 0x7) { - case 3: /* 2nd most common */ - if (put_fp_value ((extra >> 7)&7 , opcode, extra) < 0) { - FAIL(1); - return; - - } - return; - case 6: - case 7: - { - uae_u32 ad, list = 0; - int incr = 0; - if (extra & 0x2000) { - uae_u32 ad; - - /* FMOVEM FPP->memory */ - switch ((extra >> 11) & 3) { /* Get out early if failure */ - case 0: - case 2: - break; - case 1: - case 3: - default: - FAIL(1); return; - } - ad=get_fp_ad (opcode, &ad); - if (ad<0) { - abort(); - m68k_setpc (m68k_getpc () - 4); - fpuop_illg (opcode,extra); - return; - } - switch ((extra >> 11) & 3) { - case 0: /* static pred */ - list = extra & 0xff; - incr = -1; - break; - case 2: /* static postinc */ - list = extra & 0xff; - incr = 1; - break; - case 1: /* dynamic pred */ - case 3: /* dynamic postinc */ - abort(); - } - if (incr < 0) { /* Predecrement */ - for (reg = 7; reg >= 0; reg--) { - if (list & 0x80) { - fmov_ext_mr((uintptr)temp_fp,reg); - delay; - sub_l_ri(ad,4); - mov_l_rm(S2,(uintptr)temp_fp); - writelong_clobber(ad,S2,S3); - sub_l_ri(ad,4); - mov_l_rm(S2,(uintptr)temp_fp+4); - writelong_clobber(ad,S2,S3); - sub_l_ri(ad,4); - mov_w_rm(S2,(uintptr)temp_fp+8); - writeword_clobber(ad,S2,S3); - } - list <<= 1; - } - } - else { /* Postincrement */ - for (reg = 0; reg < 8; reg++) { - if (list & 0x80) { - fmov_ext_mr((uintptr)temp_fp,reg); - delay; - mov_w_rm(S2,(uintptr)temp_fp+8); - writeword_clobber(ad,S2,S3); - add_l_ri(ad,4); - mov_l_rm(S2,(uintptr)temp_fp+4); - writelong_clobber(ad,S2,S3); - add_l_ri(ad,4); - mov_l_rm(S2,(uintptr)temp_fp); - writelong_clobber(ad,S2,S3); - add_l_ri(ad,4); - } - list <<= 1; - } - } - if ((opcode & 0x38) == 0x18) - mov_l_rr((opcode & 7)+8,ad); - if ((opcode & 0x38) == 0x20) - mov_l_rr((opcode & 7)+8,ad); - } else { - /* FMOVEM memory->FPP */ - - uae_u32 ad; - switch ((extra >> 11) & 3) { /* Get out early if failure */ - case 0: - case 2: - break; - case 1: - case 3: - default: - FAIL(1); return; - } - ad=get_fp_ad (opcode, &ad); - if (ad<0) { - abort(); - m68k_setpc (m68k_getpc () - 4); - write_log("no ad\n"); - fpuop_illg (opcode,extra); - return; - } - switch ((extra >> 11) & 3) { - case 0: /* static pred */ - list = extra & 0xff; - incr = -1; - break; - case 2: /* static postinc */ - list = extra & 0xff; - incr = 1; - break; - case 1: /* dynamic pred */ - case 3: /* dynamic postinc */ - abort(); - } - - if (incr < 0) { - // not reached - for (reg = 7; reg >= 0; reg--) { - uae_u32 wrd1, wrd2, wrd3; - if (list & 0x80) { - sub_l_ri(ad,4); - readlong(ad,S2,S3); - mov_l_mr((uintptr)(temp_fp),S2); - sub_l_ri(ad,4); - readlong(ad,S2,S3); - mov_l_mr((uintptr)(temp_fp)+4,S2); - sub_l_ri(ad,4); - readword(ad,S2,S3); - mov_w_mr(((uintptr)temp_fp)+8,S2); - delay2; - fmov_ext_rm(reg,(uintptr)(temp_fp)); - } - list <<= 1; - } - } - else { - for (reg = 0; reg < 8; reg++) { - uae_u32 wrd1, wrd2, wrd3; - if (list & 0x80) { - readword(ad,S2,S3); - mov_w_mr(((uintptr)temp_fp)+8,S2); - add_l_ri(ad,4); - readlong(ad,S2,S3); - mov_l_mr((uintptr)(temp_fp)+4,S2); - add_l_ri(ad,4); - readlong(ad,S2,S3); - mov_l_mr((uintptr)(temp_fp),S2); - add_l_ri(ad,4); - delay2; - fmov_ext_rm(reg,(uintptr)(temp_fp)); - } - list <<= 1; - } - } - if ((opcode & 0x38) == 0x18) - mov_l_rr((opcode & 7)+8,ad); - if ((opcode & 0x38) == 0x20) - mov_l_rr((opcode & 7)+8,ad); - } - } - return; - - case 4: - case 5: /* rare */ - if ((opcode & 0x30) == 0) { - if (extra & 0x2000) { - if (extra & 0x1000) { -#if HANDLE_FPCR - mov_l_rm(opcode & 15, (uintptr)&fpu.fpcr.rounding_mode); - or_l_rm(opcode & 15, (uintptr)&fpu.fpcr.rounding_precision); -#else - FAIL(1); - return; -#endif - } - if (extra & 0x0800) { - FAIL(1); - return; - } - if (extra & 0x0400) { - mov_l_rm(opcode & 15,(uintptr)&fpu.instruction_address); - return; - } - } else { - // gb-- moved here so that we may FAIL() without generating any code - if (extra & 0x0800) { - // set_fpsr(m68k_dreg (regs, opcode & 15)); - FAIL(1); - return; - } - if (extra & 0x1000) { -#if HANDLE_FPCR -#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION) - FAIL(1); - return; -#endif - mov_l_rr(S1,opcode & 15); - mov_l_rr(S2,opcode & 15); - and_l_ri(S1,FPCR_ROUNDING_PRECISION); - and_l_ri(S2,FPCR_ROUNDING_MODE); - mov_l_mr((uintptr)&fpu.fpcr.rounding_precision,S1); - mov_l_mr((uintptr)&fpu.fpcr.rounding_mode,S2); -#else - FAIL(1); - return; -#endif -// return; gb-- FMOVEM could also operate on fpiar - } - if (extra & 0x0400) { - mov_l_mr((uintptr)&fpu.instruction_address,opcode & 15); -// return; gb-- we have to process all FMOVEM bits before returning - } - return; - } - } else if ((opcode & 0x3f) == 0x3c) { - if ((extra & 0x2000) == 0) { - // gb-- moved here so that we may FAIL() without generating any code - if (extra & 0x0800) { - FAIL(1); - return; - } - if (extra & 0x1000) { - uae_u32 val=comp_get_ilong((m68k_pc_offset+=4)-4); -#if HANDLE_FPCR -#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION) - FAIL(1); - return; -#endif -// mov_l_mi((uintptr)®s.fpcr,val); - mov_l_ri(S1,val); - mov_l_ri(S2,val); - and_l_ri(S1,FPCR_ROUNDING_PRECISION); - and_l_ri(S2,FPCR_ROUNDING_MODE); - mov_l_mr((uintptr)&fpu.fpcr.rounding_precision,S1); - mov_l_mr((uintptr)&fpu.fpcr.rounding_mode,S2); -#else - FAIL(1); - return; -#endif -// return; gb-- FMOVEM could also operate on fpiar - } - if (extra & 0x0400) { - uae_u32 val=comp_get_ilong((m68k_pc_offset+=4)-4); - mov_l_mi((uintptr)&fpu.instruction_address,val); -// return; gb-- we have to process all FMOVEM bits before returning - } - return; - } - FAIL(1); - return; - } else if (extra & 0x2000) { - FAIL(1); - return; - } else { - FAIL(1); - return; - } - FAIL(1); - return; - - case 0: - case 2: /* Extremely common */ - reg = (extra >> 7) & 7; - if ((extra & 0xfc00) == 0x5c00) { - switch (extra & 0x7f) { - case 0x00: - fmov_pi(reg); - break; - case 0x0b: - fmov_log10_2(reg); - break; - case 0x0c: -#if USE_LONG_DOUBLE - fmov_ext_rm(reg,(uintptr)&const_e); -#else - fmov_rm(reg,(uintptr)&const_e); -#endif - break; - case 0x0d: - fmov_log2_e(reg); - break; - case 0x0e: -#if USE_LONG_DOUBLE - fmov_ext_rm(reg,(uintptr)&const_log10_e); -#else - fmov_rm(reg,(uintptr)&const_log10_e); -#endif - break; - case 0x0f: - fmov_0(reg); - break; - case 0x30: - fmov_loge_2(reg); - break; - case 0x31: -#if USE_LONG_DOUBLE - fmov_ext_rm(reg,(uintptr)&const_loge_10); -#else - fmov_rm(reg,(uintptr)&const_loge_10); -#endif - break; - case 0x32: - fmov_1(reg); - break; - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3a: - case 0x3b: -#if USE_LONG_DOUBLE - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - fmov_ext_rm(reg,(uintptr)(power10+(extra & 0x7f)-0x32)); -#else - fmov_rm(reg,(uintptr)(power10+(extra & 0x7f)-0x32)); -#endif - break; - default: - /* This is not valid, so we fail */ - FAIL(1); - return; - } - return; - } - - switch (extra & 0x7f) { - case 0x00: /* FMOVE */ - case 0x40: /* Explicit rounding. This is just a quick fix. Same - * for all other cases that have three choices */ - case 0x44: - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fmov_rr(reg,src); - MAKE_FPSR (src); - break; - case 0x01: /* FINT */ - FAIL(1); - return; - dont_care_fflags(); - case 0x02: /* FSINH */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x03: /* FINTRZ */ -#if USE_X86_FPUCW - /* If we have control over the CW, we can do this */ - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - mov_l_ri(S1,16); /* Switch to "round to zero" mode */ - fldcw_m_indexed(S1,(uae_u32)x86_fpucw); - - frndint_rr(reg,src); - - /* restore control word */ - mov_l_rm(S1,(uintptr)®s.fpcr); - and_l_ri(S1,0x000000f0); - fldcw_m_indexed(S1,(uintptr)x86_fpucw); - - MAKE_FPSR (reg); - break; -#endif - FAIL(1); - return; - break; - case 0x04: /* FSQRT */ - case 0x41: - case 0x45: - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fsqrt_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x06: /* FLOGNP1 */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x08: /* FETOXM1 */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x09: /* FTANH */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x0a: /* FATAN */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x0c: /* FASIN */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x0d: /* FATANH */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x0e: /* FSIN */ - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fsin_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x0f: /* FTAN */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x10: /* FETOX */ - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fetox_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x11: /* FTWOTOX */ - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - ftwotox_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x12: /* FTENTOX */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x14: /* FLOGN */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x15: /* FLOG10 */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x16: /* FLOG2 */ - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - flog2_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x18: /* FABS */ - case 0x58: - case 0x5c: - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fabs_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x19: /* FCOSH */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x1a: /* FNEG */ - case 0x5a: - case 0x5e: - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fneg_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x1c: /* FACOS */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x1d: /* FCOS */ - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fcos_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x1e: /* FGETEXP */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x1f: /* FGETMAN */ - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x20: /* FDIV */ - case 0x60: - case 0x64: - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fdiv_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x21: /* FMOD */ - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - frem_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x22: /* FADD */ - case 0x62: - case 0x66: - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fadd_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x23: /* FMUL */ - case 0x63: - case 0x67: - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fmul_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x24: /* FSGLDIV */ - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fdiv_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x25: /* FREM */ - // gb-- disabled because the quotient byte must be computed - // otherwise, free rotation in ClarisWorks doesn't work. - FAIL(1); - return; - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - frem1_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x26: /* FSCALE */ - dont_care_fflags(); - FAIL(1); - return; - break; - case 0x27: /* FSGLMUL */ - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fmul_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x28: /* FSUB */ - case 0x68: - case 0x6c: - dont_care_fflags(); - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fsub_rr(reg,src); - MAKE_FPSR (reg); - break; - case 0x30: /* FSINCOS */ - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - FAIL(1); - return; - dont_care_fflags(); - break; - case 0x38: /* FCMP */ - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fmov_rr(FP_RESULT,reg); - fsub_rr(FP_RESULT,src); /* Right way? */ - break; - case 0x3a: /* FTST */ - src=get_fp_value (opcode, extra); - if (src < 0) { - FAIL(1); /* Illegal instruction */ - return; - } - fmov_rr(FP_RESULT,src); - break; - default: - FAIL(1); - return; - break; - } - return; - } - m68k_setpc (m68k_getpc () - 4); - fpuop_illg (opcode,extra); -} diff --git a/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp b/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp deleted file mode 100644 index f31febce..00000000 --- a/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp +++ /dev/null @@ -1,7129 +0,0 @@ -/* - * compiler/compemu_support.cpp - Core dynamic translation engine - * - * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer - * - * Adaptation for Basilisk II and improvements, copyright 2000-2005 - * Gwenole Beauchesne - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING -#error "Only Real or Direct Addressing is supported with the JIT Compiler" -#endif - -#if X86_ASSEMBLY && !SAHF_SETO_PROFITABLE -#error "Only [LS]AHF scheme to [gs]et flags is supported with the JIT Compiler" -#endif - -/* NOTE: support for AMD64 assumes translation cache and other code - * buffers are allocated into a 32-bit address space because (i) B2/JIT - * code is not 64-bit clean and (ii) it's faster to resolve branches - * that way. - */ -#if !defined(__i386__) && !defined(__x86_64__) -#error "Only IA-32 and X86-64 targets are supported with the JIT Compiler" -#endif - -#define USE_MATCH 0 - -/* kludge for Brian, so he can compile under MSVC++ */ -#define USE_NORMAL_CALLING_CONVENTION 1 && defined(_MSC_VER) - -#ifndef WIN32 -#include -#include -#include -#endif - -#include -#include -#include - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "vm_alloc.h" - -#include "m68k.h" -#include "memory.h" -#include "readcpu.h" -#include "newcpu.h" -#include "comptbl.h" -#include "compiler/compemu.h" -#include "fpu/fpu.h" -#include "fpu/flags.h" - -#define DEBUG 1 -#include "debug.h" - -#ifdef ENABLE_MON -#include "mon.h" -#endif - -#ifndef WIN32 -#define PROFILE_COMPILE_TIME 1 -#define PROFILE_UNTRANSLATED_INSNS 1 -#endif - -#if defined(__x86_64__) && 0 -#define RECORD_REGISTER_USAGE 1 -#endif - -#ifdef WIN32 -#undef write_log -#define write_log dummy_write_log -static void dummy_write_log(const char *, ...) { } -#endif - -#if JIT_DEBUG -#undef abort -#define abort() do { \ - fprintf(stderr, "Abort in file %s at line %d\n", __FILE__, __LINE__); \ - exit(EXIT_FAILURE); \ -} while (0) -#endif - -#if RECORD_REGISTER_USAGE -static uint64 reg_count[16]; -static int reg_count_local[16]; - -static int reg_count_compare(const void *ap, const void *bp) -{ - const int a = *((int *)ap); - const int b = *((int *)bp); - return reg_count[b] - reg_count[a]; -} -#endif - -#if PROFILE_COMPILE_TIME -#include -static uae_u32 compile_count = 0; -static clock_t compile_time = 0; -static clock_t emul_start_time = 0; -static clock_t emul_end_time = 0; -#endif - -#if PROFILE_UNTRANSLATED_INSNS -const int untranslated_top_ten = 20; -static uae_u32 raw_cputbl_count[65536] = { 0, }; -static uae_u16 opcode_nums[65536]; - -static int untranslated_compfn(const void *e1, const void *e2) -{ - return raw_cputbl_count[*(const uae_u16 *)e1] < raw_cputbl_count[*(const uae_u16 *)e2]; -} -#endif - -static compop_func *compfunctbl[65536]; -static compop_func *nfcompfunctbl[65536]; -static cpuop_func *nfcpufunctbl[65536]; -uae_u8* comp_pc_p; - -// From newcpu.cpp -extern bool quit_program; - -// gb-- Extra data for Basilisk II/JIT -#if JIT_DEBUG -static bool JITDebug = false; // Enable runtime disassemblers through mon? -#else -const bool JITDebug = false; // Don't use JIT debug mode at all -#endif -#if USE_INLINING -static bool follow_const_jumps = true; // Flag: translation through constant jumps -#else -const bool follow_const_jumps = false; -#endif - -const uae_u32 MIN_CACHE_SIZE = 1024; // Minimal translation cache size (1 MB) -static uae_u32 cache_size = 0; // Size of total cache allocated for compiled blocks -static uae_u32 current_cache_size = 0; // Cache grows upwards: how much has been consumed already -static bool lazy_flush = true; // Flag: lazy translation cache invalidation -static bool avoid_fpu = true; // Flag: compile FPU instructions ? -static bool have_cmov = false; // target has CMOV instructions ? -static bool have_lahf_lm = true; // target has LAHF supported in long mode ? -static bool have_rat_stall = true; // target has partial register stalls ? -const bool tune_alignment = true; // Tune code alignments for running CPU ? -const bool tune_nop_fillers = true; // Tune no-op fillers for architecture -static bool setzflg_uses_bsf = false; // setzflg virtual instruction can use native BSF instruction correctly? -static int align_loops = 32; // Align the start of loops -static int align_jumps = 32; // Align the start of jumps -static int optcount[10] = { - 10, // How often a block has to be executed before it is translated - 0, // How often to use naive translation - 0, 0, 0, 0, - -1, -1, -1, -1 -}; - -struct op_properties { - uae_u8 use_flags; - uae_u8 set_flags; - uae_u8 is_addx; - uae_u8 cflow; -}; -static op_properties prop[65536]; - -static inline int end_block(uae_u32 opcode) -{ - return (prop[opcode].cflow & fl_end_block); -} - -static inline bool is_const_jump(uae_u32 opcode) -{ - return (prop[opcode].cflow == fl_const_jump); -} - -static inline bool may_trap(uae_u32 opcode) -{ - return (prop[opcode].cflow & fl_trap) != 0; -} - -static inline unsigned int cft_map (unsigned int f) -{ -#ifndef HAVE_GET_WORD_UNSWAPPED - return f; -#else - return ((f >> 8) & 255) | ((f & 255) << 8); -#endif -} - -uae_u8* start_pc_p; -uae_u32 start_pc; -uae_u32 current_block_pc_p; -static uintptr current_block_start_target; -uae_u32 needed_flags; -static uintptr next_pc_p; -static uintptr taken_pc_p; -static int branch_cc; -static int redo_current_block; - -int segvcount=0; -int soft_flush_count=0; -int hard_flush_count=0; -int checksum_count=0; -static uae_u8* current_compile_p=NULL; -static uae_u8* max_compile_start; -static uae_u8* compiled_code=NULL; -static uae_s32 reg_alloc_run; -const int POPALLSPACE_SIZE = 1024; /* That should be enough space */ -static uae_u8* popallspace=NULL; - -void* pushall_call_handler=NULL; -static void* popall_do_nothing=NULL; -static void* popall_exec_nostats=NULL; -static void* popall_execute_normal=NULL; -static void* popall_cache_miss=NULL; -static void* popall_recompile_block=NULL; -static void* popall_check_checksum=NULL; - -/* The 68k only ever executes from even addresses. So right now, we - * waste half the entries in this array - * UPDATE: We now use those entries to store the start of the linked - * lists that we maintain for each hash result. - */ -cacheline cache_tags[TAGSIZE]; -int letit=0; -blockinfo* hold_bi[MAX_HOLD_BI]; -blockinfo* active; -blockinfo* dormant; - -/* 68040 */ -extern struct cputbl op_smalltbl_0_nf[]; -extern struct comptbl op_smalltbl_0_comp_nf[]; -extern struct comptbl op_smalltbl_0_comp_ff[]; - -/* 68020 + 68881 */ -extern struct cputbl op_smalltbl_1_nf[]; - -/* 68020 */ -extern struct cputbl op_smalltbl_2_nf[]; - -/* 68010 */ -extern struct cputbl op_smalltbl_3_nf[]; - -/* 68000 */ -extern struct cputbl op_smalltbl_4_nf[]; - -/* 68000 slow but compatible. */ -extern struct cputbl op_smalltbl_5_nf[]; - -static void flush_icache_hard(int n); -static void flush_icache_lazy(int n); -static void flush_icache_none(int n); -void (*flush_icache)(int n) = flush_icache_none; - - - -bigstate live; -smallstate empty_ss; -smallstate default_ss; -static int optlev; - -static int writereg(int r, int size); -static void unlock2(int r); -static void setlock(int r); -static int readreg_specific(int r, int size, int spec); -static int writereg_specific(int r, int size, int spec); -static void prepare_for_call_1(void); -static void prepare_for_call_2(void); -static void align_target(uae_u32 a); - -static uae_s32 nextused[VREGS]; - -uae_u32 m68k_pc_offset; - -/* Some arithmetic ooperations can be optimized away if the operands - * are known to be constant. But that's only a good idea when the - * side effects they would have on the flags are not important. This - * variable indicates whether we need the side effects or not - */ -uae_u32 needflags=0; - -/* Flag handling is complicated. - * - * x86 instructions create flags, which quite often are exactly what we - * want. So at times, the "68k" flags are actually in the x86 flags. - * - * Then again, sometimes we do x86 instructions that clobber the x86 - * flags, but don't represent a corresponding m68k instruction. In that - * case, we have to save them. - * - * We used to save them to the stack, but now store them back directly - * into the regflags.cznv of the traditional emulation. Thus some odd - * names. - * - * So flags can be in either of two places (used to be three; boy were - * things complicated back then!); And either place can contain either - * valid flags or invalid trash (and on the stack, there was also the - * option of "nothing at all", now gone). A couple of variables keep - * track of the respective states. - * - * To make things worse, we might or might not be interested in the flags. - * by default, we are, but a call to dont_care_flags can change that - * until the next call to live_flags. If we are not, pretty much whatever - * is in the register and/or the native flags is seen as valid. - */ - -static __inline__ blockinfo* get_blockinfo(uae_u32 cl) -{ - return cache_tags[cl+1].bi; -} - -static __inline__ blockinfo* get_blockinfo_addr(void* addr) -{ - blockinfo* bi=get_blockinfo(cacheline(addr)); - - while (bi) { - if (bi->pc_p==addr) - return bi; - bi=bi->next_same_cl; - } - return NULL; -} - - -/******************************************************************* - * All sorts of list related functions for all of the lists * - *******************************************************************/ - -static __inline__ void remove_from_cl_list(blockinfo* bi) -{ - uae_u32 cl=cacheline(bi->pc_p); - - if (bi->prev_same_cl_p) - *(bi->prev_same_cl_p)=bi->next_same_cl; - if (bi->next_same_cl) - bi->next_same_cl->prev_same_cl_p=bi->prev_same_cl_p; - if (cache_tags[cl+1].bi) - cache_tags[cl].handler=cache_tags[cl+1].bi->handler_to_use; - else - cache_tags[cl].handler=(cpuop_func *)popall_execute_normal; -} - -static __inline__ void remove_from_list(blockinfo* bi) -{ - if (bi->prev_p) - *(bi->prev_p)=bi->next; - if (bi->next) - bi->next->prev_p=bi->prev_p; -} - -static __inline__ void remove_from_lists(blockinfo* bi) -{ - remove_from_list(bi); - remove_from_cl_list(bi); -} - -static __inline__ void add_to_cl_list(blockinfo* bi) -{ - uae_u32 cl=cacheline(bi->pc_p); - - if (cache_tags[cl+1].bi) - cache_tags[cl+1].bi->prev_same_cl_p=&(bi->next_same_cl); - bi->next_same_cl=cache_tags[cl+1].bi; - - cache_tags[cl+1].bi=bi; - bi->prev_same_cl_p=&(cache_tags[cl+1].bi); - - cache_tags[cl].handler=bi->handler_to_use; -} - -static __inline__ void raise_in_cl_list(blockinfo* bi) -{ - remove_from_cl_list(bi); - add_to_cl_list(bi); -} - -static __inline__ void add_to_active(blockinfo* bi) -{ - if (active) - active->prev_p=&(bi->next); - bi->next=active; - - active=bi; - bi->prev_p=&active; -} - -static __inline__ void add_to_dormant(blockinfo* bi) -{ - if (dormant) - dormant->prev_p=&(bi->next); - bi->next=dormant; - - dormant=bi; - bi->prev_p=&dormant; -} - -static __inline__ void remove_dep(dependency* d) -{ - if (d->prev_p) - *(d->prev_p)=d->next; - if (d->next) - d->next->prev_p=d->prev_p; - d->prev_p=NULL; - d->next=NULL; -} - -/* This block's code is about to be thrown away, so it no longer - depends on anything else */ -static __inline__ void remove_deps(blockinfo* bi) -{ - remove_dep(&(bi->dep[0])); - remove_dep(&(bi->dep[1])); -} - -static __inline__ void adjust_jmpdep(dependency* d, cpuop_func* a) -{ - *(d->jmp_off)=(uintptr)a-((uintptr)d->jmp_off+4); -} - -/******************************************************************** - * Soft flush handling support functions * - ********************************************************************/ - -static __inline__ void set_dhtu(blockinfo* bi, cpuop_func* dh) -{ - //write_log("bi is %p\n",bi); - if (dh!=bi->direct_handler_to_use) { - dependency* x=bi->deplist; - //write_log("bi->deplist=%p\n",bi->deplist); - while (x) { - //write_log("x is %p\n",x); - //write_log("x->next is %p\n",x->next); - //write_log("x->prev_p is %p\n",x->prev_p); - - if (x->jmp_off) { - adjust_jmpdep(x,dh); - } - x=x->next; - } - bi->direct_handler_to_use=dh; - } -} - -static __inline__ void invalidate_block(blockinfo* bi) -{ - int i; - - bi->optlevel=0; - bi->count=optcount[0]-1; - bi->handler=NULL; - bi->handler_to_use=(cpuop_func *)popall_execute_normal; - bi->direct_handler=NULL; - set_dhtu(bi,bi->direct_pen); - bi->needed_flags=0xff; - bi->status=BI_INVALID; - for (i=0;i<2;i++) { - bi->dep[i].jmp_off=NULL; - bi->dep[i].target=NULL; - } - remove_deps(bi); -} - -static __inline__ void create_jmpdep(blockinfo* bi, int i, uae_u32* jmpaddr, uae_u32 target) -{ - blockinfo* tbi=get_blockinfo_addr((void*)(uintptr)target); - - Dif(!tbi) { - write_log("Could not create jmpdep!\n"); - abort(); - } - bi->dep[i].jmp_off=jmpaddr; - bi->dep[i].source=bi; - bi->dep[i].target=tbi; - bi->dep[i].next=tbi->deplist; - if (bi->dep[i].next) - bi->dep[i].next->prev_p=&(bi->dep[i].next); - bi->dep[i].prev_p=&(tbi->deplist); - tbi->deplist=&(bi->dep[i]); -} - -static __inline__ void block_need_recompile(blockinfo * bi) -{ - uae_u32 cl = cacheline(bi->pc_p); - - set_dhtu(bi, bi->direct_pen); - bi->direct_handler = bi->direct_pen; - - bi->handler_to_use = (cpuop_func *)popall_execute_normal; - bi->handler = (cpuop_func *)popall_execute_normal; - if (bi == cache_tags[cl + 1].bi) - cache_tags[cl].handler = (cpuop_func *)popall_execute_normal; - bi->status = BI_NEED_RECOMP; -} - -static __inline__ void mark_callers_recompile(blockinfo * bi) -{ - dependency *x = bi->deplist; - - while (x) { - dependency *next = x->next; /* This disappears when we mark for - * recompilation and thus remove the - * blocks from the lists */ - if (x->jmp_off) { - blockinfo *cbi = x->source; - - Dif(cbi->status == BI_INVALID) { - // write_log("invalid block in dependency list\n"); // FIXME? - // abort(); - } - if (cbi->status == BI_ACTIVE || cbi->status == BI_NEED_CHECK) { - block_need_recompile(cbi); - mark_callers_recompile(cbi); - } - else if (cbi->status == BI_COMPILING) { - redo_current_block = 1; - } - else if (cbi->status == BI_NEED_RECOMP) { - /* nothing */ - } - else { - //write_log("Status %d in mark_callers\n",cbi->status); // FIXME? - } - } - x = next; - } -} - -static __inline__ blockinfo* get_blockinfo_addr_new(void* addr, int setstate) -{ - blockinfo* bi=get_blockinfo_addr(addr); - int i; - - if (!bi) { - for (i=0;ipc_p=(uae_u8 *)addr; - invalidate_block(bi); - add_to_active(bi); - add_to_cl_list(bi); - - } - } - } - if (!bi) { - write_log("Looking for blockinfo, can't find free one\n"); - abort(); - } - return bi; -} - -static void prepare_block(blockinfo* bi); - -/* Managment of blockinfos. - - A blockinfo struct is allocated whenever a new block has to be - compiled. If the list of free blockinfos is empty, we allocate a new - pool of blockinfos and link the newly created blockinfos altogether - into the list of free blockinfos. Otherwise, we simply pop a structure - off the free list. - - Blockinfo are lazily deallocated, i.e. chained altogether in the - list of free blockinfos whenvever a translation cache flush (hard or - soft) request occurs. -*/ - -template< class T > -class LazyBlockAllocator -{ - enum { - kPoolSize = 1 + 4096 / sizeof(T) - }; - struct Pool { - T chunk[kPoolSize]; - Pool * next; - }; - Pool * mPools; - T * mChunks; -public: - LazyBlockAllocator() : mPools(0), mChunks(0) { } - ~LazyBlockAllocator(); - T * acquire(); - void release(T * const); -}; - -template< class T > -LazyBlockAllocator::~LazyBlockAllocator() -{ - Pool * currentPool = mPools; - while (currentPool) { - Pool * deadPool = currentPool; - currentPool = currentPool->next; - free(deadPool); - } -} - -template< class T > -T * LazyBlockAllocator::acquire() -{ - if (!mChunks) { - // There is no chunk left, allocate a new pool and link the - // chunks into the free list - Pool * newPool = (Pool *)malloc(sizeof(Pool)); - for (T * chunk = &newPool->chunk[0]; chunk < &newPool->chunk[kPoolSize]; chunk++) { - chunk->next = mChunks; - mChunks = chunk; - } - newPool->next = mPools; - mPools = newPool; - } - T * chunk = mChunks; - mChunks = chunk->next; - return chunk; -} - -template< class T > -void LazyBlockAllocator::release(T * const chunk) -{ - chunk->next = mChunks; - mChunks = chunk; -} - -template< class T > -class HardBlockAllocator -{ -public: - T * acquire() { - T * data = (T *)current_compile_p; - current_compile_p += sizeof(T); - return data; - } - - void release(T * const chunk) { - // Deallocated on invalidation - } -}; - -#if USE_SEPARATE_BIA -static LazyBlockAllocator BlockInfoAllocator; -static LazyBlockAllocator ChecksumInfoAllocator; -#else -static HardBlockAllocator BlockInfoAllocator; -static HardBlockAllocator ChecksumInfoAllocator; -#endif - -static __inline__ checksum_info *alloc_checksum_info(void) -{ - checksum_info *csi = ChecksumInfoAllocator.acquire(); - csi->next = NULL; - return csi; -} - -static __inline__ void free_checksum_info(checksum_info *csi) -{ - csi->next = NULL; - ChecksumInfoAllocator.release(csi); -} - -static __inline__ void free_checksum_info_chain(checksum_info *csi) -{ - while (csi != NULL) { - checksum_info *csi2 = csi->next; - free_checksum_info(csi); - csi = csi2; - } -} - -static __inline__ blockinfo *alloc_blockinfo(void) -{ - blockinfo *bi = BlockInfoAllocator.acquire(); -#if USE_CHECKSUM_INFO - bi->csi = NULL; -#endif - return bi; -} - -static __inline__ void free_blockinfo(blockinfo *bi) -{ -#if USE_CHECKSUM_INFO - free_checksum_info_chain(bi->csi); - bi->csi = NULL; -#endif - BlockInfoAllocator.release(bi); -} - -static __inline__ void alloc_blockinfos(void) -{ - int i; - blockinfo* bi; - - for (i=0;i>24)&0xff) | ((v>>8)&0xff00) | ((v<<8)&0xff0000) | ((v<<24)&0xff000000); -#endif -} - -/******************************************************************** - * Getting the information about the target CPU * - ********************************************************************/ - -#include "codegen_x86.cpp" - -void set_target(uae_u8* t) -{ - target=t; -} - -static __inline__ uae_u8* get_target_noopt(void) -{ - return target; -} - -__inline__ uae_u8* get_target(void) -{ - return get_target_noopt(); -} - - -/******************************************************************** - * Flags status handling. EMIT TIME! * - ********************************************************************/ - -static void bt_l_ri_noclobber(R4 r, IMM i); - -static void make_flags_live_internal(void) -{ - if (live.flags_in_flags==VALID) - return; - Dif (live.flags_on_stack==TRASH) { - write_log("Want flags, got something on stack, but it is TRASH\n"); - abort(); - } - if (live.flags_on_stack==VALID) { - int tmp; - tmp=readreg_specific(FLAGTMP,4,FLAG_NREG2); - raw_reg_to_flags(tmp); - unlock2(tmp); - - live.flags_in_flags=VALID; - return; - } - write_log("Huh? live.flags_in_flags=%d, live.flags_on_stack=%d, but need to make live\n", - live.flags_in_flags,live.flags_on_stack); - abort(); -} - -static void flags_to_stack(void) -{ - if (live.flags_on_stack==VALID) - return; - if (!live.flags_are_important) { - live.flags_on_stack=VALID; - return; - } - Dif (live.flags_in_flags!=VALID) - abort(); - else { - int tmp; - tmp=writereg_specific(FLAGTMP,4,FLAG_NREG1); - raw_flags_to_reg(tmp); - unlock2(tmp); - } - live.flags_on_stack=VALID; -} - -static __inline__ void clobber_flags(void) -{ - if (live.flags_in_flags==VALID && live.flags_on_stack!=VALID) - flags_to_stack(); - live.flags_in_flags=TRASH; -} - -/* Prepare for leaving the compiled stuff */ -static __inline__ void flush_flags(void) -{ - flags_to_stack(); - return; -} - -int touchcnt; - -/******************************************************************** - * Partial register flushing for optimized calls * - ********************************************************************/ - -struct regusage { - uae_u16 rmask; - uae_u16 wmask; -}; - -static inline void ru_set(uae_u16 *mask, int reg) -{ -#if USE_OPTIMIZED_CALLS - *mask |= 1 << reg; -#endif -} - -static inline bool ru_get(const uae_u16 *mask, int reg) -{ -#if USE_OPTIMIZED_CALLS - return (*mask & (1 << reg)); -#else - /* Default: instruction reads & write to register */ - return true; -#endif -} - -static inline void ru_set_read(regusage *ru, int reg) -{ - ru_set(&ru->rmask, reg); -} - -static inline void ru_set_write(regusage *ru, int reg) -{ - ru_set(&ru->wmask, reg); -} - -static inline bool ru_read_p(const regusage *ru, int reg) -{ - return ru_get(&ru->rmask, reg); -} - -static inline bool ru_write_p(const regusage *ru, int reg) -{ - return ru_get(&ru->wmask, reg); -} - -static void ru_fill_ea(regusage *ru, int reg, amodes mode, - wordsizes size, int write_mode) -{ - switch (mode) { - case Areg: - reg += 8; - /* fall through */ - case Dreg: - ru_set(write_mode ? &ru->wmask : &ru->rmask, reg); - break; - case Ad16: - /* skip displacment */ - m68k_pc_offset += 2; - case Aind: - case Aipi: - case Apdi: - ru_set_read(ru, reg+8); - break; - case Ad8r: - ru_set_read(ru, reg+8); - /* fall through */ - case PC8r: { - uae_u16 dp = comp_get_iword((m68k_pc_offset+=2)-2); - reg = (dp >> 12) & 15; - ru_set_read(ru, reg); - if (dp & 0x100) - m68k_pc_offset += (((dp & 0x30) >> 3) & 7) + ((dp & 3) * 2); - break; - } - case PC16: - case absw: - case imm0: - case imm1: - m68k_pc_offset += 2; - break; - case absl: - case imm2: - m68k_pc_offset += 4; - break; - case immi: - m68k_pc_offset += (size == sz_long) ? 4 : 2; - break; - } -} - -/* TODO: split into a static initialization part and a dynamic one - (instructions depending on extension words) */ -static void ru_fill(regusage *ru, uae_u32 opcode) -{ - m68k_pc_offset += 2; - - /* Default: no register is used or written to */ - ru->rmask = 0; - ru->wmask = 0; - - uae_u32 real_opcode = cft_map(opcode); - struct instr *dp = &table68k[real_opcode]; - - bool rw_dest = true; - bool handled = false; - - /* Handle some instructions specifically */ - uae_u16 ext; - switch (dp->mnemo) { - case i_BFCHG: - case i_BFCLR: - case i_BFEXTS: - case i_BFEXTU: - case i_BFFFO: - case i_BFINS: - case i_BFSET: - case i_BFTST: - ext = comp_get_iword((m68k_pc_offset+=2)-2); - if (ext & 0x800) ru_set_read(ru, (ext >> 6) & 7); - if (ext & 0x020) ru_set_read(ru, ext & 7); - ru_fill_ea(ru, dp->dreg, (amodes)dp->dmode, (wordsizes)dp->size, 1); - if (dp->dmode == Dreg) - ru_set_read(ru, dp->dreg); - switch (dp->mnemo) { - case i_BFEXTS: - case i_BFEXTU: - case i_BFFFO: - ru_set_write(ru, (ext >> 12) & 7); - break; - case i_BFINS: - ru_set_read(ru, (ext >> 12) & 7); - /* fall through */ - case i_BFCHG: - case i_BFCLR: - case i_BSET: - if (dp->dmode == Dreg) - ru_set_write(ru, dp->dreg); - break; - } - handled = true; - rw_dest = false; - break; - - case i_BTST: - rw_dest = false; - break; - - case i_CAS: - { - ext = comp_get_iword((m68k_pc_offset+=2)-2); - int Du = ext & 7; - ru_set_read(ru, Du); - int Dc = (ext >> 6) & 7; - ru_set_read(ru, Dc); - ru_set_write(ru, Dc); - break; - } - case i_CAS2: - { - int Dc1, Dc2, Du1, Du2, Rn1, Rn2; - ext = comp_get_iword((m68k_pc_offset+=2)-2); - Rn1 = (ext >> 12) & 15; - Du1 = (ext >> 6) & 7; - Dc1 = ext & 7; - ru_set_read(ru, Rn1); - ru_set_read(ru, Du1); - ru_set_read(ru, Dc1); - ru_set_write(ru, Dc1); - ext = comp_get_iword((m68k_pc_offset+=2)-2); - Rn2 = (ext >> 12) & 15; - Du2 = (ext >> 6) & 7; - Dc2 = ext & 7; - ru_set_read(ru, Rn2); - ru_set_read(ru, Du2); - ru_set_write(ru, Dc2); - break; - } - case i_DIVL: case i_MULL: - m68k_pc_offset += 2; - break; - case i_LEA: - case i_MOVE: case i_MOVEA: case i_MOVE16: - rw_dest = false; - break; - case i_PACK: case i_UNPK: - rw_dest = false; - m68k_pc_offset += 2; - break; - case i_TRAPcc: - m68k_pc_offset += (dp->size == sz_long) ? 4 : 2; - break; - case i_RTR: - /* do nothing, just for coverage debugging */ - break; - /* TODO: handle EXG instruction */ - } - - /* Handle A-Traps better */ - if ((real_opcode & 0xf000) == 0xa000) { - handled = true; - } - - /* Handle EmulOps better */ - if ((real_opcode & 0xff00) == 0x7100) { - handled = true; - ru->rmask = 0xffff; - ru->wmask = 0; - } - - if (dp->suse && !handled) - ru_fill_ea(ru, dp->sreg, (amodes)dp->smode, (wordsizes)dp->size, 0); - - if (dp->duse && !handled) - ru_fill_ea(ru, dp->dreg, (amodes)dp->dmode, (wordsizes)dp->size, 1); - - if (rw_dest) - ru->rmask |= ru->wmask; - - handled = handled || dp->suse || dp->duse; - - /* Mark all registers as used/written if the instruction may trap */ - if (may_trap(opcode)) { - handled = true; - ru->rmask = 0xffff; - ru->wmask = 0xffff; - } - - if (!handled) { - write_log("ru_fill: %04x = { %04x, %04x }\n", - real_opcode, ru->rmask, ru->wmask); - abort(); - } -} - -/******************************************************************** - * register allocation per block logging * - ********************************************************************/ - -static uae_s8 vstate[VREGS]; -static uae_s8 vwritten[VREGS]; -static uae_s8 nstate[N_REGS]; - -#define L_UNKNOWN -127 -#define L_UNAVAIL -1 -#define L_NEEDED -2 -#define L_UNNEEDED -3 - -static __inline__ void big_to_small_state(bigstate * b, smallstate * s) -{ - int i; - - for (i = 0; i < VREGS; i++) - s->virt[i] = vstate[i]; - for (i = 0; i < N_REGS; i++) - s->nat[i] = nstate[i]; -} - -static __inline__ int callers_need_recompile(bigstate * b, smallstate * s) -{ - int i; - int reverse = 0; - - for (i = 0; i < VREGS; i++) { - if (vstate[i] != L_UNNEEDED && s->virt[i] == L_UNNEEDED) - return 1; - if (vstate[i] == L_UNNEEDED && s->virt[i] != L_UNNEEDED) - reverse++; - } - for (i = 0; i < N_REGS; i++) { - if (nstate[i] >= 0 && nstate[i] != s->nat[i]) - return 1; - if (nstate[i] < 0 && s->nat[i] >= 0) - reverse++; - } - if (reverse >= 2 && USE_MATCH) - return 1; /* In this case, it might be worth recompiling the - * callers */ - return 0; -} - -static __inline__ void log_startblock(void) -{ - int i; - - for (i = 0; i < VREGS; i++) { - vstate[i] = L_UNKNOWN; - vwritten[i] = 0; - } - for (i = 0; i < N_REGS; i++) - nstate[i] = L_UNKNOWN; -} - -/* Using an n-reg for a temp variable */ -static __inline__ void log_isused(int n) -{ - if (nstate[n] == L_UNKNOWN) - nstate[n] = L_UNAVAIL; -} - -static __inline__ void log_visused(int r) -{ - if (vstate[r] == L_UNKNOWN) - vstate[r] = L_NEEDED; -} - -static __inline__ void do_load_reg(int n, int r) -{ - if (r == FLAGTMP) - raw_load_flagreg(n, r); - else if (r == FLAGX) - raw_load_flagx(n, r); - else - raw_mov_l_rm(n, (uintptr) live.state[r].mem); -} - -static __inline__ void check_load_reg(int n, int r) -{ - raw_mov_l_rm(n, (uintptr) live.state[r].mem); -} - -static __inline__ void log_vwrite(int r) -{ - vwritten[r] = 1; -} - -/* Using an n-reg to hold a v-reg */ -static __inline__ void log_isreg(int n, int r) -{ - static int count = 0; - - if (nstate[n] == L_UNKNOWN && r < 16 && !vwritten[r] && USE_MATCH) - nstate[n] = r; - else { - do_load_reg(n, r); - if (nstate[n] == L_UNKNOWN) - nstate[n] = L_UNAVAIL; - } - if (vstate[r] == L_UNKNOWN) - vstate[r] = L_NEEDED; -} - -static __inline__ void log_clobberreg(int r) -{ - if (vstate[r] == L_UNKNOWN) - vstate[r] = L_UNNEEDED; -} - -/* This ends all possibility of clever register allocation */ - -static __inline__ void log_flush(void) -{ - int i; - - for (i = 0; i < VREGS; i++) - if (vstate[i] == L_UNKNOWN) - vstate[i] = L_NEEDED; - for (i = 0; i < N_REGS; i++) - if (nstate[i] == L_UNKNOWN) - nstate[i] = L_UNAVAIL; -} - -static __inline__ void log_dump(void) -{ - int i; - - return; - - write_log("----------------------\n"); - for (i = 0; i < N_REGS; i++) { - switch (nstate[i]) { - case L_UNKNOWN: - write_log("Nat %d : UNKNOWN\n", i); - break; - case L_UNAVAIL: - write_log("Nat %d : UNAVAIL\n", i); - break; - default: - write_log("Nat %d : %d\n", i, nstate[i]); - break; - } - } - for (i = 0; i < VREGS; i++) { - if (vstate[i] == L_UNNEEDED) - write_log("Virt %d: UNNEEDED\n", i); - } -} - -/******************************************************************** - * register status handling. EMIT TIME! * - ********************************************************************/ - -static __inline__ void set_status(int r, int status) -{ - if (status == ISCONST) - log_clobberreg(r); - live.state[r].status=status; -} - -static __inline__ int isinreg(int r) -{ - return live.state[r].status==CLEAN || live.state[r].status==DIRTY; -} - -static __inline__ void adjust_nreg(int r, uae_u32 val) -{ - if (!val) - return; - raw_lea_l_brr(r,r,val); -} - -static void tomem(int r) -{ - int rr=live.state[r].realreg; - - if (isinreg(r)) { - if (live.state[r].val && live.nat[rr].nholds==1 - && !live.nat[rr].locked) { - // write_log("RemovingA offset %x from reg %d (%d) at %p\n", - // live.state[r].val,r,rr,target); - adjust_nreg(rr,live.state[r].val); - live.state[r].val=0; - live.state[r].dirtysize=4; - set_status(r,DIRTY); - } - } - - if (live.state[r].status==DIRTY) { - switch (live.state[r].dirtysize) { - case 1: raw_mov_b_mr((uintptr)live.state[r].mem,rr); break; - case 2: raw_mov_w_mr((uintptr)live.state[r].mem,rr); break; - case 4: raw_mov_l_mr((uintptr)live.state[r].mem,rr); break; - default: abort(); - } - log_vwrite(r); - set_status(r,CLEAN); - live.state[r].dirtysize=0; - } -} - -static __inline__ int isconst(int r) -{ - return live.state[r].status==ISCONST; -} - -int is_const(int r) -{ - return isconst(r); -} - -static __inline__ void writeback_const(int r) -{ - if (!isconst(r)) - return; - Dif (live.state[r].needflush==NF_HANDLER) { - write_log("Trying to write back constant NF_HANDLER!\n"); - abort(); - } - - raw_mov_l_mi((uintptr)live.state[r].mem,live.state[r].val); - log_vwrite(r); - live.state[r].val=0; - set_status(r,INMEM); -} - -static __inline__ void tomem_c(int r) -{ - if (isconst(r)) { - writeback_const(r); - } - else - tomem(r); -} - -static void evict(int r) -{ - int rr; - - if (!isinreg(r)) - return; - tomem(r); - rr=live.state[r].realreg; - - Dif (live.nat[rr].locked && - live.nat[rr].nholds==1) { - write_log("register %d in nreg %d is locked!\n",r,live.state[r].realreg); - abort(); - } - - live.nat[rr].nholds--; - if (live.nat[rr].nholds!=live.state[r].realind) { /* Was not last */ - int topreg=live.nat[rr].holds[live.nat[rr].nholds]; - int thisind=live.state[r].realind; - - live.nat[rr].holds[thisind]=topreg; - live.state[topreg].realind=thisind; - } - live.state[r].realreg=-1; - set_status(r,INMEM); -} - -static __inline__ void free_nreg(int r) -{ - int i=live.nat[r].nholds; - - while (i) { - int vr; - - --i; - vr=live.nat[r].holds[i]; - evict(vr); - } - Dif (live.nat[r].nholds!=0) { - write_log("Failed to free nreg %d, nholds is %d\n",r,live.nat[r].nholds); - abort(); - } -} - -/* Use with care! */ -static __inline__ void isclean(int r) -{ - if (!isinreg(r)) - return; - live.state[r].validsize=4; - live.state[r].dirtysize=0; - live.state[r].val=0; - set_status(r,CLEAN); -} - -static __inline__ void disassociate(int r) -{ - isclean(r); - evict(r); -} - -static __inline__ void set_const(int r, uae_u32 val) -{ - disassociate(r); - live.state[r].val=val; - set_status(r,ISCONST); -} - -static __inline__ uae_u32 get_offset(int r) -{ - return live.state[r].val; -} - -static int alloc_reg_hinted(int r, int size, int willclobber, int hint) -{ - int bestreg; - uae_s32 when; - int i; - uae_s32 badness=0; /* to shut up gcc */ - bestreg=-1; - when=2000000000; - - /* XXX use a regalloc_order table? */ - for (i=0;i0) { - free_nreg(bestreg); - } - if (isinreg(r)) { - int rr=live.state[r].realreg; - /* This will happen if we read a partially dirty register at a - bigger size */ - Dif (willclobber || live.state[r].validsize>=size) - abort(); - Dif (live.nat[rr].nholds!=1) - abort(); - if (size==4 && live.state[r].validsize==2) { - log_isused(bestreg); - log_visused(r); - raw_mov_l_rm(bestreg,(uintptr)live.state[r].mem); - raw_bswap_32(bestreg); - raw_zero_extend_16_rr(rr,rr); - raw_zero_extend_16_rr(bestreg,bestreg); - raw_bswap_32(bestreg); - raw_lea_l_brr_indexed(rr,rr,bestreg,1,0); - live.state[r].validsize=4; - live.nat[rr].touched=touchcnt++; - return rr; - } - if (live.state[r].validsize==1) { - /* Nothing yet */ - } - evict(r); - } - - if (!willclobber) { - if (live.state[r].status!=UNDEF) { - if (isconst(r)) { - raw_mov_l_ri(bestreg,live.state[r].val); - live.state[r].val=0; - live.state[r].dirtysize=4; - set_status(r,DIRTY); - log_isused(bestreg); - } - else { - log_isreg(bestreg, r); /* This will also load it! */ - live.state[r].dirtysize=0; - set_status(r,CLEAN); - } - } - else { - live.state[r].val=0; - live.state[r].dirtysize=0; - set_status(r,CLEAN); - log_isused(bestreg); - } - live.state[r].validsize=4; - } - else { /* this is the easiest way, but not optimal. FIXME! */ - /* Now it's trickier, but hopefully still OK */ - if (!isconst(r) || size==4) { - live.state[r].validsize=size; - live.state[r].dirtysize=size; - live.state[r].val=0; - set_status(r,DIRTY); - if (size == 4) { - log_clobberreg(r); - log_isused(bestreg); - } - else { - log_visused(r); - log_isused(bestreg); - } - } - else { - if (live.state[r].status!=UNDEF) - raw_mov_l_ri(bestreg,live.state[r].val); - live.state[r].val=0; - live.state[r].validsize=4; - live.state[r].dirtysize=4; - set_status(r,DIRTY); - log_isused(bestreg); - } - } - live.state[r].realreg=bestreg; - live.state[r].realind=live.nat[bestreg].nholds; - live.nat[bestreg].touched=touchcnt++; - live.nat[bestreg].holds[live.nat[bestreg].nholds]=r; - live.nat[bestreg].nholds++; - - return bestreg; -} - -static int alloc_reg(int r, int size, int willclobber) -{ - return alloc_reg_hinted(r,size,willclobber,-1); -} - -static void unlock2(int r) -{ - Dif (!live.nat[r].locked) - abort(); - live.nat[r].locked--; -} - -static void setlock(int r) -{ - live.nat[r].locked++; -} - - -static void mov_nregs(int d, int s) -{ - int ns=live.nat[s].nholds; - int nd=live.nat[d].nholds; - int i; - - if (s==d) - return; - - if (nd>0) - free_nreg(d); - - log_isused(d); - raw_mov_l_rr(d,s); - - for (i=0;i=size) { - n=live.state[r].realreg; - switch(size) { - case 1: - if (live.nat[n].canbyte || spec>=0) { - answer=n; - } - break; - case 2: - if (live.nat[n].canword || spec>=0) { - answer=n; - } - break; - case 4: - answer=n; - break; - default: abort(); - } - if (answer<0) - evict(r); - } - /* either the value was in memory to start with, or it was evicted and - is in memory now */ - if (answer<0) { - answer=alloc_reg_hinted(r,spec>=0?4:size,0,spec); - } - - if (spec>=0 && spec!=answer) { - /* Too bad */ - mov_nregs(spec,answer); - answer=spec; - } - live.nat[answer].locked++; - live.nat[answer].touched=touchcnt++; - return answer; -} - - - -static int readreg(int r, int size) -{ - return readreg_general(r,size,-1,0); -} - -static int readreg_specific(int r, int size, int spec) -{ - return readreg_general(r,size,spec,0); -} - -static int readreg_offset(int r, int size) -{ - return readreg_general(r,size,-1,1); -} - -/* writereg_general(r, size, spec) - * - * INPUT - * - r : mid-layer register - * - size : requested size (1/2/4) - * - spec : -1 if find or make a register free, otherwise specifies - * the physical register to use in any case - * - * OUTPUT - * - hard (physical, x86 here) register allocated to virtual register r - */ -static __inline__ int writereg_general(int r, int size, int spec) -{ - int n; - int answer=-1; - - record_register(r); - if (size<4) { - remove_offset(r,spec); - } - - make_exclusive(r,size,spec); - if (isinreg(r)) { - int nvsize=size>live.state[r].validsize?size:live.state[r].validsize; - int ndsize=size>live.state[r].dirtysize?size:live.state[r].dirtysize; - n=live.state[r].realreg; - - Dif (live.nat[n].nholds!=1) - abort(); - switch(size) { - case 1: - if (live.nat[n].canbyte || spec>=0) { - live.state[r].dirtysize=ndsize; - live.state[r].validsize=nvsize; - answer=n; - } - break; - case 2: - if (live.nat[n].canword || spec>=0) { - live.state[r].dirtysize=ndsize; - live.state[r].validsize=nvsize; - answer=n; - } - break; - case 4: - live.state[r].dirtysize=ndsize; - live.state[r].validsize=nvsize; - answer=n; - break; - default: abort(); - } - if (answer<0) - evict(r); - } - /* either the value was in memory to start with, or it was evicted and - is in memory now */ - if (answer<0) { - answer=alloc_reg_hinted(r,size,1,spec); - } - if (spec>=0 && spec!=answer) { - mov_nregs(spec,answer); - answer=spec; - } - if (live.state[r].status==UNDEF) - live.state[r].validsize=4; - live.state[r].dirtysize=size>live.state[r].dirtysize?size:live.state[r].dirtysize; - live.state[r].validsize=size>live.state[r].validsize?size:live.state[r].validsize; - - live.nat[answer].locked++; - live.nat[answer].touched=touchcnt++; - if (size==4) { - live.state[r].val=0; - } - else { - Dif (live.state[r].val) { - write_log("Problem with val\n"); - abort(); - } - } - set_status(r,DIRTY); - return answer; -} - -static int writereg(int r, int size) -{ - return writereg_general(r,size,-1); -} - -static int writereg_specific(int r, int size, int spec) -{ - return writereg_general(r,size,spec); -} - -static __inline__ int rmw_general(int r, int wsize, int rsize, int spec) -{ - int n; - int answer=-1; - - record_register(r); - if (live.state[r].status==UNDEF) { - write_log("WARNING: Unexpected read of undefined register %d\n",r); - } - remove_offset(r,spec); - make_exclusive(r,0,spec); - - Dif (wsize=rsize) { - n=live.state[r].realreg; - Dif (live.nat[n].nholds!=1) - abort(); - - switch(rsize) { - case 1: - if (live.nat[n].canbyte || spec>=0) { - answer=n; - } - break; - case 2: - if (live.nat[n].canword || spec>=0) { - answer=n; - } - break; - case 4: - answer=n; - break; - default: abort(); - } - if (answer<0) - evict(r); - } - /* either the value was in memory to start with, or it was evicted and - is in memory now */ - if (answer<0) { - answer=alloc_reg_hinted(r,spec>=0?4:rsize,0,spec); - } - - if (spec>=0 && spec!=answer) { - /* Too bad */ - mov_nregs(spec,answer); - answer=spec; - } - if (wsize>live.state[r].dirtysize) - live.state[r].dirtysize=wsize; - if (wsize>live.state[r].validsize) - live.state[r].validsize=wsize; - set_status(r,DIRTY); - - live.nat[answer].locked++; - live.nat[answer].touched=touchcnt++; - - Dif (live.state[r].val) { - write_log("Problem with val(rmw)\n"); - abort(); - } - return answer; -} - -static int rmw(int r, int wsize, int rsize) -{ - return rmw_general(r,wsize,rsize,-1); -} - -static int rmw_specific(int r, int wsize, int rsize, int spec) -{ - return rmw_general(r,wsize,rsize,spec); -} - - -/* needed for restoring the carry flag on non-P6 cores */ -static void bt_l_ri_noclobber(R4 r, IMM i) -{ - int size=4; - if (i<16) - size=2; - r=readreg(r,size); - raw_bt_l_ri(r,i); - unlock2(r); -} - -/******************************************************************** - * FPU register status handling. EMIT TIME! * - ********************************************************************/ - -static void f_tomem(int r) -{ - if (live.fate[r].status==DIRTY) { -#if USE_LONG_DOUBLE - raw_fmov_ext_mr((uintptr)live.fate[r].mem,live.fate[r].realreg); -#else - raw_fmov_mr((uintptr)live.fate[r].mem,live.fate[r].realreg); -#endif - live.fate[r].status=CLEAN; - } -} - -static void f_tomem_drop(int r) -{ - if (live.fate[r].status==DIRTY) { -#if USE_LONG_DOUBLE - raw_fmov_ext_mr_drop((uintptr)live.fate[r].mem,live.fate[r].realreg); -#else - raw_fmov_mr_drop((uintptr)live.fate[r].mem,live.fate[r].realreg); -#endif - live.fate[r].status=INMEM; - } -} - - -static __inline__ int f_isinreg(int r) -{ - return live.fate[r].status==CLEAN || live.fate[r].status==DIRTY; -} - -static void f_evict(int r) -{ - int rr; - - if (!f_isinreg(r)) - return; - rr=live.fate[r].realreg; - if (live.fat[rr].nholds==1) - f_tomem_drop(r); - else - f_tomem(r); - - Dif (live.fat[rr].locked && - live.fat[rr].nholds==1) { - write_log("FPU register %d in nreg %d is locked!\n",r,live.fate[r].realreg); - abort(); - } - - live.fat[rr].nholds--; - if (live.fat[rr].nholds!=live.fate[r].realind) { /* Was not last */ - int topreg=live.fat[rr].holds[live.fat[rr].nholds]; - int thisind=live.fate[r].realind; - live.fat[rr].holds[thisind]=topreg; - live.fate[topreg].realind=thisind; - } - live.fate[r].status=INMEM; - live.fate[r].realreg=-1; -} - -static __inline__ void f_free_nreg(int r) -{ - int i=live.fat[r].nholds; - - while (i) { - int vr; - - --i; - vr=live.fat[r].holds[i]; - f_evict(vr); - } - Dif (live.fat[r].nholds!=0) { - write_log("Failed to free nreg %d, nholds is %d\n",r,live.fat[r].nholds); - abort(); - } -} - - -/* Use with care! */ -static __inline__ void f_isclean(int r) -{ - if (!f_isinreg(r)) - return; - live.fate[r].status=CLEAN; -} - -static __inline__ void f_disassociate(int r) -{ - f_isclean(r); - f_evict(r); -} - - - -static int f_alloc_reg(int r, int willclobber) -{ - int bestreg; - uae_s32 when; - int i; - uae_s32 badness; - bestreg=-1; - when=2000000000; - for (i=N_FREGS;i--;) { - badness=live.fat[i].touched; - if (live.fat[i].nholds==0) - badness=0; - - if (!live.fat[i].locked && badness0) { - f_free_nreg(bestreg); - } - if (f_isinreg(r)) { - f_evict(r); - } - - if (!willclobber) { - if (live.fate[r].status!=UNDEF) { -#if USE_LONG_DOUBLE - raw_fmov_ext_rm(bestreg,(uintptr)live.fate[r].mem); -#else - raw_fmov_rm(bestreg,(uintptr)live.fate[r].mem); -#endif - } - live.fate[r].status=CLEAN; - } - else { - live.fate[r].status=DIRTY; - } - live.fate[r].realreg=bestreg; - live.fate[r].realind=live.fat[bestreg].nholds; - live.fat[bestreg].touched=touchcnt++; - live.fat[bestreg].holds[live.fat[bestreg].nholds]=r; - live.fat[bestreg].nholds++; - - return bestreg; -} - -static void f_unlock(int r) -{ - Dif (!live.fat[r].locked) - abort(); - live.fat[r].locked--; -} - -static void f_setlock(int r) -{ - live.fat[r].locked++; -} - -static __inline__ int f_readreg(int r) -{ - int n; - int answer=-1; - - if (f_isinreg(r)) { - n=live.fate[r].realreg; - answer=n; - } - /* either the value was in memory to start with, or it was evicted and - is in memory now */ - if (answer<0) - answer=f_alloc_reg(r,0); - - live.fat[answer].locked++; - live.fat[answer].touched=touchcnt++; - return answer; -} - -static __inline__ void f_make_exclusive(int r, int clobber) -{ - freg_status oldstate; - int rr=live.fate[r].realreg; - int nr; - int nind; - int ndirt=0; - int i; - - if (!f_isinreg(r)) - return; - if (live.fat[rr].nholds==1) - return; - for (i=0;i>=i; - return; - } - CLOBBER_SHRL; - r=rmw(r,4,4); - raw_shrl_l_ri(r,i); - unlock2(r); -} -MENDFUNC(2,shrl_l_ri,(RW4 r, IMM i)) - -MIDFUNC(2,shrl_w_ri,(RW2 r, IMM i)) -{ - if (!i && !needflags) - return; - CLOBBER_SHRL; - r=rmw(r,2,2); - raw_shrl_w_ri(r,i); - unlock2(r); -} -MENDFUNC(2,shrl_w_ri,(RW2 r, IMM i)) - -MIDFUNC(2,shrl_b_ri,(RW1 r, IMM i)) -{ - if (!i && !needflags) - return; - CLOBBER_SHRL; - r=rmw(r,1,1); - raw_shrl_b_ri(r,i); - unlock2(r); -} -MENDFUNC(2,shrl_b_ri,(RW1 r, IMM i)) - -MIDFUNC(2,shra_l_ri,(RW4 r, IMM i)) -{ - if (!i && !needflags) - return; - CLOBBER_SHRA; - r=rmw(r,4,4); - raw_shra_l_ri(r,i); - unlock2(r); -} -MENDFUNC(2,shra_l_ri,(RW4 r, IMM i)) - -MIDFUNC(2,shra_w_ri,(RW2 r, IMM i)) -{ - if (!i && !needflags) - return; - CLOBBER_SHRA; - r=rmw(r,2,2); - raw_shra_w_ri(r,i); - unlock2(r); -} -MENDFUNC(2,shra_w_ri,(RW2 r, IMM i)) - -MIDFUNC(2,shra_b_ri,(RW1 r, IMM i)) -{ - if (!i && !needflags) - return; - CLOBBER_SHRA; - r=rmw(r,1,1); - raw_shra_b_ri(r,i); - unlock2(r); -} -MENDFUNC(2,shra_b_ri,(RW1 r, IMM i)) - -MIDFUNC(2,shra_l_rr,(RW4 d, R1 r)) -{ - if (isconst(r)) { - COMPCALL(shra_l_ri)(d,(uae_u8)live.state[r].val); - return; - } - CLOBBER_SHRA; - r=readreg_specific(r,1,SHIFTCOUNT_NREG); - d=rmw(d,4,4); - Dif (r!=1) { - write_log("Illegal register %d in raw_rol_b\n",r); - abort(); - } - raw_shra_l_rr(d,r) ; - unlock2(r); - unlock2(d); -} -MENDFUNC(2,shra_l_rr,(RW4 d, R1 r)) - -MIDFUNC(2,shra_w_rr,(RW2 d, R1 r)) -{ /* Can only do this with r==1, i.e. cl */ - - if (isconst(r)) { - COMPCALL(shra_w_ri)(d,(uae_u8)live.state[r].val); - return; - } - CLOBBER_SHRA; - r=readreg_specific(r,1,SHIFTCOUNT_NREG); - d=rmw(d,2,2); - Dif (r!=1) { - write_log("Illegal register %d in raw_shra_b\n",r); - abort(); - } - raw_shra_w_rr(d,r) ; - unlock2(r); - unlock2(d); -} -MENDFUNC(2,shra_w_rr,(RW2 d, R1 r)) - -MIDFUNC(2,shra_b_rr,(RW1 d, R1 r)) -{ /* Can only do this with r==1, i.e. cl */ - - if (isconst(r)) { - COMPCALL(shra_b_ri)(d,(uae_u8)live.state[r].val); - return; - } - - CLOBBER_SHRA; - r=readreg_specific(r,1,SHIFTCOUNT_NREG); - d=rmw(d,1,1); - Dif (r!=1) { - write_log("Illegal register %d in raw_shra_b\n",r); - abort(); - } - raw_shra_b_rr(d,r) ; - unlock2(r); - unlock2(d); -} -MENDFUNC(2,shra_b_rr,(RW1 d, R1 r)) - - -MIDFUNC(2,setcc,(W1 d, IMM cc)) -{ - CLOBBER_SETCC; - d=writereg(d,1); - raw_setcc(d,cc); - unlock2(d); -} -MENDFUNC(2,setcc,(W1 d, IMM cc)) - -MIDFUNC(2,setcc_m,(IMM d, IMM cc)) -{ - CLOBBER_SETCC; - raw_setcc_m(d,cc); -} -MENDFUNC(2,setcc_m,(IMM d, IMM cc)) - -MIDFUNC(3,cmov_b_rr,(RW1 d, R1 s, IMM cc)) -{ - if (d==s) - return; - CLOBBER_CMOV; - s=readreg(s,1); - d=rmw(d,1,1); - raw_cmov_b_rr(d,s,cc); - unlock2(s); - unlock2(d); -} -MENDFUNC(3,cmov_b_rr,(RW1 d, R1 s, IMM cc)) - -MIDFUNC(3,cmov_w_rr,(RW2 d, R2 s, IMM cc)) -{ - if (d==s) - return; - CLOBBER_CMOV; - s=readreg(s,2); - d=rmw(d,2,2); - raw_cmov_w_rr(d,s,cc); - unlock2(s); - unlock2(d); -} -MENDFUNC(3,cmov_w_rr,(RW2 d, R2 s, IMM cc)) - -MIDFUNC(3,cmov_l_rr,(RW4 d, R4 s, IMM cc)) -{ - if (d==s) - return; - CLOBBER_CMOV; - s=readreg(s,4); - d=rmw(d,4,4); - raw_cmov_l_rr(d,s,cc); - unlock2(s); - unlock2(d); -} -MENDFUNC(3,cmov_l_rr,(RW4 d, R4 s, IMM cc)) - -MIDFUNC(3,cmov_l_rm,(RW4 d, IMM s, IMM cc)) -{ - CLOBBER_CMOV; - d=rmw(d,4,4); - raw_cmov_l_rm(d,s,cc); - unlock2(d); -} -MENDFUNC(3,cmov_l_rm,(RW4 d, IMM s, IMM cc)) - -MIDFUNC(2,bsf_l_rr,(W4 d, W4 s)) -{ - CLOBBER_BSF; - s = readreg(s, 4); - d = writereg(d, 4); - raw_bsf_l_rr(d, s); - unlock2(s); - unlock2(d); -} -MENDFUNC(2,bsf_l_rr,(W4 d, W4 s)) - -/* Set the Z flag depending on the value in s. Note that the - value has to be 0 or -1 (or, more precisely, for non-zero - values, bit 14 must be set)! */ -MIDFUNC(2,simulate_bsf,(W4 tmp, RW4 s)) -{ - CLOBBER_BSF; - s=rmw_specific(s,4,4,FLAG_NREG3); - tmp=writereg(tmp,4); - raw_flags_set_zero(s, tmp); - unlock2(tmp); - unlock2(s); -} -MENDFUNC(2,simulate_bsf,(W4 tmp, RW4 s)) - -MIDFUNC(2,imul_32_32,(RW4 d, R4 s)) -{ - CLOBBER_MUL; - s=readreg(s,4); - d=rmw(d,4,4); - raw_imul_32_32(d,s); - unlock2(s); - unlock2(d); -} -MENDFUNC(2,imul_32_32,(RW4 d, R4 s)) - -MIDFUNC(2,imul_64_32,(RW4 d, RW4 s)) -{ - CLOBBER_MUL; - s=rmw_specific(s,4,4,MUL_NREG2); - d=rmw_specific(d,4,4,MUL_NREG1); - raw_imul_64_32(d,s); - unlock2(s); - unlock2(d); -} -MENDFUNC(2,imul_64_32,(RW4 d, RW4 s)) - -MIDFUNC(2,mul_64_32,(RW4 d, RW4 s)) -{ - CLOBBER_MUL; - s=rmw_specific(s,4,4,MUL_NREG2); - d=rmw_specific(d,4,4,MUL_NREG1); - raw_mul_64_32(d,s); - unlock2(s); - unlock2(d); -} -MENDFUNC(2,mul_64_32,(RW4 d, RW4 s)) - -MIDFUNC(2,mul_32_32,(RW4 d, R4 s)) -{ - CLOBBER_MUL; - s=readreg(s,4); - d=rmw(d,4,4); - raw_mul_32_32(d,s); - unlock2(s); - unlock2(d); -} -MENDFUNC(2,mul_32_32,(RW4 d, R4 s)) - -#if SIZEOF_VOID_P == 8 -MIDFUNC(2,sign_extend_32_rr,(W4 d, R2 s)) -{ - int isrmw; - - if (isconst(s)) { - set_const(d,(uae_s32)live.state[s].val); - return; - } - - CLOBBER_SE32; - isrmw=(s==d); - if (!isrmw) { - s=readreg(s,4); - d=writereg(d,4); - } - else { /* If we try to lock this twice, with different sizes, we - are int trouble! */ - s=d=rmw(s,4,4); - } - raw_sign_extend_32_rr(d,s); - if (!isrmw) { - unlock2(d); - unlock2(s); - } - else { - unlock2(s); - } -} -MENDFUNC(2,sign_extend_32_rr,(W4 d, R2 s)) -#endif - -MIDFUNC(2,sign_extend_16_rr,(W4 d, R2 s)) -{ - int isrmw; - - if (isconst(s)) { - set_const(d,(uae_s32)(uae_s16)live.state[s].val); - return; - } - - CLOBBER_SE16; - isrmw=(s==d); - if (!isrmw) { - s=readreg(s,2); - d=writereg(d,4); - } - else { /* If we try to lock this twice, with different sizes, we - are int trouble! */ - s=d=rmw(s,4,2); - } - raw_sign_extend_16_rr(d,s); - if (!isrmw) { - unlock2(d); - unlock2(s); - } - else { - unlock2(s); - } -} -MENDFUNC(2,sign_extend_16_rr,(W4 d, R2 s)) - -MIDFUNC(2,sign_extend_8_rr,(W4 d, R1 s)) -{ - int isrmw; - - if (isconst(s)) { - set_const(d,(uae_s32)(uae_s8)live.state[s].val); - return; - } - - isrmw=(s==d); - CLOBBER_SE8; - if (!isrmw) { - s=readreg(s,1); - d=writereg(d,4); - } - else { /* If we try to lock this twice, with different sizes, we - are int trouble! */ - s=d=rmw(s,4,1); - } - - raw_sign_extend_8_rr(d,s); - - if (!isrmw) { - unlock2(d); - unlock2(s); - } - else { - unlock2(s); - } -} -MENDFUNC(2,sign_extend_8_rr,(W4 d, R1 s)) - - -MIDFUNC(2,zero_extend_16_rr,(W4 d, R2 s)) -{ - int isrmw; - - if (isconst(s)) { - set_const(d,(uae_u32)(uae_u16)live.state[s].val); - return; - } - - isrmw=(s==d); - CLOBBER_ZE16; - if (!isrmw) { - s=readreg(s,2); - d=writereg(d,4); - } - else { /* If we try to lock this twice, with different sizes, we - are int trouble! */ - s=d=rmw(s,4,2); - } - raw_zero_extend_16_rr(d,s); - if (!isrmw) { - unlock2(d); - unlock2(s); - } - else { - unlock2(s); - } -} -MENDFUNC(2,zero_extend_16_rr,(W4 d, R2 s)) - -MIDFUNC(2,zero_extend_8_rr,(W4 d, R1 s)) -{ - int isrmw; - if (isconst(s)) { - set_const(d,(uae_u32)(uae_u8)live.state[s].val); - return; - } - - isrmw=(s==d); - CLOBBER_ZE8; - if (!isrmw) { - s=readreg(s,1); - d=writereg(d,4); - } - else { /* If we try to lock this twice, with different sizes, we - are int trouble! */ - s=d=rmw(s,4,1); - } - - raw_zero_extend_8_rr(d,s); - - if (!isrmw) { - unlock2(d); - unlock2(s); - } - else { - unlock2(s); - } -} -MENDFUNC(2,zero_extend_8_rr,(W4 d, R1 s)) - -MIDFUNC(2,mov_b_rr,(W1 d, R1 s)) -{ - if (d==s) - return; - if (isconst(s)) { - COMPCALL(mov_b_ri)(d,(uae_u8)live.state[s].val); - return; - } - - CLOBBER_MOV; - s=readreg(s,1); - d=writereg(d,1); - raw_mov_b_rr(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,mov_b_rr,(W1 d, R1 s)) - -MIDFUNC(2,mov_w_rr,(W2 d, R2 s)) -{ - if (d==s) - return; - if (isconst(s)) { - COMPCALL(mov_w_ri)(d,(uae_u16)live.state[s].val); - return; - } - - CLOBBER_MOV; - s=readreg(s,2); - d=writereg(d,2); - raw_mov_w_rr(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,mov_w_rr,(W2 d, R2 s)) - - -MIDFUNC(4,mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor)) -{ - CLOBBER_MOV; - baser=readreg(baser,4); - index=readreg(index,4); - d=writereg(d,4); - - raw_mov_l_rrm_indexed(d,baser,index,factor); - unlock2(d); - unlock2(baser); - unlock2(index); -} -MENDFUNC(4,mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor)) - -MIDFUNC(4,mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor)) -{ - CLOBBER_MOV; - baser=readreg(baser,4); - index=readreg(index,4); - d=writereg(d,2); - - raw_mov_w_rrm_indexed(d,baser,index,factor); - unlock2(d); - unlock2(baser); - unlock2(index); -} -MENDFUNC(4,mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor)) - -MIDFUNC(4,mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor)) -{ - CLOBBER_MOV; - baser=readreg(baser,4); - index=readreg(index,4); - d=writereg(d,1); - - raw_mov_b_rrm_indexed(d,baser,index,factor); - - unlock2(d); - unlock2(baser); - unlock2(index); -} -MENDFUNC(4,mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor)) - - -MIDFUNC(4,mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s)) -{ - CLOBBER_MOV; - baser=readreg(baser,4); - index=readreg(index,4); - s=readreg(s,4); - - Dif (baser==s || index==s) - abort(); - - - raw_mov_l_mrr_indexed(baser,index,factor,s); - unlock2(s); - unlock2(baser); - unlock2(index); -} -MENDFUNC(4,mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s)) - -MIDFUNC(4,mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s)) -{ - CLOBBER_MOV; - baser=readreg(baser,4); - index=readreg(index,4); - s=readreg(s,2); - - raw_mov_w_mrr_indexed(baser,index,factor,s); - unlock2(s); - unlock2(baser); - unlock2(index); -} -MENDFUNC(4,mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s)) - -MIDFUNC(4,mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s)) -{ - CLOBBER_MOV; - s=readreg(s,1); - baser=readreg(baser,4); - index=readreg(index,4); - - raw_mov_b_mrr_indexed(baser,index,factor,s); - unlock2(s); - unlock2(baser); - unlock2(index); -} -MENDFUNC(4,mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s)) - - -MIDFUNC(5,mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s)) -{ - int basereg=baser; - int indexreg=index; - - CLOBBER_MOV; - s=readreg(s,4); - baser=readreg_offset(baser,4); - index=readreg_offset(index,4); - - base+=get_offset(basereg); - base+=factor*get_offset(indexreg); - - raw_mov_l_bmrr_indexed(base,baser,index,factor,s); - unlock2(s); - unlock2(baser); - unlock2(index); -} -MENDFUNC(5,mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s)) - -MIDFUNC(5,mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s)) -{ - int basereg=baser; - int indexreg=index; - - CLOBBER_MOV; - s=readreg(s,2); - baser=readreg_offset(baser,4); - index=readreg_offset(index,4); - - base+=get_offset(basereg); - base+=factor*get_offset(indexreg); - - raw_mov_w_bmrr_indexed(base,baser,index,factor,s); - unlock2(s); - unlock2(baser); - unlock2(index); -} -MENDFUNC(5,mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s)) - -MIDFUNC(5,mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s)) -{ - int basereg=baser; - int indexreg=index; - - CLOBBER_MOV; - s=readreg(s,1); - baser=readreg_offset(baser,4); - index=readreg_offset(index,4); - - base+=get_offset(basereg); - base+=factor*get_offset(indexreg); - - raw_mov_b_bmrr_indexed(base,baser,index,factor,s); - unlock2(s); - unlock2(baser); - unlock2(index); -} -MENDFUNC(5,mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s)) - - - -/* Read a long from base+baser+factor*index */ -MIDFUNC(5,mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - int basereg=baser; - int indexreg=index; - - CLOBBER_MOV; - baser=readreg_offset(baser,4); - index=readreg_offset(index,4); - base+=get_offset(basereg); - base+=factor*get_offset(indexreg); - d=writereg(d,4); - raw_mov_l_brrm_indexed(d,base,baser,index,factor); - unlock2(d); - unlock2(baser); - unlock2(index); -} -MENDFUNC(5,mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor)) - - -MIDFUNC(5,mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - int basereg=baser; - int indexreg=index; - - CLOBBER_MOV; - remove_offset(d,-1); - baser=readreg_offset(baser,4); - index=readreg_offset(index,4); - base+=get_offset(basereg); - base+=factor*get_offset(indexreg); - d=writereg(d,2); - raw_mov_w_brrm_indexed(d,base,baser,index,factor); - unlock2(d); - unlock2(baser); - unlock2(index); -} -MENDFUNC(5,mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor)) - - -MIDFUNC(5,mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - int basereg=baser; - int indexreg=index; - - CLOBBER_MOV; - remove_offset(d,-1); - baser=readreg_offset(baser,4); - index=readreg_offset(index,4); - base+=get_offset(basereg); - base+=factor*get_offset(indexreg); - d=writereg(d,1); - raw_mov_b_brrm_indexed(d,base,baser,index,factor); - unlock2(d); - unlock2(baser); - unlock2(index); -} -MENDFUNC(5,mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor)) - -/* Read a long from base+factor*index */ -MIDFUNC(4,mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor)) -{ - int indexreg=index; - - if (isconst(index)) { - COMPCALL(mov_l_rm)(d,base+factor*live.state[index].val); - return; - } - - CLOBBER_MOV; - index=readreg_offset(index,4); - base+=get_offset(indexreg)*factor; - d=writereg(d,4); - - raw_mov_l_rm_indexed(d,base,index,factor); - unlock2(index); - unlock2(d); -} -MENDFUNC(4,mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor)) - - -/* read the long at the address contained in s+offset and store in d */ -MIDFUNC(3,mov_l_rR,(W4 d, R4 s, IMM offset)) -{ - if (isconst(s)) { - COMPCALL(mov_l_rm)(d,live.state[s].val+offset); - return; - } - CLOBBER_MOV; - s=readreg(s,4); - d=writereg(d,4); - - raw_mov_l_rR(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_l_rR,(W4 d, R4 s, IMM offset)) - -/* read the word at the address contained in s+offset and store in d */ -MIDFUNC(3,mov_w_rR,(W2 d, R4 s, IMM offset)) -{ - if (isconst(s)) { - COMPCALL(mov_w_rm)(d,live.state[s].val+offset); - return; - } - CLOBBER_MOV; - s=readreg(s,4); - d=writereg(d,2); - - raw_mov_w_rR(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_w_rR,(W2 d, R4 s, IMM offset)) - -/* read the word at the address contained in s+offset and store in d */ -MIDFUNC(3,mov_b_rR,(W1 d, R4 s, IMM offset)) -{ - if (isconst(s)) { - COMPCALL(mov_b_rm)(d,live.state[s].val+offset); - return; - } - CLOBBER_MOV; - s=readreg(s,4); - d=writereg(d,1); - - raw_mov_b_rR(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_b_rR,(W1 d, R4 s, IMM offset)) - -/* read the long at the address contained in s+offset and store in d */ -MIDFUNC(3,mov_l_brR,(W4 d, R4 s, IMM offset)) -{ - int sreg=s; - if (isconst(s)) { - COMPCALL(mov_l_rm)(d,live.state[s].val+offset); - return; - } - CLOBBER_MOV; - s=readreg_offset(s,4); - offset+=get_offset(sreg); - d=writereg(d,4); - - raw_mov_l_brR(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_l_brR,(W4 d, R4 s, IMM offset)) - -/* read the word at the address contained in s+offset and store in d */ -MIDFUNC(3,mov_w_brR,(W2 d, R4 s, IMM offset)) -{ - int sreg=s; - if (isconst(s)) { - COMPCALL(mov_w_rm)(d,live.state[s].val+offset); - return; - } - CLOBBER_MOV; - remove_offset(d,-1); - s=readreg_offset(s,4); - offset+=get_offset(sreg); - d=writereg(d,2); - - raw_mov_w_brR(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_w_brR,(W2 d, R4 s, IMM offset)) - -/* read the word at the address contained in s+offset and store in d */ -MIDFUNC(3,mov_b_brR,(W1 d, R4 s, IMM offset)) -{ - int sreg=s; - if (isconst(s)) { - COMPCALL(mov_b_rm)(d,live.state[s].val+offset); - return; - } - CLOBBER_MOV; - remove_offset(d,-1); - s=readreg_offset(s,4); - offset+=get_offset(sreg); - d=writereg(d,1); - - raw_mov_b_brR(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_b_brR,(W1 d, R4 s, IMM offset)) - -MIDFUNC(3,mov_l_Ri,(R4 d, IMM i, IMM offset)) -{ - int dreg=d; - if (isconst(d)) { - COMPCALL(mov_l_mi)(live.state[d].val+offset,i); - return; - } - - CLOBBER_MOV; - d=readreg_offset(d,4); - offset+=get_offset(dreg); - raw_mov_l_Ri(d,i,offset); - unlock2(d); -} -MENDFUNC(3,mov_l_Ri,(R4 d, IMM i, IMM offset)) - -MIDFUNC(3,mov_w_Ri,(R4 d, IMM i, IMM offset)) -{ - int dreg=d; - if (isconst(d)) { - COMPCALL(mov_w_mi)(live.state[d].val+offset,i); - return; - } - - CLOBBER_MOV; - d=readreg_offset(d,4); - offset+=get_offset(dreg); - raw_mov_w_Ri(d,i,offset); - unlock2(d); -} -MENDFUNC(3,mov_w_Ri,(R4 d, IMM i, IMM offset)) - -MIDFUNC(3,mov_b_Ri,(R4 d, IMM i, IMM offset)) -{ - int dreg=d; - if (isconst(d)) { - COMPCALL(mov_b_mi)(live.state[d].val+offset,i); - return; - } - - CLOBBER_MOV; - d=readreg_offset(d,4); - offset+=get_offset(dreg); - raw_mov_b_Ri(d,i,offset); - unlock2(d); -} -MENDFUNC(3,mov_b_Ri,(R4 d, IMM i, IMM offset)) - - /* Warning! OFFSET is byte sized only! */ -MIDFUNC(3,mov_l_Rr,(R4 d, R4 s, IMM offset)) -{ - if (isconst(d)) { - COMPCALL(mov_l_mr)(live.state[d].val+offset,s); - return; - } - if (isconst(s)) { - COMPCALL(mov_l_Ri)(d,live.state[s].val,offset); - return; - } - - CLOBBER_MOV; - s=readreg(s,4); - d=readreg(d,4); - - raw_mov_l_Rr(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_l_Rr,(R4 d, R4 s, IMM offset)) - -MIDFUNC(3,mov_w_Rr,(R4 d, R2 s, IMM offset)) -{ - if (isconst(d)) { - COMPCALL(mov_w_mr)(live.state[d].val+offset,s); - return; - } - if (isconst(s)) { - COMPCALL(mov_w_Ri)(d,(uae_u16)live.state[s].val,offset); - return; - } - - CLOBBER_MOV; - s=readreg(s,2); - d=readreg(d,4); - raw_mov_w_Rr(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_w_Rr,(R4 d, R2 s, IMM offset)) - -MIDFUNC(3,mov_b_Rr,(R4 d, R1 s, IMM offset)) -{ - if (isconst(d)) { - COMPCALL(mov_b_mr)(live.state[d].val+offset,s); - return; - } - if (isconst(s)) { - COMPCALL(mov_b_Ri)(d,(uae_u8)live.state[s].val,offset); - return; - } - - CLOBBER_MOV; - s=readreg(s,1); - d=readreg(d,4); - raw_mov_b_Rr(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_b_Rr,(R4 d, R1 s, IMM offset)) - -MIDFUNC(3,lea_l_brr,(W4 d, R4 s, IMM offset)) -{ - if (isconst(s)) { - COMPCALL(mov_l_ri)(d,live.state[s].val+offset); - return; - } -#if USE_OFFSET - if (d==s) { - add_offset(d,offset); - return; - } -#endif - CLOBBER_LEA; - s=readreg(s,4); - d=writereg(d,4); - raw_lea_l_brr(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,lea_l_brr,(W4 d, R4 s, IMM offset)) - -MIDFUNC(5,lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset)) -{ - if (!offset) { - COMPCALL(lea_l_rr_indexed)(d,s,index,factor); - return; - } - CLOBBER_LEA; - s=readreg(s,4); - index=readreg(index,4); - d=writereg(d,4); - - raw_lea_l_brr_indexed(d,s,index,factor,offset); - unlock2(d); - unlock2(index); - unlock2(s); -} -MENDFUNC(5,lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset)) - -MIDFUNC(4,lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor)) -{ - CLOBBER_LEA; - s=readreg(s,4); - index=readreg(index,4); - d=writereg(d,4); - - raw_lea_l_rr_indexed(d,s,index,factor); - unlock2(d); - unlock2(index); - unlock2(s); -} -MENDFUNC(4,lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor)) - -/* write d to the long at the address contained in s+offset */ -MIDFUNC(3,mov_l_bRr,(R4 d, R4 s, IMM offset)) -{ - int dreg=d; - if (isconst(d)) { - COMPCALL(mov_l_mr)(live.state[d].val+offset,s); - return; - } - - CLOBBER_MOV; - s=readreg(s,4); - d=readreg_offset(d,4); - offset+=get_offset(dreg); - - raw_mov_l_bRr(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_l_bRr,(R4 d, R4 s, IMM offset)) - -/* write the word at the address contained in s+offset and store in d */ -MIDFUNC(3,mov_w_bRr,(R4 d, R2 s, IMM offset)) -{ - int dreg=d; - - if (isconst(d)) { - COMPCALL(mov_w_mr)(live.state[d].val+offset,s); - return; - } - - CLOBBER_MOV; - s=readreg(s,2); - d=readreg_offset(d,4); - offset+=get_offset(dreg); - raw_mov_w_bRr(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_w_bRr,(R4 d, R2 s, IMM offset)) - -MIDFUNC(3,mov_b_bRr,(R4 d, R1 s, IMM offset)) -{ - int dreg=d; - if (isconst(d)) { - COMPCALL(mov_b_mr)(live.state[d].val+offset,s); - return; - } - - CLOBBER_MOV; - s=readreg(s,1); - d=readreg_offset(d,4); - offset+=get_offset(dreg); - raw_mov_b_bRr(d,s,offset); - unlock2(d); - unlock2(s); -} -MENDFUNC(3,mov_b_bRr,(R4 d, R1 s, IMM offset)) - -MIDFUNC(1,bswap_32,(RW4 r)) -{ - int reg=r; - - if (isconst(r)) { - uae_u32 oldv=live.state[r].val; - live.state[r].val=reverse32(oldv); - return; - } - - CLOBBER_SW32; - r=rmw(r,4,4); - raw_bswap_32(r); - unlock2(r); -} -MENDFUNC(1,bswap_32,(RW4 r)) - -MIDFUNC(1,bswap_16,(RW2 r)) -{ - if (isconst(r)) { - uae_u32 oldv=live.state[r].val; - live.state[r].val=((oldv>>8)&0xff) | ((oldv<<8)&0xff00) | - (oldv&0xffff0000); - return; - } - - CLOBBER_SW16; - r=rmw(r,2,2); - - raw_bswap_16(r); - unlock2(r); -} -MENDFUNC(1,bswap_16,(RW2 r)) - - - -MIDFUNC(2,mov_l_rr,(W4 d, R4 s)) -{ - int olds; - - if (d==s) { /* How pointless! */ - return; - } - if (isconst(s)) { - COMPCALL(mov_l_ri)(d,live.state[s].val); - return; - } - olds=s; - disassociate(d); - s=readreg_offset(s,4); - live.state[d].realreg=s; - live.state[d].realind=live.nat[s].nholds; - live.state[d].val=live.state[olds].val; - live.state[d].validsize=4; - live.state[d].dirtysize=4; - set_status(d,DIRTY); - - live.nat[s].holds[live.nat[s].nholds]=d; - live.nat[s].nholds++; - log_clobberreg(d); - /* write_log("Added %d to nreg %d(%d), now holds %d regs\n", - d,s,live.state[d].realind,live.nat[s].nholds); */ - unlock2(s); -} -MENDFUNC(2,mov_l_rr,(W4 d, R4 s)) - -MIDFUNC(2,mov_l_mr,(IMM d, R4 s)) -{ - if (isconst(s)) { - COMPCALL(mov_l_mi)(d,live.state[s].val); - return; - } - CLOBBER_MOV; - s=readreg(s,4); - - raw_mov_l_mr(d,s); - unlock2(s); -} -MENDFUNC(2,mov_l_mr,(IMM d, R4 s)) - - -MIDFUNC(2,mov_w_mr,(IMM d, R2 s)) -{ - if (isconst(s)) { - COMPCALL(mov_w_mi)(d,(uae_u16)live.state[s].val); - return; - } - CLOBBER_MOV; - s=readreg(s,2); - - raw_mov_w_mr(d,s); - unlock2(s); -} -MENDFUNC(2,mov_w_mr,(IMM d, R2 s)) - -MIDFUNC(2,mov_w_rm,(W2 d, IMM s)) -{ - CLOBBER_MOV; - d=writereg(d,2); - - raw_mov_w_rm(d,s); - unlock2(d); -} -MENDFUNC(2,mov_w_rm,(W2 d, IMM s)) - -MIDFUNC(2,mov_b_mr,(IMM d, R1 s)) -{ - if (isconst(s)) { - COMPCALL(mov_b_mi)(d,(uae_u8)live.state[s].val); - return; - } - - CLOBBER_MOV; - s=readreg(s,1); - - raw_mov_b_mr(d,s); - unlock2(s); -} -MENDFUNC(2,mov_b_mr,(IMM d, R1 s)) - -MIDFUNC(2,mov_b_rm,(W1 d, IMM s)) -{ - CLOBBER_MOV; - d=writereg(d,1); - - raw_mov_b_rm(d,s); - unlock2(d); -} -MENDFUNC(2,mov_b_rm,(W1 d, IMM s)) - -MIDFUNC(2,mov_l_ri,(W4 d, IMM s)) -{ - set_const(d,s); - return; -} -MENDFUNC(2,mov_l_ri,(W4 d, IMM s)) - -MIDFUNC(2,mov_w_ri,(W2 d, IMM s)) -{ - CLOBBER_MOV; - d=writereg(d,2); - - raw_mov_w_ri(d,s); - unlock2(d); -} -MENDFUNC(2,mov_w_ri,(W2 d, IMM s)) - -MIDFUNC(2,mov_b_ri,(W1 d, IMM s)) -{ - CLOBBER_MOV; - d=writereg(d,1); - - raw_mov_b_ri(d,s); - unlock2(d); -} -MENDFUNC(2,mov_b_ri,(W1 d, IMM s)) - - -MIDFUNC(2,add_l_mi,(IMM d, IMM s)) -{ - CLOBBER_ADD; - raw_add_l_mi(d,s) ; -} -MENDFUNC(2,add_l_mi,(IMM d, IMM s)) - -MIDFUNC(2,add_w_mi,(IMM d, IMM s)) -{ - CLOBBER_ADD; - raw_add_w_mi(d,s) ; -} -MENDFUNC(2,add_w_mi,(IMM d, IMM s)) - -MIDFUNC(2,add_b_mi,(IMM d, IMM s)) -{ - CLOBBER_ADD; - raw_add_b_mi(d,s) ; -} -MENDFUNC(2,add_b_mi,(IMM d, IMM s)) - - -MIDFUNC(2,test_l_ri,(R4 d, IMM i)) -{ - CLOBBER_TEST; - d=readreg(d,4); - - raw_test_l_ri(d,i); - unlock2(d); -} -MENDFUNC(2,test_l_ri,(R4 d, IMM i)) - -MIDFUNC(2,test_l_rr,(R4 d, R4 s)) -{ - CLOBBER_TEST; - d=readreg(d,4); - s=readreg(s,4); - - raw_test_l_rr(d,s);; - unlock2(d); - unlock2(s); -} -MENDFUNC(2,test_l_rr,(R4 d, R4 s)) - -MIDFUNC(2,test_w_rr,(R2 d, R2 s)) -{ - CLOBBER_TEST; - d=readreg(d,2); - s=readreg(s,2); - - raw_test_w_rr(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,test_w_rr,(R2 d, R2 s)) - -MIDFUNC(2,test_b_rr,(R1 d, R1 s)) -{ - CLOBBER_TEST; - d=readreg(d,1); - s=readreg(s,1); - - raw_test_b_rr(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,test_b_rr,(R1 d, R1 s)) - - -MIDFUNC(2,and_l_ri,(RW4 d, IMM i)) -{ - if (isconst(d) && !needflags) { - live.state[d].val &= i; - return; - } - - CLOBBER_AND; - d=rmw(d,4,4); - - raw_and_l_ri(d,i); - unlock2(d); -} -MENDFUNC(2,and_l_ri,(RW4 d, IMM i)) - -MIDFUNC(2,and_l,(RW4 d, R4 s)) -{ - CLOBBER_AND; - s=readreg(s,4); - d=rmw(d,4,4); - - raw_and_l(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,and_l,(RW4 d, R4 s)) - -MIDFUNC(2,and_w,(RW2 d, R2 s)) -{ - CLOBBER_AND; - s=readreg(s,2); - d=rmw(d,2,2); - - raw_and_w(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,and_w,(RW2 d, R2 s)) - -MIDFUNC(2,and_b,(RW1 d, R1 s)) -{ - CLOBBER_AND; - s=readreg(s,1); - d=rmw(d,1,1); - - raw_and_b(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,and_b,(RW1 d, R1 s)) - -// gb-- used for making an fpcr value in compemu_fpp.cpp -MIDFUNC(2,or_l_rm,(RW4 d, IMM s)) -{ - CLOBBER_OR; - d=rmw(d,4,4); - - raw_or_l_rm(d,s); - unlock2(d); -} -MENDFUNC(2,or_l_rm,(RW4 d, IMM s)) - -MIDFUNC(2,or_l_ri,(RW4 d, IMM i)) -{ - if (isconst(d) && !needflags) { - live.state[d].val|=i; - return; - } - CLOBBER_OR; - d=rmw(d,4,4); - - raw_or_l_ri(d,i); - unlock2(d); -} -MENDFUNC(2,or_l_ri,(RW4 d, IMM i)) - -MIDFUNC(2,or_l,(RW4 d, R4 s)) -{ - if (isconst(d) && isconst(s) && !needflags) { - live.state[d].val|=live.state[s].val; - return; - } - CLOBBER_OR; - s=readreg(s,4); - d=rmw(d,4,4); - - raw_or_l(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,or_l,(RW4 d, R4 s)) - -MIDFUNC(2,or_w,(RW2 d, R2 s)) -{ - CLOBBER_OR; - s=readreg(s,2); - d=rmw(d,2,2); - - raw_or_w(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,or_w,(RW2 d, R2 s)) - -MIDFUNC(2,or_b,(RW1 d, R1 s)) -{ - CLOBBER_OR; - s=readreg(s,1); - d=rmw(d,1,1); - - raw_or_b(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,or_b,(RW1 d, R1 s)) - -MIDFUNC(2,adc_l,(RW4 d, R4 s)) -{ - CLOBBER_ADC; - s=readreg(s,4); - d=rmw(d,4,4); - - raw_adc_l(d,s); - - unlock2(d); - unlock2(s); -} -MENDFUNC(2,adc_l,(RW4 d, R4 s)) - -MIDFUNC(2,adc_w,(RW2 d, R2 s)) -{ - CLOBBER_ADC; - s=readreg(s,2); - d=rmw(d,2,2); - - raw_adc_w(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,adc_w,(RW2 d, R2 s)) - -MIDFUNC(2,adc_b,(RW1 d, R1 s)) -{ - CLOBBER_ADC; - s=readreg(s,1); - d=rmw(d,1,1); - - raw_adc_b(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,adc_b,(RW1 d, R1 s)) - -MIDFUNC(2,add_l,(RW4 d, R4 s)) -{ - if (isconst(s)) { - COMPCALL(add_l_ri)(d,live.state[s].val); - return; - } - - CLOBBER_ADD; - s=readreg(s,4); - d=rmw(d,4,4); - - raw_add_l(d,s); - - unlock2(d); - unlock2(s); -} -MENDFUNC(2,add_l,(RW4 d, R4 s)) - -MIDFUNC(2,add_w,(RW2 d, R2 s)) -{ - if (isconst(s)) { - COMPCALL(add_w_ri)(d,(uae_u16)live.state[s].val); - return; - } - - CLOBBER_ADD; - s=readreg(s,2); - d=rmw(d,2,2); - - raw_add_w(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,add_w,(RW2 d, R2 s)) - -MIDFUNC(2,add_b,(RW1 d, R1 s)) -{ - if (isconst(s)) { - COMPCALL(add_b_ri)(d,(uae_u8)live.state[s].val); - return; - } - - CLOBBER_ADD; - s=readreg(s,1); - d=rmw(d,1,1); - - raw_add_b(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,add_b,(RW1 d, R1 s)) - -MIDFUNC(2,sub_l_ri,(RW4 d, IMM i)) -{ - if (!i && !needflags) - return; - if (isconst(d) && !needflags) { - live.state[d].val-=i; - return; - } -#if USE_OFFSET - if (!needflags) { - add_offset(d,-i); - return; - } -#endif - - CLOBBER_SUB; - d=rmw(d,4,4); - - raw_sub_l_ri(d,i); - unlock2(d); -} -MENDFUNC(2,sub_l_ri,(RW4 d, IMM i)) - -MIDFUNC(2,sub_w_ri,(RW2 d, IMM i)) -{ - if (!i && !needflags) - return; - - CLOBBER_SUB; - d=rmw(d,2,2); - - raw_sub_w_ri(d,i); - unlock2(d); -} -MENDFUNC(2,sub_w_ri,(RW2 d, IMM i)) - -MIDFUNC(2,sub_b_ri,(RW1 d, IMM i)) -{ - if (!i && !needflags) - return; - - CLOBBER_SUB; - d=rmw(d,1,1); - - raw_sub_b_ri(d,i); - - unlock2(d); -} -MENDFUNC(2,sub_b_ri,(RW1 d, IMM i)) - -MIDFUNC(2,add_l_ri,(RW4 d, IMM i)) -{ - if (!i && !needflags) - return; - if (isconst(d) && !needflags) { - live.state[d].val+=i; - return; - } -#if USE_OFFSET - if (!needflags) { - add_offset(d,i); - return; - } -#endif - CLOBBER_ADD; - d=rmw(d,4,4); - raw_add_l_ri(d,i); - unlock2(d); -} -MENDFUNC(2,add_l_ri,(RW4 d, IMM i)) - -MIDFUNC(2,add_w_ri,(RW2 d, IMM i)) -{ - if (!i && !needflags) - return; - - CLOBBER_ADD; - d=rmw(d,2,2); - - raw_add_w_ri(d,i); - unlock2(d); -} -MENDFUNC(2,add_w_ri,(RW2 d, IMM i)) - -MIDFUNC(2,add_b_ri,(RW1 d, IMM i)) -{ - if (!i && !needflags) - return; - - CLOBBER_ADD; - d=rmw(d,1,1); - - raw_add_b_ri(d,i); - - unlock2(d); -} -MENDFUNC(2,add_b_ri,(RW1 d, IMM i)) - -MIDFUNC(2,sbb_l,(RW4 d, R4 s)) -{ - CLOBBER_SBB; - s=readreg(s,4); - d=rmw(d,4,4); - - raw_sbb_l(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,sbb_l,(RW4 d, R4 s)) - -MIDFUNC(2,sbb_w,(RW2 d, R2 s)) -{ - CLOBBER_SBB; - s=readreg(s,2); - d=rmw(d,2,2); - - raw_sbb_w(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,sbb_w,(RW2 d, R2 s)) - -MIDFUNC(2,sbb_b,(RW1 d, R1 s)) -{ - CLOBBER_SBB; - s=readreg(s,1); - d=rmw(d,1,1); - - raw_sbb_b(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,sbb_b,(RW1 d, R1 s)) - -MIDFUNC(2,sub_l,(RW4 d, R4 s)) -{ - if (isconst(s)) { - COMPCALL(sub_l_ri)(d,live.state[s].val); - return; - } - - CLOBBER_SUB; - s=readreg(s,4); - d=rmw(d,4,4); - - raw_sub_l(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,sub_l,(RW4 d, R4 s)) - -MIDFUNC(2,sub_w,(RW2 d, R2 s)) -{ - if (isconst(s)) { - COMPCALL(sub_w_ri)(d,(uae_u16)live.state[s].val); - return; - } - - CLOBBER_SUB; - s=readreg(s,2); - d=rmw(d,2,2); - - raw_sub_w(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,sub_w,(RW2 d, R2 s)) - -MIDFUNC(2,sub_b,(RW1 d, R1 s)) -{ - if (isconst(s)) { - COMPCALL(sub_b_ri)(d,(uae_u8)live.state[s].val); - return; - } - - CLOBBER_SUB; - s=readreg(s,1); - d=rmw(d,1,1); - - raw_sub_b(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,sub_b,(RW1 d, R1 s)) - -MIDFUNC(2,cmp_l,(R4 d, R4 s)) -{ - CLOBBER_CMP; - s=readreg(s,4); - d=readreg(d,4); - - raw_cmp_l(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,cmp_l,(R4 d, R4 s)) - -MIDFUNC(2,cmp_l_ri,(R4 r, IMM i)) -{ - CLOBBER_CMP; - r=readreg(r,4); - - raw_cmp_l_ri(r,i); - unlock2(r); -} -MENDFUNC(2,cmp_l_ri,(R4 r, IMM i)) - -MIDFUNC(2,cmp_w,(R2 d, R2 s)) -{ - CLOBBER_CMP; - s=readreg(s,2); - d=readreg(d,2); - - raw_cmp_w(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,cmp_w,(R2 d, R2 s)) - -MIDFUNC(2,cmp_b,(R1 d, R1 s)) -{ - CLOBBER_CMP; - s=readreg(s,1); - d=readreg(d,1); - - raw_cmp_b(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,cmp_b,(R1 d, R1 s)) - - -MIDFUNC(2,xor_l,(RW4 d, R4 s)) -{ - CLOBBER_XOR; - s=readreg(s,4); - d=rmw(d,4,4); - - raw_xor_l(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,xor_l,(RW4 d, R4 s)) - -MIDFUNC(2,xor_w,(RW2 d, R2 s)) -{ - CLOBBER_XOR; - s=readreg(s,2); - d=rmw(d,2,2); - - raw_xor_w(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,xor_w,(RW2 d, R2 s)) - -MIDFUNC(2,xor_b,(RW1 d, R1 s)) -{ - CLOBBER_XOR; - s=readreg(s,1); - d=rmw(d,1,1); - - raw_xor_b(d,s); - unlock2(d); - unlock2(s); -} -MENDFUNC(2,xor_b,(RW1 d, R1 s)) - -MIDFUNC(5,call_r_11,(W4 out1, R4 r, R4 in1, IMM osize, IMM isize)) -{ - clobber_flags(); - remove_all_offsets(); - if (osize==4) { - if (out1!=in1 && out1!=r) { - COMPCALL(forget_about)(out1); - } - } - else { - tomem_c(out1); - } - - in1=readreg_specific(in1,isize,REG_PAR1); - r=readreg(r,4); - prepare_for_call_1(); /* This should ensure that there won't be - any need for swapping nregs in prepare_for_call_2 - */ -#if USE_NORMAL_CALLING_CONVENTION - raw_push_l_r(in1); -#endif - unlock2(in1); - unlock2(r); - - prepare_for_call_2(); - raw_call_r(r); - -#if USE_NORMAL_CALLING_CONVENTION - raw_inc_sp(4); -#endif - - - live.nat[REG_RESULT].holds[0]=out1; - live.nat[REG_RESULT].nholds=1; - live.nat[REG_RESULT].touched=touchcnt++; - - live.state[out1].realreg=REG_RESULT; - live.state[out1].realind=0; - live.state[out1].val=0; - live.state[out1].validsize=osize; - live.state[out1].dirtysize=osize; - set_status(out1,DIRTY); -} -MENDFUNC(5,call_r_11,(W4 out1, R4 r, R4 in1, IMM osize, IMM isize)) - -MIDFUNC(5,call_r_02,(R4 r, R4 in1, R4 in2, IMM isize1, IMM isize2)) -{ - clobber_flags(); - remove_all_offsets(); - in1=readreg_specific(in1,isize1,REG_PAR1); - in2=readreg_specific(in2,isize2,REG_PAR2); - r=readreg(r,4); - prepare_for_call_1(); /* This should ensure that there won't be - any need for swapping nregs in prepare_for_call_2 - */ -#if USE_NORMAL_CALLING_CONVENTION - raw_push_l_r(in2); - raw_push_l_r(in1); -#endif - unlock2(r); - unlock2(in1); - unlock2(in2); - prepare_for_call_2(); - raw_call_r(r); -#if USE_NORMAL_CALLING_CONVENTION - raw_inc_sp(8); -#endif -} -MENDFUNC(5,call_r_02,(R4 r, R4 in1, R4 in2, IMM isize1, IMM isize2)) - -/* forget_about() takes a mid-layer register */ -MIDFUNC(1,forget_about,(W4 r)) -{ - if (isinreg(r)) - disassociate(r); - live.state[r].val=0; - set_status(r,UNDEF); -} -MENDFUNC(1,forget_about,(W4 r)) - -MIDFUNC(0,nop,(void)) -{ - raw_nop(); -} -MENDFUNC(0,nop,(void)) - - -MIDFUNC(1,f_forget_about,(FW r)) -{ - if (f_isinreg(r)) - f_disassociate(r); - live.fate[r].status=UNDEF; -} -MENDFUNC(1,f_forget_about,(FW r)) - -MIDFUNC(1,fmov_pi,(FW r)) -{ - r=f_writereg(r); - raw_fmov_pi(r); - f_unlock(r); -} -MENDFUNC(1,fmov_pi,(FW r)) - -MIDFUNC(1,fmov_log10_2,(FW r)) -{ - r=f_writereg(r); - raw_fmov_log10_2(r); - f_unlock(r); -} -MENDFUNC(1,fmov_log10_2,(FW r)) - -MIDFUNC(1,fmov_log2_e,(FW r)) -{ - r=f_writereg(r); - raw_fmov_log2_e(r); - f_unlock(r); -} -MENDFUNC(1,fmov_log2_e,(FW r)) - -MIDFUNC(1,fmov_loge_2,(FW r)) -{ - r=f_writereg(r); - raw_fmov_loge_2(r); - f_unlock(r); -} -MENDFUNC(1,fmov_loge_2,(FW r)) - -MIDFUNC(1,fmov_1,(FW r)) -{ - r=f_writereg(r); - raw_fmov_1(r); - f_unlock(r); -} -MENDFUNC(1,fmov_1,(FW r)) - -MIDFUNC(1,fmov_0,(FW r)) -{ - r=f_writereg(r); - raw_fmov_0(r); - f_unlock(r); -} -MENDFUNC(1,fmov_0,(FW r)) - -MIDFUNC(2,fmov_rm,(FW r, MEMR m)) -{ - r=f_writereg(r); - raw_fmov_rm(r,m); - f_unlock(r); -} -MENDFUNC(2,fmov_rm,(FW r, MEMR m)) - -MIDFUNC(2,fmovi_rm,(FW r, MEMR m)) -{ - r=f_writereg(r); - raw_fmovi_rm(r,m); - f_unlock(r); -} -MENDFUNC(2,fmovi_rm,(FW r, MEMR m)) - -MIDFUNC(2,fmovi_mr,(MEMW m, FR r)) -{ - r=f_readreg(r); - raw_fmovi_mr(m,r); - f_unlock(r); -} -MENDFUNC(2,fmovi_mr,(MEMW m, FR r)) - -MIDFUNC(2,fmovs_rm,(FW r, MEMR m)) -{ - r=f_writereg(r); - raw_fmovs_rm(r,m); - f_unlock(r); -} -MENDFUNC(2,fmovs_rm,(FW r, MEMR m)) - -MIDFUNC(2,fmovs_mr,(MEMW m, FR r)) -{ - r=f_readreg(r); - raw_fmovs_mr(m,r); - f_unlock(r); -} -MENDFUNC(2,fmovs_mr,(MEMW m, FR r)) - -MIDFUNC(2,fmov_ext_mr,(MEMW m, FR r)) -{ - r=f_readreg(r); - raw_fmov_ext_mr(m,r); - f_unlock(r); -} -MENDFUNC(2,fmov_ext_mr,(MEMW m, FR r)) - -MIDFUNC(2,fmov_mr,(MEMW m, FR r)) -{ - r=f_readreg(r); - raw_fmov_mr(m,r); - f_unlock(r); -} -MENDFUNC(2,fmov_mr,(MEMW m, FR r)) - -MIDFUNC(2,fmov_ext_rm,(FW r, MEMR m)) -{ - r=f_writereg(r); - raw_fmov_ext_rm(r,m); - f_unlock(r); -} -MENDFUNC(2,fmov_ext_rm,(FW r, MEMR m)) - -MIDFUNC(2,fmov_rr,(FW d, FR s)) -{ - if (d==s) { /* How pointless! */ - return; - } -#if USE_F_ALIAS - f_disassociate(d); - s=f_readreg(s); - live.fate[d].realreg=s; - live.fate[d].realind=live.fat[s].nholds; - live.fate[d].status=DIRTY; - live.fat[s].holds[live.fat[s].nholds]=d; - live.fat[s].nholds++; - f_unlock(s); -#else - s=f_readreg(s); - d=f_writereg(d); - raw_fmov_rr(d,s); - f_unlock(s); - f_unlock(d); -#endif -} -MENDFUNC(2,fmov_rr,(FW d, FR s)) - -MIDFUNC(2,fldcw_m_indexed,(R4 index, IMM base)) -{ - index=readreg(index,4); - - raw_fldcw_m_indexed(index,base); - unlock2(index); -} -MENDFUNC(2,fldcw_m_indexed,(R4 index, IMM base)) - -MIDFUNC(1,ftst_r,(FR r)) -{ - r=f_readreg(r); - raw_ftst_r(r); - f_unlock(r); -} -MENDFUNC(1,ftst_r,(FR r)) - -MIDFUNC(0,dont_care_fflags,(void)) -{ - f_disassociate(FP_RESULT); -} -MENDFUNC(0,dont_care_fflags,(void)) - -MIDFUNC(2,fsqrt_rr,(FW d, FR s)) -{ - s=f_readreg(s); - d=f_writereg(d); - raw_fsqrt_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,fsqrt_rr,(FW d, FR s)) - -MIDFUNC(2,fabs_rr,(FW d, FR s)) -{ - s=f_readreg(s); - d=f_writereg(d); - raw_fabs_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,fabs_rr,(FW d, FR s)) - -MIDFUNC(2,fsin_rr,(FW d, FR s)) -{ - s=f_readreg(s); - d=f_writereg(d); - raw_fsin_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,fsin_rr,(FW d, FR s)) - -MIDFUNC(2,fcos_rr,(FW d, FR s)) -{ - s=f_readreg(s); - d=f_writereg(d); - raw_fcos_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,fcos_rr,(FW d, FR s)) - -MIDFUNC(2,ftwotox_rr,(FW d, FR s)) -{ - s=f_readreg(s); - d=f_writereg(d); - raw_ftwotox_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,ftwotox_rr,(FW d, FR s)) - -MIDFUNC(2,fetox_rr,(FW d, FR s)) -{ - s=f_readreg(s); - d=f_writereg(d); - raw_fetox_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,fetox_rr,(FW d, FR s)) - -MIDFUNC(2,frndint_rr,(FW d, FR s)) -{ - s=f_readreg(s); - d=f_writereg(d); - raw_frndint_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,frndint_rr,(FW d, FR s)) - -MIDFUNC(2,flog2_rr,(FW d, FR s)) -{ - s=f_readreg(s); - d=f_writereg(d); - raw_flog2_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,flog2_rr,(FW d, FR s)) - -MIDFUNC(2,fneg_rr,(FW d, FR s)) -{ - s=f_readreg(s); - d=f_writereg(d); - raw_fneg_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,fneg_rr,(FW d, FR s)) - -MIDFUNC(2,fadd_rr,(FRW d, FR s)) -{ - s=f_readreg(s); - d=f_rmw(d); - raw_fadd_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,fadd_rr,(FRW d, FR s)) - -MIDFUNC(2,fsub_rr,(FRW d, FR s)) -{ - s=f_readreg(s); - d=f_rmw(d); - raw_fsub_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,fsub_rr,(FRW d, FR s)) - -MIDFUNC(2,fcmp_rr,(FR d, FR s)) -{ - d=f_readreg(d); - s=f_readreg(s); - raw_fcmp_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,fcmp_rr,(FR d, FR s)) - -MIDFUNC(2,fdiv_rr,(FRW d, FR s)) -{ - s=f_readreg(s); - d=f_rmw(d); - raw_fdiv_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,fdiv_rr,(FRW d, FR s)) - -MIDFUNC(2,frem_rr,(FRW d, FR s)) -{ - s=f_readreg(s); - d=f_rmw(d); - raw_frem_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,frem_rr,(FRW d, FR s)) - -MIDFUNC(2,frem1_rr,(FRW d, FR s)) -{ - s=f_readreg(s); - d=f_rmw(d); - raw_frem1_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,frem1_rr,(FRW d, FR s)) - -MIDFUNC(2,fmul_rr,(FRW d, FR s)) -{ - s=f_readreg(s); - d=f_rmw(d); - raw_fmul_rr(d,s); - f_unlock(s); - f_unlock(d); -} -MENDFUNC(2,fmul_rr,(FRW d, FR s)) - -/******************************************************************** - * Support functions exposed to gencomp. CREATE time * - ********************************************************************/ - -void set_zero(int r, int tmp) -{ - if (setzflg_uses_bsf) - bsf_l_rr(r,r); - else - simulate_bsf(tmp,r); -} - -int kill_rodent(int r) -{ - return KILLTHERAT && - have_rat_stall && - (live.state[r].status==INMEM || - live.state[r].status==CLEAN || - live.state[r].status==ISCONST || - live.state[r].dirtysize==4); -} - -uae_u32 get_const(int r) -{ - Dif (!isconst(r)) { - write_log("Register %d should be constant, but isn't\n",r); - abort(); - } - return live.state[r].val; -} - -void sync_m68k_pc(void) -{ - if (m68k_pc_offset) { - add_l_ri(PC_P,m68k_pc_offset); - comp_pc_p+=m68k_pc_offset; - m68k_pc_offset=0; - } -} - -/******************************************************************** - * Scratch registers management * - ********************************************************************/ - -struct scratch_t { - uae_u32 regs[VREGS]; - fpu_register fregs[VFREGS]; -}; - -static scratch_t scratch; - -/******************************************************************** - * Support functions exposed to newcpu * - ********************************************************************/ - -static inline const char *str_on_off(bool b) -{ - return b ? "on" : "off"; -} - -void compiler_init(void) -{ - static bool initialized = false; - if (initialized) - return; - -#if JIT_DEBUG - // JIT debug mode ? - JITDebug = PrefsFindBool("jitdebug"); -#endif - write_log(" : enable runtime disassemblers : %s\n", JITDebug ? "yes" : "no"); - -#ifdef USE_JIT_FPU - // Use JIT compiler for FPU instructions ? - avoid_fpu = !PrefsFindBool("jitfpu"); -#else - // JIT FPU is always disabled - avoid_fpu = true; -#endif - write_log(" : compile FPU instructions : %s\n", !avoid_fpu ? "yes" : "no"); - - // Get size of the translation cache (in KB) - cache_size = PrefsFindInt32("jitcachesize"); - write_log(" : requested translation cache size : %d KB\n", cache_size); - - // Initialize target CPU (check for features, e.g. CMOV, rat stalls) - raw_init_cpu(); - setzflg_uses_bsf = target_check_bsf(); - write_log(" : target processor has CMOV instructions : %s\n", have_cmov ? "yes" : "no"); - write_log(" : target processor can suffer from partial register stalls : %s\n", have_rat_stall ? "yes" : "no"); - write_log(" : alignment for loops, jumps are %d, %d\n", align_loops, align_jumps); - - // Translation cache flush mechanism - lazy_flush = PrefsFindBool("jitlazyflush"); - write_log(" : lazy translation cache invalidation : %s\n", str_on_off(lazy_flush)); - flush_icache = lazy_flush ? flush_icache_lazy : flush_icache_hard; - - // Compiler features - write_log(" : register aliasing : %s\n", str_on_off(1)); - write_log(" : FP register aliasing : %s\n", str_on_off(USE_F_ALIAS)); - write_log(" : lazy constant offsetting : %s\n", str_on_off(USE_OFFSET)); -#if USE_INLINING - follow_const_jumps = PrefsFindBool("jitinline"); -#endif - write_log(" : translate through constant jumps : %s\n", str_on_off(follow_const_jumps)); - write_log(" : separate blockinfo allocation : %s\n", str_on_off(USE_SEPARATE_BIA)); - - // Build compiler tables - build_comp(); - - initialized = true; - -#if PROFILE_UNTRANSLATED_INSNS - write_log(" : gather statistics on untranslated insns count\n"); -#endif - -#if PROFILE_COMPILE_TIME - write_log(" : gather statistics on translation time\n"); - emul_start_time = clock(); -#endif -} - -void compiler_exit(void) -{ -#if PROFILE_COMPILE_TIME - emul_end_time = clock(); -#endif - - // Deallocate translation cache - if (compiled_code) { - vm_release(compiled_code, cache_size * 1024); - compiled_code = 0; - } - - // Deallocate popallspace - if (popallspace) { - vm_release(popallspace, POPALLSPACE_SIZE); - popallspace = 0; - } - -#if PROFILE_COMPILE_TIME - write_log("### Compile Block statistics\n"); - write_log("Number of calls to compile_block : %d\n", compile_count); - uae_u32 emul_time = emul_end_time - emul_start_time; - write_log("Total emulation time : %.1f sec\n", double(emul_time)/double(CLOCKS_PER_SEC)); - write_log("Total compilation time : %.1f sec (%.1f%%)\n", double(compile_time)/double(CLOCKS_PER_SEC), - 100.0*double(compile_time)/double(emul_time)); - write_log("\n"); -#endif - -#if PROFILE_UNTRANSLATED_INSNS - uae_u64 untranslated_count = 0; - for (int i = 0; i < 65536; i++) { - opcode_nums[i] = i; - untranslated_count += raw_cputbl_count[i]; - } - write_log("Sorting out untranslated instructions count...\n"); - qsort(opcode_nums, 65536, sizeof(uae_u16), untranslated_compfn); - write_log("\nRank Opc Count Name\n"); - for (int i = 0; i < untranslated_top_ten; i++) { - uae_u32 count = raw_cputbl_count[opcode_nums[i]]; - struct instr *dp; - struct mnemolookup *lookup; - if (!count) - break; - dp = table68k + opcode_nums[i]; - for (lookup = lookuptab; lookup->mnemo != dp->mnemo; lookup++) - ; - write_log("%03d: %04x %10lu %s\n", i, opcode_nums[i], count, lookup->name); - } -#endif - -#if RECORD_REGISTER_USAGE - int reg_count_ids[16]; - uint64 tot_reg_count = 0; - for (int i = 0; i < 16; i++) { - reg_count_ids[i] = i; - tot_reg_count += reg_count[i]; - } - qsort(reg_count_ids, 16, sizeof(int), reg_count_compare); - uint64 cum_reg_count = 0; - for (int i = 0; i < 16; i++) { - int r = reg_count_ids[i]; - cum_reg_count += reg_count[r]; - printf("%c%d : %16ld %2.1f%% [%2.1f]\n", r < 8 ? 'D' : 'A', r % 8, - reg_count[r], - 100.0*double(reg_count[r])/double(tot_reg_count), - 100.0*double(cum_reg_count)/double(tot_reg_count)); - } -#endif -} - -bool compiler_use_jit(void) -{ - // Check for the "jit" prefs item - if (!PrefsFindBool("jit")) - return false; - - // Don't use JIT if translation cache size is less then MIN_CACHE_SIZE KB - if (PrefsFindInt32("jitcachesize") < MIN_CACHE_SIZE) { - write_log(" : translation cache size is less than %d KB. Disabling JIT.\n", MIN_CACHE_SIZE); - return false; - } - - // Enable JIT for 68020+ emulation only - if (CPUType < 2) { - write_log(" : JIT is not supported in 680%d0 emulation mode, disabling.\n", CPUType); - return false; - } - - return true; -} - -void init_comp(void) -{ - int i; - uae_s8* cb=can_byte; - uae_s8* cw=can_word; - uae_s8* au=always_used; - -#if RECORD_REGISTER_USAGE - for (i=0;i<16;i++) - reg_count_local[i] = 0; -#endif - - for (i=0;i= (uintptr)ROMBaseHost) && (addr < (uintptr)ROMBaseHost + ROMSize)); -} - -static void flush_all(void) -{ - int i; - - log_flush(); - for (i=0;i0) - free_nreg(i); - - for (i=0;i0) - f_free_nreg(i); - - live.flags_in_flags=TRASH; /* Note: We assume we already rescued the - flags at the very start of the call_r - functions! */ -} - -/******************************************************************** - * Memory access and related functions, CREATE time * - ********************************************************************/ - -void register_branch(uae_u32 not_taken, uae_u32 taken, uae_u8 cond) -{ - next_pc_p=not_taken; - taken_pc_p=taken; - branch_cc=cond; -} - - -static uae_u32 get_handler_address(uae_u32 addr) -{ - uae_u32 cl=cacheline(addr); - blockinfo* bi=get_blockinfo_addr_new((void*)(uintptr)addr,0); - return (uintptr)&(bi->direct_handler_to_use); -} - -static uae_u32 get_handler(uae_u32 addr) -{ - uae_u32 cl=cacheline(addr); - blockinfo* bi=get_blockinfo_addr_new((void*)(uintptr)addr,0); - return (uintptr)bi->direct_handler_to_use; -} - -static void load_handler(int reg, uae_u32 addr) -{ - mov_l_rm(reg,get_handler_address(addr)); -} - -/* This version assumes that it is writing *real* memory, and *will* fail - * if that assumption is wrong! No branches, no second chances, just - * straight go-for-it attitude */ - -static void writemem_real(int address, int source, int size, int tmp, int clobber) -{ - int f=tmp; - - if (clobber) - f=source; - - switch(size) { - case 1: mov_b_bRr(address,source,MEMBaseDiff); break; - case 2: mov_w_rr(f,source); bswap_16(f); mov_w_bRr(address,f,MEMBaseDiff); break; - case 4: mov_l_rr(f,source); bswap_32(f); mov_l_bRr(address,f,MEMBaseDiff); break; - } - forget_about(tmp); - forget_about(f); -} - -void writebyte(int address, int source, int tmp) -{ - writemem_real(address,source,1,tmp,0); -} - -static __inline__ void writeword_general(int address, int source, int tmp, - int clobber) -{ - writemem_real(address,source,2,tmp,clobber); -} - -void writeword_clobber(int address, int source, int tmp) -{ - writeword_general(address,source,tmp,1); -} - -void writeword(int address, int source, int tmp) -{ - writeword_general(address,source,tmp,0); -} - -static __inline__ void writelong_general(int address, int source, int tmp, - int clobber) -{ - writemem_real(address,source,4,tmp,clobber); -} - -void writelong_clobber(int address, int source, int tmp) -{ - writelong_general(address,source,tmp,1); -} - -void writelong(int address, int source, int tmp) -{ - writelong_general(address,source,tmp,0); -} - - - -/* This version assumes that it is reading *real* memory, and *will* fail - * if that assumption is wrong! No branches, no second chances, just - * straight go-for-it attitude */ - -static void readmem_real(int address, int dest, int size, int tmp) -{ - int f=tmp; - - if (size==4 && address!=dest) - f=dest; - - switch(size) { - case 1: mov_b_brR(dest,address,MEMBaseDiff); break; - case 2: mov_w_brR(dest,address,MEMBaseDiff); bswap_16(dest); break; - case 4: mov_l_brR(dest,address,MEMBaseDiff); bswap_32(dest); break; - } - forget_about(tmp); -} - -void readbyte(int address, int dest, int tmp) -{ - readmem_real(address,dest,1,tmp); -} - -void readword(int address, int dest, int tmp) -{ - readmem_real(address,dest,2,tmp); -} - -void readlong(int address, int dest, int tmp) -{ - readmem_real(address,dest,4,tmp); -} - -void get_n_addr(int address, int dest, int tmp) -{ - // a is the register containing the virtual address - // after the offset had been fetched - int a=tmp; - - // f is the register that will contain the offset - int f=tmp; - - // a == f == tmp if (address == dest) - if (address!=dest) { - a=address; - f=dest; - } - -#if REAL_ADDRESSING - mov_l_rr(dest, address); -#elif DIRECT_ADDRESSING - lea_l_brr(dest,address,MEMBaseDiff); -#endif - forget_about(tmp); -} - -void get_n_addr_jmp(int address, int dest, int tmp) -{ - /* For this, we need to get the same address as the rest of UAE - would --- otherwise we end up translating everything twice */ - get_n_addr(address,dest,tmp); -} - - -/* base is a register, but dp is an actual value. - target is a register, as is tmp */ -void calc_disp_ea_020(int base, uae_u32 dp, int target, int tmp) -{ - int reg = (dp >> 12) & 15; - int regd_shift=(dp >> 9) & 3; - - if (dp & 0x100) { - int ignorebase=(dp&0x80); - int ignorereg=(dp&0x40); - int addbase=0; - int outer=0; - - if ((dp & 0x30) == 0x20) addbase = (uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); - if ((dp & 0x30) == 0x30) addbase = comp_get_ilong((m68k_pc_offset+=4)-4); - - if ((dp & 0x3) == 0x2) outer = (uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); - if ((dp & 0x3) == 0x3) outer = comp_get_ilong((m68k_pc_offset+=4)-4); - - if ((dp & 0x4) == 0) { /* add regd *before* the get_long */ - if (!ignorereg) { - if ((dp & 0x800) == 0) - sign_extend_16_rr(target,reg); - else - mov_l_rr(target,reg); - shll_l_ri(target,regd_shift); - } - else - mov_l_ri(target,0); - - /* target is now regd */ - if (!ignorebase) - add_l(target,base); - add_l_ri(target,addbase); - if (dp&0x03) readlong(target,target,tmp); - } else { /* do the getlong first, then add regd */ - if (!ignorebase) { - mov_l_rr(target,base); - add_l_ri(target,addbase); - } - else - mov_l_ri(target,addbase); - if (dp&0x03) readlong(target,target,tmp); - - if (!ignorereg) { - if ((dp & 0x800) == 0) - sign_extend_16_rr(tmp,reg); - else - mov_l_rr(tmp,reg); - shll_l_ri(tmp,regd_shift); - /* tmp is now regd */ - add_l(target,tmp); - } - } - add_l_ri(target,outer); - } - else { /* 68000 version */ - if ((dp & 0x800) == 0) { /* Sign extend */ - sign_extend_16_rr(target,reg); - lea_l_brr_indexed(target,base,target,1<= CODE_ALLOC_MAX_ATTEMPTS) - return NULL; - - return do_alloc_code(size, depth + 1); -#else - uint8 *code = (uint8 *)vm_acquire(size); - return code == VM_MAP_FAILED ? NULL : code; -#endif -} - -static inline uint8 *alloc_code(uint32 size) -{ - uint8 *ptr = do_alloc_code(size, 0); - /* allocated code must fit in 32-bit boundaries */ - assert((uintptr)ptr <= 0xffffffff); - return ptr; -} - -void alloc_cache(void) -{ - if (compiled_code) { - flush_icache_hard(6); - vm_release(compiled_code, cache_size * 1024); - compiled_code = 0; - } - - if (cache_size == 0) - return; - - while (!compiled_code && cache_size) { - if ((compiled_code = alloc_code(cache_size * 1024)) == NULL) { - compiled_code = 0; - cache_size /= 2; - } - } - vm_protect(compiled_code, cache_size * 1024, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE); - - if (compiled_code) { - write_log(" : actual translation cache size : %d KB at 0x%08X\n", cache_size, compiled_code); - max_compile_start = compiled_code + cache_size*1024 - BYTES_PER_INST; - current_compile_p = compiled_code; - current_cache_size = 0; - } -} - - - -extern void op_illg_1 (uae_u32 opcode) REGPARAM; - -static void calc_checksum(blockinfo* bi, uae_u32* c1, uae_u32* c2) -{ - uae_u32 k1 = 0; - uae_u32 k2 = 0; - -#if USE_CHECKSUM_INFO - checksum_info *csi = bi->csi; - Dif(!csi) abort(); - while (csi) { - uae_s32 len = csi->length; - uintptr tmp = (uintptr)csi->start_p; -#else - uae_s32 len = bi->len; - uintptr tmp = (uintptr)bi->min_pcp; -#endif - uae_u32*pos; - - len += (tmp & 3); - tmp &= ~((uintptr)3); - pos = (uae_u32 *)tmp; - - if (len >= 0 && len <= MAX_CHECKSUM_LEN) { - while (len > 0) { - k1 += *pos; - k2 ^= *pos; - pos++; - len -= 4; - } - } - -#if USE_CHECKSUM_INFO - csi = csi->next; - } -#endif - - *c1 = k1; - *c2 = k2; -} - -#if 0 -static void show_checksum(CSI_TYPE* csi) -{ - uae_u32 k1=0; - uae_u32 k2=0; - uae_s32 len=CSI_LENGTH(csi); - uae_u32 tmp=(uintptr)CSI_STARTcsi - uae_u32* pos; - - len+=(tmp&3); - tmp&=(~3); - pos=(uae_u32*)tmp; - - if (len<0 || len>MAX_CHECKSUM_LEN) { - return; - } - else { - while (len>0) { - write_log("%08x ",*pos); - pos++; - len-=4; - } - write_log(" bla\n"); - } -} -#endif - - -int check_for_cache_miss(void) -{ - blockinfo* bi=get_blockinfo_addr(regs.pc_p); - - if (bi) { - int cl=cacheline(regs.pc_p); - if (bi!=cache_tags[cl+1].bi) { - raise_in_cl_list(bi); - return 1; - } - } - return 0; -} - - -static void recompile_block(void) -{ - /* An existing block's countdown code has expired. We need to make - sure that execute_normal doesn't refuse to recompile due to a - perceived cache miss... */ - blockinfo* bi=get_blockinfo_addr(regs.pc_p); - - Dif (!bi) - abort(); - raise_in_cl_list(bi); - execute_normal(); - return; -} -static void cache_miss(void) -{ - blockinfo* bi=get_blockinfo_addr(regs.pc_p); - uae_u32 cl=cacheline(regs.pc_p); - blockinfo* bi2=get_blockinfo(cl); - - if (!bi) { - execute_normal(); /* Compile this block now */ - return; - } - Dif (!bi2 || bi==bi2) { - write_log("Unexplained cache miss %p %p\n",bi,bi2); - abort(); - } - raise_in_cl_list(bi); - return; -} - -static int called_check_checksum(blockinfo* bi); - -static inline int block_check_checksum(blockinfo* bi) -{ - uae_u32 c1,c2; - bool isgood; - - if (bi->status!=BI_NEED_CHECK) - return 1; /* This block is in a checked state */ - - checksum_count++; - - if (bi->c1 || bi->c2) - calc_checksum(bi,&c1,&c2); - else { - c1=c2=1; /* Make sure it doesn't match */ - } - - isgood=(c1==bi->c1 && c2==bi->c2); - - if (isgood) { - /* This block is still OK. So we reactivate. Of course, that - means we have to move it into the needs-to-be-flushed list */ - bi->handler_to_use=bi->handler; - set_dhtu(bi,bi->direct_handler); - bi->status=BI_CHECKING; - isgood=called_check_checksum(bi) != 0; - } - if (isgood) { - /* write_log("reactivate %p/%p (%x %x/%x %x)\n",bi,bi->pc_p, - c1,c2,bi->c1,bi->c2);*/ - remove_from_list(bi); - add_to_active(bi); - raise_in_cl_list(bi); - bi->status=BI_ACTIVE; - } - else { - /* This block actually changed. We need to invalidate it, - and set it up to be recompiled */ - /* write_log("discard %p/%p (%x %x/%x %x)\n",bi,bi->pc_p, - c1,c2,bi->c1,bi->c2); */ - invalidate_block(bi); - raise_in_cl_list(bi); - } - return isgood; -} - -static int called_check_checksum(blockinfo* bi) -{ - dependency* x=bi->deplist; - int isgood=1; - int i; - - for (i=0;i<2 && isgood;i++) { - if (bi->dep[i].jmp_off) { - isgood=block_check_checksum(bi->dep[i].target); - } - } - return isgood; -} - -static void check_checksum(void) -{ - blockinfo* bi=get_blockinfo_addr(regs.pc_p); - uae_u32 cl=cacheline(regs.pc_p); - blockinfo* bi2=get_blockinfo(cl); - - /* These are not the droids you are looking for... */ - if (!bi) { - /* Whoever is the primary target is in a dormant state, but - calling it was accidental, and we should just compile this - new block */ - execute_normal(); - return; - } - if (bi!=bi2) { - /* The block was hit accidentally, but it does exist. Cache miss */ - cache_miss(); - return; - } - - if (!block_check_checksum(bi)) - execute_normal(); -} - -static __inline__ void match_states(blockinfo* bi) -{ - int i; - smallstate* s=&(bi->env); - - if (bi->status==BI_NEED_CHECK) { - block_check_checksum(bi); - } - if (bi->status==BI_ACTIVE || - bi->status==BI_FINALIZING) { /* Deal with the *promises* the - block makes (about not using - certain vregs) */ - for (i=0;i<16;i++) { - if (s->virt[i]==L_UNNEEDED) { - // write_log("unneeded reg %d at %p\n",i,target); - COMPCALL(forget_about)(i); // FIXME - } - } - } - flush(1); - - /* And now deal with the *demands* the block makes */ - for (i=0;inat[i]; - if (v>=0) { - // printf("Loading reg %d into %d at %p\n",v,i,target); - readreg_specific(v,4,i); - // do_load_reg(i,v); - // setlock(i); - } - } - for (i=0;inat[i]; - if (v>=0) { - unlock2(i); - } - } -} - -static __inline__ void create_popalls(void) -{ - int i,r; - - if ((popallspace = alloc_code(POPALLSPACE_SIZE)) == NULL) { - write_log("FATAL: Could not allocate popallspace!\n"); - abort(); - } - vm_protect(popallspace, POPALLSPACE_SIZE, VM_PAGE_READ | VM_PAGE_WRITE); - - int stack_space = STACK_OFFSET; - for (i=0;idirect_pen=(cpuop_func *)get_target(); - raw_mov_l_rm(0,(uintptr)&(bi->pc_p)); - raw_mov_l_mr((uintptr)®s.pc_p,0); - raw_jmp((uintptr)popall_execute_normal); - - align_target(align_jumps); - bi->direct_pcc=(cpuop_func *)get_target(); - raw_mov_l_rm(0,(uintptr)&(bi->pc_p)); - raw_mov_l_mr((uintptr)®s.pc_p,0); - raw_jmp((uintptr)popall_check_checksum); - current_compile_p=get_target(); - - bi->deplist=NULL; - for (i=0;i<2;i++) { - bi->dep[i].prev_p=NULL; - bi->dep[i].next=NULL; - } - bi->env=default_ss; - bi->status=BI_INVALID; - bi->havestate=0; - //bi->env=empty_ss; -} - -// OPCODE is in big endian format, use cft_map() beforehand, if needed. -static inline void reset_compop(int opcode) -{ - compfunctbl[opcode] = NULL; - nfcompfunctbl[opcode] = NULL; -} - -static int read_opcode(const char *p) -{ - int opcode = 0; - for (int i = 0; i < 4; i++) { - int op = p[i]; - switch (op) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - opcode = (opcode << 4) | (op - '0'); - break; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - opcode = (opcode << 4) | ((op - 'a') + 10); - break; - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - opcode = (opcode << 4) | ((op - 'A') + 10); - break; - default: - return -1; - } - } - return opcode; -} - -static bool merge_blacklist() -{ - const char *blacklist = PrefsFindString("jitblacklist"); - if (blacklist) { - const char *p = blacklist; - for (;;) { - if (*p == 0) - return true; - - int opcode1 = read_opcode(p); - if (opcode1 < 0) - return false; - p += 4; - - int opcode2 = opcode1; - if (*p == '-') { - p++; - opcode2 = read_opcode(p); - if (opcode2 < 0) - return false; - p += 4; - } - - if (*p == 0 || *p == ',' || *p == ';') { - write_log(" : blacklist opcodes : %04x-%04x\n", opcode1, opcode2); - for (int opcode = opcode1; opcode <= opcode2; opcode++) - reset_compop(cft_map(opcode)); - - if (*p == ',' || *p++ == ';') - continue; - - return true; - } - - return false; - } - } - return true; -} - -void build_comp(void) -{ - int i; - int jumpcount=0; - unsigned long opcode; - struct comptbl* tbl=op_smalltbl_0_comp_ff; - struct comptbl* nftbl=op_smalltbl_0_comp_nf; - int count; - unsigned int cpu_level = 0; // 68000 (default) - if (CPUType == 4) - cpu_level = 4; // 68040 with FPU - else { - if (FPUType) - cpu_level = 3; // 68020 with FPU - else if (CPUType >= 2) - cpu_level = 2; // 68020 - else if (CPUType == 1) - cpu_level = 1; - } - struct cputbl *nfctbl = ( - cpu_level == 4 ? op_smalltbl_0_nf - : cpu_level == 3 ? op_smalltbl_1_nf - : cpu_level == 2 ? op_smalltbl_2_nf - : cpu_level == 1 ? op_smalltbl_3_nf - : op_smalltbl_4_nf); - - write_log (" : building compiler function tables\n"); - - for (opcode = 0; opcode < 65536; opcode++) { - reset_compop(opcode); - nfcpufunctbl[opcode] = op_illg_1; - prop[opcode].use_flags = 0x1f; - prop[opcode].set_flags = 0x1f; - prop[opcode].cflow = fl_trap; // ILLEGAL instructions do trap - } - - for (i = 0; tbl[i].opcode < 65536; i++) { - int cflow = table68k[tbl[i].opcode].cflow; - if (follow_const_jumps && (tbl[i].specific & 16)) - cflow = fl_const_jump; - else - cflow &= ~fl_const_jump; - prop[cft_map(tbl[i].opcode)].cflow = cflow; - - int uses_fpu = tbl[i].specific & 32; - if (uses_fpu && avoid_fpu) - compfunctbl[cft_map(tbl[i].opcode)] = NULL; - else - compfunctbl[cft_map(tbl[i].opcode)] = tbl[i].handler; - } - - for (i = 0; nftbl[i].opcode < 65536; i++) { - int uses_fpu = tbl[i].specific & 32; - if (uses_fpu && avoid_fpu) - nfcompfunctbl[cft_map(nftbl[i].opcode)] = NULL; - else - nfcompfunctbl[cft_map(nftbl[i].opcode)] = nftbl[i].handler; - - nfcpufunctbl[cft_map(nftbl[i].opcode)] = nfctbl[i].handler; - } - - for (i = 0; nfctbl[i].handler; i++) { - nfcpufunctbl[cft_map(nfctbl[i].opcode)] = nfctbl[i].handler; - } - - for (opcode = 0; opcode < 65536; opcode++) { - compop_func *f; - compop_func *nff; - cpuop_func *nfcf; - int isaddx,cflow; - - if (table68k[opcode].mnemo == i_ILLG || table68k[opcode].clev > cpu_level) - continue; - - if (table68k[opcode].handler != -1) { - f = compfunctbl[cft_map(table68k[opcode].handler)]; - nff = nfcompfunctbl[cft_map(table68k[opcode].handler)]; - nfcf = nfcpufunctbl[cft_map(table68k[opcode].handler)]; - cflow = prop[cft_map(table68k[opcode].handler)].cflow; - isaddx = prop[cft_map(table68k[opcode].handler)].is_addx; - prop[cft_map(opcode)].cflow = cflow; - prop[cft_map(opcode)].is_addx = isaddx; - compfunctbl[cft_map(opcode)] = f; - nfcompfunctbl[cft_map(opcode)] = nff; - Dif (nfcf == op_illg_1) - abort(); - nfcpufunctbl[cft_map(opcode)] = nfcf; - } - prop[cft_map(opcode)].set_flags = table68k[opcode].flagdead; - prop[cft_map(opcode)].use_flags = table68k[opcode].flaglive; - /* Unconditional jumps don't evaluate condition codes, so they - * don't actually use any flags themselves */ - if (prop[cft_map(opcode)].cflow & fl_const_jump) - prop[cft_map(opcode)].use_flags = 0; - } - for (i = 0; nfctbl[i].handler != NULL; i++) { - if (nfctbl[i].specific) - nfcpufunctbl[cft_map(tbl[i].opcode)] = nfctbl[i].handler; - } - - /* Merge in blacklist */ - if (!merge_blacklist()) - write_log(" : blacklist merge failure!\n"); - - count=0; - for (opcode = 0; opcode < 65536; opcode++) { - if (compfunctbl[cft_map(opcode)]) - count++; - } - write_log(" : supposedly %d compileable opcodes!\n",count); - - /* Initialise state */ - create_popalls(); - alloc_cache(); - reset_lists(); - - for (i=0;ipc_p)].handler=(cpuop_func *)popall_execute_normal; - cache_tags[cacheline(bi->pc_p)+1].bi=NULL; - dbi=bi; bi=bi->next; - free_blockinfo(dbi); - } - bi=dormant; - while(bi) { - cache_tags[cacheline(bi->pc_p)].handler=(cpuop_func *)popall_execute_normal; - cache_tags[cacheline(bi->pc_p)+1].bi=NULL; - dbi=bi; bi=bi->next; - free_blockinfo(dbi); - } - - reset_lists(); - if (!compiled_code) - return; - current_compile_p=compiled_code; - SPCFLAGS_SET( SPCFLAG_JIT_EXEC_RETURN ); /* To get out of compiled code */ -} - - -/* "Soft flushing" --- instead of actually throwing everything away, - we simply mark everything as "needs to be checked". -*/ - -static inline void flush_icache_lazy(int n) -{ - blockinfo* bi; - blockinfo* bi2; - - soft_flush_count++; - if (!active) - return; - - bi=active; - while (bi) { - uae_u32 cl=cacheline(bi->pc_p); - if (bi->status==BI_INVALID || - bi->status==BI_NEED_RECOMP) { - if (bi==cache_tags[cl+1].bi) - cache_tags[cl].handler=(cpuop_func *)popall_execute_normal; - bi->handler_to_use=(cpuop_func *)popall_execute_normal; - set_dhtu(bi,bi->direct_pen); - bi->status=BI_INVALID; - } - else { - if (bi==cache_tags[cl+1].bi) - cache_tags[cl].handler=(cpuop_func *)popall_check_checksum; - bi->handler_to_use=(cpuop_func *)popall_check_checksum; - set_dhtu(bi,bi->direct_pcc); - bi->status=BI_NEED_CHECK; - } - bi2=bi; - bi=bi->next; - } - /* bi2 is now the last entry in the active list */ - bi2->next=dormant; - if (dormant) - dormant->prev_p=&(bi2->next); - - dormant=active; - active->prev_p=&dormant; - active=NULL; -} - -void flush_icache_range(uae_u8 *start_p, uae_u32 length) -{ - if (!active) - return; - -#if LAZY_FLUSH_ICACHE_RANGE - blockinfo *bi = active; - while (bi) { -#if USE_CHECKSUM_INFO - bool candidate = false; - for (checksum_info *csi = bi->csi; csi; csi = csi->next) { - if (((start_p - csi->start_p) < csi->length) || - ((csi->start_p - start_p) < length)) { - candidate = true; - break; - } - } -#else - // Assume system is consistent and would invalidate the right range - const bool candidate = (bi->pc_p - start_p) < length; -#endif - blockinfo *dbi = bi; - bi = bi->next; - if (candidate) { - uae_u32 cl = cacheline(dbi->pc_p); - if (dbi->status == BI_INVALID || dbi->status == BI_NEED_RECOMP) { - if (dbi == cache_tags[cl+1].bi) - cache_tags[cl].handler = (cpuop_func *)popall_execute_normal; - dbi->handler_to_use = (cpuop_func *)popall_execute_normal; - set_dhtu(dbi, dbi->direct_pen); - dbi->status = BI_INVALID; - } - else { - if (dbi == cache_tags[cl+1].bi) - cache_tags[cl].handler = (cpuop_func *)popall_check_checksum; - dbi->handler_to_use = (cpuop_func *)popall_check_checksum; - set_dhtu(dbi, dbi->direct_pcc); - dbi->status = BI_NEED_CHECK; - } - remove_from_list(dbi); - add_to_dormant(dbi); - } - } - return; -#endif - flush_icache(-1); -} - -static void catastrophe(void) -{ - abort(); -} - -int failure; - -#define TARGET_M68K 0 -#define TARGET_POWERPC 1 -#define TARGET_X86 2 -#define TARGET_X86_64 3 -#if defined(i386) || defined(__i386__) -#define TARGET_NATIVE TARGET_X86 -#endif -#if defined(powerpc) || defined(__powerpc__) -#define TARGET_NATIVE TARGET_POWERPC -#endif -#if defined(x86_64) || defined(__x86_64__) -#define TARGET_NATIVE TARGET_X86_64 -#endif - -#ifdef ENABLE_MON -static uae_u32 mon_read_byte_jit(uintptr addr) -{ - uae_u8 *m = (uae_u8 *)addr; - return (uintptr)(*m); -} - -static void mon_write_byte_jit(uintptr addr, uae_u32 b) -{ - uae_u8 *m = (uae_u8 *)addr; - *m = b; -} -#endif - -void disasm_block(int target, uint8 * start, size_t length) -{ - if (!JITDebug) - return; - -#if defined(JIT_DEBUG) && defined(ENABLE_MON) - char disasm_str[200]; - sprintf(disasm_str, "%s $%x $%x", - target == TARGET_M68K ? "d68" : - target == TARGET_X86 ? "d86" : - target == TARGET_X86_64 ? "d8664" : - target == TARGET_POWERPC ? "d" : "x", - start, start + length - 1); - - uae_u32 (*old_mon_read_byte)(uintptr) = mon_read_byte; - void (*old_mon_write_byte)(uintptr, uae_u32) = mon_write_byte; - - mon_read_byte = mon_read_byte_jit; - mon_write_byte = mon_write_byte_jit; - - char *arg[5] = {"mon", "-m", "-r", disasm_str, NULL}; - mon(4, arg); - - mon_read_byte = old_mon_read_byte; - mon_write_byte = old_mon_write_byte; -#endif -} - -static void disasm_native_block(uint8 *start, size_t length) -{ - disasm_block(TARGET_NATIVE, start, length); -} - -static void disasm_m68k_block(uint8 *start, size_t length) -{ - disasm_block(TARGET_M68K, start, length); -} - -#ifdef HAVE_GET_WORD_UNSWAPPED -# define DO_GET_OPCODE(a) (do_get_mem_word_unswapped((uae_u16 *)(a))) -#else -# define DO_GET_OPCODE(a) (do_get_mem_word((uae_u16 *)(a))) -#endif - -#if JIT_DEBUG -static uae_u8 *last_regs_pc_p = 0; -static uae_u8 *last_compiled_block_addr = 0; - -void compiler_dumpstate(void) -{ - if (!JITDebug) - return; - - write_log("### Host addresses\n"); - write_log("MEM_BASE : %x\n", MEMBaseDiff); - write_log("PC_P : %p\n", ®s.pc_p); - write_log("SPCFLAGS : %p\n", ®s.spcflags); - write_log("D0-D7 : %p-%p\n", ®s.regs[0], ®s.regs[7]); - write_log("A0-A7 : %p-%p\n", ®s.regs[8], ®s.regs[15]); - write_log("\n"); - - write_log("### M68k processor state\n"); - m68k_dumpstate(0); - write_log("\n"); - - write_log("### Block in Mac address space\n"); - write_log("M68K block : %p\n", - (void *)(uintptr)get_virtual_address(last_regs_pc_p)); - write_log("Native block : %p (%d bytes)\n", - (void *)(uintptr)get_virtual_address(last_compiled_block_addr), - get_blockinfo_addr(last_regs_pc_p)->direct_handler_size); - write_log("\n"); -} -#endif - -static void compile_block(cpu_history* pc_hist, int blocklen) -{ - if (letit && compiled_code) { -#if PROFILE_COMPILE_TIME - compile_count++; - clock_t start_time = clock(); -#endif -#if JIT_DEBUG - bool disasm_block = false; -#endif - - /* OK, here we need to 'compile' a block */ - int i; - int r; - int was_comp=0; - uae_u8 liveflags[MAXRUN+1]; -#if USE_CHECKSUM_INFO - bool trace_in_rom = isinrom((uintptr)pc_hist[0].location); - uintptr max_pcp=(uintptr)pc_hist[blocklen - 1].location; - uintptr min_pcp=max_pcp; -#else - uintptr max_pcp=(uintptr)pc_hist[0].location; - uintptr min_pcp=max_pcp; -#endif - uae_u32 cl=cacheline(pc_hist[0].location); - void* specflags=(void*)®s.spcflags; - blockinfo* bi=NULL; - blockinfo* bi2; - int extra_len=0; - - redo_current_block=0; - if (current_compile_p>=max_compile_start) - flush_icache_hard(7); - - alloc_blockinfos(); - - bi=get_blockinfo_addr_new(pc_hist[0].location,0); - bi2=get_blockinfo(cl); - - optlev=bi->optlevel; - if (bi->status!=BI_INVALID) { - Dif (bi!=bi2) { - /* I don't think it can happen anymore. Shouldn't, in - any case. So let's make sure... */ - write_log("WOOOWOO count=%d, ol=%d %p %p\n", - bi->count,bi->optlevel,bi->handler_to_use, - cache_tags[cl].handler); - abort(); - } - - Dif (bi->count!=-1 && bi->status!=BI_NEED_RECOMP) { - write_log("bi->count=%d, bi->status=%d\n",bi->count,bi->status); - /* What the heck? We are not supposed to be here! */ - abort(); - } - } - if (bi->count==-1) { - optlev++; - while (!optcount[optlev]) - optlev++; - bi->count=optcount[optlev]-1; - } - current_block_pc_p=(uintptr)pc_hist[0].location; - - remove_deps(bi); /* We are about to create new code */ - bi->optlevel=optlev; - bi->pc_p=(uae_u8*)pc_hist[0].location; -#if USE_CHECKSUM_INFO - free_checksum_info_chain(bi->csi); - bi->csi = NULL; -#endif - - liveflags[blocklen]=0x1f; /* All flags needed afterwards */ - i=blocklen; - while (i--) { - uae_u16* currpcp=pc_hist[i].location; - uae_u32 op=DO_GET_OPCODE(currpcp); - -#if USE_CHECKSUM_INFO - trace_in_rom = trace_in_rom && isinrom((uintptr)currpcp); - if (follow_const_jumps && is_const_jump(op)) { - checksum_info *csi = alloc_checksum_info(); - csi->start_p = (uae_u8 *)min_pcp; - csi->length = max_pcp - min_pcp + LONGEST_68K_INST; - csi->next = bi->csi; - bi->csi = csi; - max_pcp = (uintptr)currpcp; - } - min_pcp = (uintptr)currpcp; -#else - if ((uintptr)currpcpmax_pcp) - max_pcp=(uintptr)currpcp; -#endif - - liveflags[i]=((liveflags[i+1]& - (~prop[op].set_flags))| - prop[op].use_flags); - if (prop[op].is_addx && (liveflags[i+1]&FLAG_Z)==0) - liveflags[i]&= ~FLAG_Z; - } - -#if USE_CHECKSUM_INFO - checksum_info *csi = alloc_checksum_info(); - csi->start_p = (uae_u8 *)min_pcp; - csi->length = max_pcp - min_pcp + LONGEST_68K_INST; - csi->next = bi->csi; - bi->csi = csi; -#endif - - bi->needed_flags=liveflags[0]; - - align_target(align_loops); - was_comp=0; - - bi->direct_handler=(cpuop_func *)get_target(); - set_dhtu(bi,bi->direct_handler); - bi->status=BI_COMPILING; - current_block_start_target=(uintptr)get_target(); - - log_startblock(); - - if (bi->count>=0) { /* Need to generate countdown code */ - raw_mov_l_mi((uintptr)®s.pc_p,(uintptr)pc_hist[0].location); - raw_sub_l_mi((uintptr)&(bi->count),1); - raw_jl((uintptr)popall_recompile_block); - } - if (optlev==0) { /* No need to actually translate */ - /* Execute normally without keeping stats */ - raw_mov_l_mi((uintptr)®s.pc_p,(uintptr)pc_hist[0].location); - raw_jmp((uintptr)popall_exec_nostats); - } - else { - reg_alloc_run=0; - next_pc_p=0; - taken_pc_p=0; - branch_cc=0; - - comp_pc_p=(uae_u8*)pc_hist[0].location; - init_comp(); - was_comp=1; - -#ifdef USE_CPU_EMUL_SERVICES - raw_sub_l_mi((uintptr)&emulated_ticks,blocklen); - raw_jcc_b_oponly(NATIVE_CC_GT); - uae_s8 *branchadd=(uae_s8*)get_target(); - emit_byte(0); - raw_call((uintptr)cpu_do_check_ticks); - *branchadd=(uintptr)get_target()-((uintptr)branchadd+1); -#endif - -#if JIT_DEBUG - if (JITDebug) { - raw_mov_l_mi((uintptr)&last_regs_pc_p,(uintptr)pc_hist[0].location); - raw_mov_l_mi((uintptr)&last_compiled_block_addr,current_block_start_target); - } -#endif - - for (i=0;i1) { - failure=0; - if (!was_comp) { - comp_pc_p=(uae_u8*)pc_hist[i].location; - init_comp(); - } - was_comp=1; - - comptbl[opcode](opcode); - freescratch(); - if (!(liveflags[i+1] & FLAG_CZNV)) { - /* We can forget about flags */ - dont_care_flags(); - } -#if INDIVIDUAL_INST - flush(1); - nop(); - flush(1); - was_comp=0; -#endif - } - - if (failure) { - if (was_comp) { - flush(1); - was_comp=0; - } - raw_mov_l_ri(REG_PAR1,(uae_u32)opcode); -#if USE_NORMAL_CALLING_CONVENTION - raw_push_l_r(REG_PAR1); -#endif - raw_mov_l_mi((uintptr)®s.pc_p, - (uintptr)pc_hist[i].location); - raw_call((uintptr)cputbl[opcode]); -#if PROFILE_UNTRANSLATED_INSNS - // raw_cputbl_count[] is indexed with plain opcode (in m68k order) - raw_add_l_mi((uintptr)&raw_cputbl_count[cft_map(opcode)],1); -#endif -#if USE_NORMAL_CALLING_CONVENTION - raw_inc_sp(4); -#endif - - if (i < blocklen - 1) { - uae_s8* branchadd; - - raw_mov_l_rm(0,(uintptr)specflags); - raw_test_l_rr(0,0); - raw_jz_b_oponly(); - branchadd=(uae_s8 *)get_target(); - emit_byte(0); - raw_jmp((uintptr)popall_do_nothing); - *branchadd=(uintptr)get_target()-(uintptr)branchadd-1; - } - } - } -#if 1 /* This isn't completely kosher yet; It really needs to be - be integrated into a general inter-block-dependency scheme */ - if (next_pc_p && taken_pc_p && - was_comp && taken_pc_p==current_block_pc_p) { - blockinfo* bi1=get_blockinfo_addr_new((void*)next_pc_p,0); - blockinfo* bi2=get_blockinfo_addr_new((void*)taken_pc_p,0); - uae_u8 x=bi1->needed_flags; - - if (x==0xff || 1) { /* To be on the safe side */ - uae_u16* next=(uae_u16*)next_pc_p; - uae_u32 op=DO_GET_OPCODE(next); - - x=0x1f; - x&=(~prop[op].set_flags); - x|=prop[op].use_flags; - } - - x|=bi2->needed_flags; - if (!(x & FLAG_CZNV)) { - /* We can forget about flags */ - dont_care_flags(); - extra_len+=2; /* The next instruction now is part of this - block */ - } - - } -#endif - log_flush(); - - if (next_pc_p) { /* A branch was registered */ - uintptr t1=next_pc_p; - uintptr t2=taken_pc_p; - int cc=branch_cc; - - uae_u32* branchadd; - uae_u32* tba; - bigstate tmp; - blockinfo* tbi; - - if (taken_pc_penv))) { - mark_callers_recompile(bi); - } - - big_to_small_state(&live,&(bi->env)); -#endif - -#if USE_CHECKSUM_INFO - remove_from_list(bi); - if (trace_in_rom) { - // No need to checksum that block trace on cache invalidation - free_checksum_info_chain(bi->csi); - bi->csi = NULL; - add_to_dormant(bi); - } - else { - calc_checksum(bi,&(bi->c1),&(bi->c2)); - add_to_active(bi); - } -#else - if (next_pc_p+extra_len>=max_pcp && - next_pc_p+extra_lenlen=max_pcp-min_pcp; - bi->min_pcp=min_pcp; - - remove_from_list(bi); - if (isinrom(min_pcp) && isinrom(max_pcp)) { - add_to_dormant(bi); /* No need to checksum it on cache flush. - Please don't start changing ROMs in - flight! */ - } - else { - calc_checksum(bi,&(bi->c1),&(bi->c2)); - add_to_active(bi); - } -#endif - - current_cache_size += get_target() - (uae_u8 *)current_compile_p; - -#if JIT_DEBUG - if (JITDebug) - bi->direct_handler_size = get_target() - (uae_u8 *)current_block_start_target; - - if (JITDebug && disasm_block) { - uaecptr block_addr = start_pc + ((char *)pc_hist[0].location - (char *)start_pc_p); - D(bug("M68K block @ 0x%08x (%d insns)\n", block_addr, blocklen)); - uae_u32 block_size = ((uae_u8 *)pc_hist[blocklen - 1].location - (uae_u8 *)pc_hist[0].location) + 1; - disasm_m68k_block((uae_u8 *)pc_hist[0].location, block_size); - D(bug("Compiled block @ 0x%08x\n", pc_hist[0].location)); - disasm_native_block((uae_u8 *)current_block_start_target, bi->direct_handler_size); - getchar(); - } -#endif - - log_dump(); - align_target(align_jumps); - - /* This is the non-direct handler */ - bi->handler= - bi->handler_to_use=(cpuop_func *)get_target(); - raw_cmp_l_mi((uintptr)®s.pc_p,(uintptr)pc_hist[0].location); - raw_jnz((uintptr)popall_cache_miss); - comp_pc_p=(uae_u8*)pc_hist[0].location; - - bi->status=BI_FINALIZING; - init_comp(); - match_states(bi); - flush(1); - - raw_jmp((uintptr)bi->direct_handler); - - current_compile_p=get_target(); - raise_in_cl_list(bi); - - /* We will flush soon, anyway, so let's do it now */ - if (current_compile_p>=max_compile_start) - flush_icache_hard(7); - - bi->status=BI_ACTIVE; - if (redo_current_block) - block_need_recompile(bi); - -#if PROFILE_COMPILE_TIME - compile_time += (clock() - start_time); -#endif - } - - /* Account for compilation time */ - cpu_do_check_ticks(); -} - -void do_nothing(void) -{ - /* What did you expect this to do? */ -} - -void exec_nostats(void) -{ - for (;;) { - uae_u32 opcode = GET_OPCODE; -#if FLIGHT_RECORDER - m68k_record_step(m68k_getpc()); -#endif - (*cpufunctbl[opcode])(opcode); - cpu_check_ticks(); - if (end_block(opcode) || SPCFLAGS_TEST(SPCFLAG_ALL)) { - return; /* We will deal with the spcflags in the caller */ - } - } -} - -void execute_normal(void) -{ - if (!check_for_cache_miss()) { - cpu_history pc_hist[MAXRUN]; - int blocklen = 0; -#if REAL_ADDRESSING || DIRECT_ADDRESSING - start_pc_p = regs.pc_p; - start_pc = get_virtual_address(regs.pc_p); -#else - start_pc_p = regs.pc_oldp; - start_pc = regs.pc; -#endif - for (;;) { /* Take note: This is the do-it-normal loop */ - pc_hist[blocklen++].location = (uae_u16 *)regs.pc_p; - uae_u32 opcode = GET_OPCODE; -#if FLIGHT_RECORDER - m68k_record_step(m68k_getpc()); -#endif - (*cpufunctbl[opcode])(opcode); - cpu_check_ticks(); - if (end_block(opcode) || SPCFLAGS_TEST(SPCFLAG_ALL) || blocklen>=MAXRUN) { - compile_block(pc_hist, blocklen); - return; /* We will deal with the spcflags in the caller */ - } - /* No need to check regs.spcflags, because if they were set, - we'd have ended up inside that "if" */ - } - } -} - -typedef void (*compiled_handler)(void); - -static void m68k_do_compile_execute(void) -{ - for (;;) { - ((compiled_handler)(pushall_call_handler))(); - /* Whenever we return from that, we should check spcflags */ - if (SPCFLAGS_TEST(SPCFLAG_ALL)) { - if (m68k_do_specialties ()) - return; - } - } -} - -void m68k_compile_execute (void) -{ - for (;;) { - if (quit_program) - break; - m68k_do_compile_execute(); - } -} diff --git a/BasiliskII/src/uae_cpu/compiler/flags_x86.h b/BasiliskII/src/uae_cpu/compiler/flags_x86.h deleted file mode 100644 index 4247f10a..00000000 --- a/BasiliskII/src/uae_cpu/compiler/flags_x86.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * compiler/flags_x86.h - Native flags definitions for IA-32 - * - * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer - * - * Adaptation for Basilisk II and improvements, copyright 2000-2005 - * Gwenole Beauchesne - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef NATIVE_FLAGS_X86_H -#define NATIVE_FLAGS_X86_H - -/* Native integer code conditions */ -enum { - NATIVE_CC_HI = 7, - NATIVE_CC_LS = 6, - NATIVE_CC_CC = 3, - NATIVE_CC_CS = 2, - NATIVE_CC_NE = 5, - NATIVE_CC_EQ = 4, - NATIVE_CC_VC = 11, - NATIVE_CC_VS = 10, - NATIVE_CC_PL = 9, - NATIVE_CC_MI = 8, - NATIVE_CC_GE = 13, - NATIVE_CC_LT = 12, - NATIVE_CC_GT = 15, - NATIVE_CC_LE = 14 -}; - -#endif /* NATIVE_FLAGS_X86_H */ diff --git a/BasiliskII/src/uae_cpu/compiler/gencomp.c b/BasiliskII/src/uae_cpu/compiler/gencomp.c deleted file mode 100644 index 2e16972d..00000000 --- a/BasiliskII/src/uae_cpu/compiler/gencomp.c +++ /dev/null @@ -1,3072 +0,0 @@ -/* - * compiler/gencomp.c - MC680x0 compilation generator - * - * Based on work Copyright 1995, 1996 Bernd Schmidt - * Changes for UAE-JIT Copyright 2000 Bernd Meyer - * - * Adaptation for Basilisk II and improvements, copyright 2000-2005 - * Gwenole Beauchesne - * - * Basilisk II (C) 1997-2005 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include "sysdeps.h" -#include "../readcpu.h" - -#define BOOL_TYPE "int" -#define failure global_failure=1 -#define FAILURE global_failure=1 -#define isjump global_isjump=1 -#define is_const_jump global_iscjump=1; -#define isaddx global_isaddx=1 -#define uses_cmov global_cmov=1 -#define mayfail global_mayfail=1 -#define uses_fpu global_fpu=1 - -int hack_opcode; - -static int global_failure; -static int global_isjump; -static int global_iscjump; -static int global_isaddx; -static int global_cmov; -static int long_opcode; -static int global_mayfail; -static int global_fpu; - -static char endstr[1000]; -static char lines[100000]; -static int comp_index=0; - -static int cond_codes_x86[]={-1,-1,7,6,3,2,5,4,-1,-1,9,8,13,12,15,14}; - -static void comprintf(const char* format, ...) -{ - va_list args; - - va_start(args,format); - comp_index+=vsprintf(lines+comp_index,format,args); -} - -static void com_discard(void) -{ - comp_index=0; -} - -static void com_flush(void) -{ - int i; - for (i=0;i 0); - n_braces--; - comprintf ("}"); -} - -static void -finish_braces (void) -{ - while (n_braces > 0) - close_brace (); -} - -static void -pop_braces (int to) -{ - while (n_braces > to) - close_brace (); -} - -static int -bit_size (int size) -{ - switch (size) - { - case sz_byte: - return 8; - case sz_word: - return 16; - case sz_long: - return 32; - default: - abort (); - } - return 0; -} - -static const char * -bit_mask (int size) -{ - switch (size) - { - case sz_byte: - return "0xff"; - case sz_word: - return "0xffff"; - case sz_long: - return "0xffffffff"; - default: - abort (); - } - return 0; -} - -static __inline__ void gen_update_next_handler(void) -{ - return; /* Can anything clever be done here? */ -} - -static void gen_writebyte(char* address, char* source) -{ - comprintf("\twritebyte(%s,%s,scratchie);\n",address,source); -} - -static void gen_writeword(char* address, char* source) -{ - comprintf("\twriteword(%s,%s,scratchie);\n",address,source); -} - -static void gen_writelong(char* address, char* source) -{ - comprintf("\twritelong(%s,%s,scratchie);\n",address,source); -} - -static void gen_readbyte(char* address, char* dest) -{ - comprintf("\treadbyte(%s,%s,scratchie);\n",address,dest); -} - -static void gen_readword(char* address, char* dest) -{ - comprintf("\treadword(%s,%s,scratchie);\n",address,dest); -} - -static void gen_readlong(char* address, char* dest) -{ - comprintf("\treadlong(%s,%s,scratchie);\n",address,dest); -} - - - -static const char * -gen_nextilong (void) -{ - static char buffer[80]; - - sprintf (buffer, "comp_get_ilong((m68k_pc_offset+=4)-4)"); - insn_n_cycles += 4; - - long_opcode=1; - return buffer; -} - -static const char * -gen_nextiword (void) -{ - static char buffer[80]; - - sprintf (buffer, "comp_get_iword((m68k_pc_offset+=2)-2)"); - insn_n_cycles+=2; - - long_opcode=1; - return buffer; -} - -static const char * -gen_nextibyte (void) -{ - static char buffer[80]; - - sprintf (buffer, "comp_get_ibyte((m68k_pc_offset+=2)-2)"); - insn_n_cycles += 2; - - long_opcode=1; - return buffer; -} - -static void -swap_opcode (void) -{ - comprintf("#ifdef HAVE_GET_WORD_UNSWAPPED\n"); - comprintf("\topcode = do_byteswap_16(opcode);\n"); - comprintf("#endif\n"); -} - -static void -sync_m68k_pc (void) -{ - comprintf("\t if (m68k_pc_offset>100) sync_m68k_pc();\n"); -} - - -/* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, - * the calling routine handles Apdi and Aipi modes. - * gb-- movem == 2 means the same thing but for a MOVE16 instruction */ -static void -genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem) -{ - start_brace (); - switch (mode) - { - case Dreg: /* Do we need to check dodgy here? */ - if (movem) - abort (); - if (getv == 1 || getv==2) { - /* We generate the variable even for getv==2, so we can use - it as a destination for MOVE */ - comprintf ("\tint %s=%s;\n",name,reg); - } - return; - - case Areg: - if (movem) - abort (); - if (getv == 1 || getv==2) { - /* see above */ - comprintf ("\tint %s=dodgy?scratchie++:%s+8;\n",name,reg); - if (getv==1) { - comprintf ("\tif (dodgy) \n"); - comprintf ("\t\tmov_l_rr(%s,%s+8);\n",name, reg); - } - } - return; - - case Aind: - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf ("\tif (dodgy) \n"); - comprintf ("\t\tmov_l_rr(%sa,%s+8);\n",name, reg); - break; - case Aipi: - comprintf ("\tint %sa=scratchie++;\n",name,reg); - comprintf ("\tmov_l_rr(%sa,%s+8);\n",name, reg); - break; - case Apdi: - switch (size) - { - case sz_byte: - if (movem) { - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - else { - start_brace(); - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf("\tlea_l_brr(%s+8,%s+8,(uae_s32)-areg_byteinc[%s]);\n",reg,reg,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - break; - case sz_word: - if (movem) { - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - else { - start_brace(); - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf("\tlea_l_brr(%s+8,%s+8,-2);\n",reg,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - break; - case sz_long: - if (movem) { - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - else { - start_brace(); - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf("\tlea_l_brr(%s+8,%s+8,-4);\n",reg,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - break; - default: - abort (); - } - break; - case Ad16: - comprintf("\tint %sa=scratchie++;\n",name); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - comprintf("\tlea_l_brr(%sa,%sa,(uae_s32)(uae_s16)%s);\n",name,name,gen_nextiword()); - break; - case Ad8r: - comprintf("\tint %sa=scratchie++;\n",name); - comprintf("\tcalc_disp_ea_020(%s+8,%s,%sa,scratchie);\n", - reg,gen_nextiword(),name); - break; - - case PC16: - comprintf("\tint %sa=scratchie++;\n",name); - comprintf("\tuae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); - comprintf ("\tuae_s32 PC16off = (uae_s32)(uae_s16)%s;\n", gen_nextiword ()); - comprintf("\tmov_l_ri(%sa,address+PC16off);\n",name); - break; - - case PC8r: - comprintf("\tint pctmp=scratchie++;\n"); - comprintf("\tint %sa=scratchie++;\n",name); - comprintf("\tuae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); - start_brace(); - comprintf("\tmov_l_ri(pctmp,address);\n"); - - comprintf("\tcalc_disp_ea_020(pctmp,%s,%sa,scratchie);\n", - gen_nextiword(),name); - break; - case absw: - comprintf ("\tint %sa = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%sa,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ()); - break; - case absl: - comprintf ("\tint %sa = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%sa,%s); /* absl */\n", name, gen_nextilong ()); - break; - case imm: - if (getv != 1) - abort (); - switch (size) - { - case sz_byte: - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s8)%s);\n", name, gen_nextibyte ()); - break; - case sz_word: - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ()); - break; - case sz_long: - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,%s);\n", name, gen_nextilong ()); - break; - default: - abort (); - } - return; - case imm0: - if (getv != 1) - abort (); - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s8)%s);\n", name, gen_nextibyte ()); - return; - case imm1: - if (getv != 1) - abort (); - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ()); - return; - case imm2: - if (getv != 1) - abort (); - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,%s);\n", name, gen_nextilong ()); - return; - case immi: - if (getv != 1) - abort (); - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,%s);\n", name, reg); - return; - default: - abort (); - } - - /* We get here for all non-reg non-immediate addressing modes to - * actually fetch the value. */ - if (getv == 1) - { - char astring[80]; - sprintf(astring,"%sa",name); - switch (size) - { - case sz_byte: - insn_n_cycles += 2; - break; - case sz_word: - insn_n_cycles += 2; - break; - case sz_long: - insn_n_cycles += 4; - break; - default: - abort (); - } - start_brace (); - comprintf("\tint %s=scratchie++;\n",name); - switch (size) - { - case sz_byte: - gen_readbyte(astring,name); - break; - case sz_word: - gen_readword(astring,name); - break; - case sz_long: - gen_readlong(astring,name); - break; - default: - abort (); - } - } - - /* We now might have to fix up the register for pre-dec or post-inc - * addressing modes. */ - if (!movem) { - switch (mode) - { - case Aipi: - switch (size) - { - case sz_byte: - comprintf("\tlea_l_brr(%s+8,%s+8,areg_byteinc[%s]);\n",reg,reg,reg); - break; - case sz_word: - comprintf("\tlea_l_brr(%s+8,%s+8,2);\n",reg,reg,reg); - break; - case sz_long: - comprintf("\tlea_l_brr(%s+8,%s+8,4);\n",reg,reg); - break; - default: - abort (); - } - break; - case Apdi: - break; - default: - break; - } - } -} - -static void -genastore (char *from, amodes mode, char *reg, wordsizes size, char *to) -{ - switch (mode) - { - case Dreg: - switch (size) - { - case sz_byte: - comprintf("\tif(%s!=%s)\n",reg,from); - comprintf ("\t\tmov_b_rr(%s,%s);\n", reg, from); - break; - case sz_word: - comprintf("\tif(%s!=%s)\n",reg,from); - comprintf ("\t\tmov_w_rr(%s,%s);\n", reg, from); - break; - case sz_long: - comprintf("\tif(%s!=%s)\n",reg,from); - comprintf ("\t\tmov_l_rr(%s,%s);\n", reg, from); - break; - default: - abort (); - } - break; - case Areg: - switch (size) - { - case sz_word: - comprintf("\tif(%s+8!=%s)\n",reg,from); - comprintf ("\t\tmov_w_rr(%s+8,%s);\n", reg, from); - break; - case sz_long: - comprintf("\tif(%s+8!=%s)\n",reg,from); - comprintf ("\t\tmov_l_rr(%s+8,%s);\n", reg, from); - break; - default: - abort (); - } - break; - - case Apdi: - case absw: - case PC16: - case PC8r: - case Ad16: - case Ad8r: - case Aipi: - case Aind: - case absl: - { - char astring[80]; - sprintf(astring,"%sa",to); - - switch (size) - { - case sz_byte: - insn_n_cycles += 2; - gen_writebyte(astring,from); - break; - case sz_word: - insn_n_cycles += 2; - gen_writeword(astring,from); - break; - case sz_long: - insn_n_cycles += 4; - gen_writelong(astring,from); - break; - default: - abort (); - } - } - break; - case imm: - case imm0: - case imm1: - case imm2: - case immi: - abort (); - break; - default: - abort (); - } -} - -static void genmov16(uae_u32 opcode, struct instr *curi) -{ - comprintf("\tint src=scratchie++;\n"); - comprintf("\tint dst=scratchie++;\n"); - - if ((opcode & 0xfff8) == 0xf620) { - /* MOVE16 (Ax)+,(Ay)+ */ - comprintf("\tuae_u16 dstreg=((%s)>>12)&0x07;\n", gen_nextiword()); - comprintf("\tmov_l_rr(src,8+srcreg);\n"); - comprintf("\tmov_l_rr(dst,8+dstreg);\n"); - } - else { - /* Other variants */ - genamode (curi->smode, "srcreg", curi->size, "src", 0, 2); - genamode (curi->dmode, "dstreg", curi->size, "dst", 0, 2); - comprintf("\tmov_l_rr(src,srca);\n"); - comprintf("\tmov_l_rr(dst,dsta);\n"); - } - - /* Align on 16-byte boundaries */ - comprintf("\tand_l_ri(src,~15);\n"); - comprintf("\tand_l_ri(dst,~15);\n"); - - if ((opcode & 0xfff8) == 0xf620) { - comprintf("\tif (srcreg != dstreg)\n"); - comprintf("\tadd_l_ri(srcreg+8,16);\n"); - comprintf("\tadd_l_ri(dstreg+8,16);\n"); - } - else if ((opcode & 0xfff8) == 0xf600) - comprintf("\tadd_l_ri(srcreg+8,16);\n"); - else if ((opcode & 0xfff8) == 0xf608) - comprintf("\tadd_l_ri(dstreg+8,16);\n"); - - comprintf("\tint tmp=scratchie;\n"); - comprintf("\tscratchie+=4;\n"); - - comprintf("\tget_n_addr(src,src,scratchie);\n" - "\tget_n_addr(dst,dst,scratchie);\n" - "\tmov_l_rR(tmp+0,src,0);\n" - "\tmov_l_rR(tmp+1,src,4);\n" - "\tmov_l_rR(tmp+2,src,8);\n" - "\tmov_l_rR(tmp+3,src,12);\n" - "\tmov_l_Rr(dst,tmp+0,0);\n" - "\tforget_about(tmp+0);\n" - "\tmov_l_Rr(dst,tmp+1,4);\n" - "\tforget_about(tmp+1);\n" - "\tmov_l_Rr(dst,tmp+2,8);\n" - "\tforget_about(tmp+2);\n" - "\tmov_l_Rr(dst,tmp+3,12);\n"); -} - -static void -genmovemel (uae_u16 opcode) -{ - comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); - comprintf ("\tint native=scratchie++;\n"); - comprintf ("\tint i;\n"); - comprintf ("\tsigned char offset=0;\n"); - genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); - comprintf("\tget_n_addr(srca,native,scratchie);\n"); - - comprintf("\tfor (i=0;i<16;i++) {\n" - "\t\tif ((mask>>i)&1) {\n"); - switch(table68k[opcode].size) { - case sz_long: - comprintf("\t\t\tmov_l_rR(i,native,offset);\n" - "\t\t\tbswap_32(i);\n" - "\t\t\toffset+=4;\n"); - break; - case sz_word: - comprintf("\t\t\tmov_w_rR(i,native,offset);\n" - "\t\t\tbswap_16(i);\n" - "\t\t\tsign_extend_16_rr(i,i);\n" - "\t\t\toffset+=2;\n"); - break; - default: abort(); - } - comprintf("\t\t}\n" - "\t}"); - if (table68k[opcode].dmode == Aipi) { - comprintf("\t\t\tlea_l_brr(8+dstreg,srca,offset);\n"); - } -} - - -static void -genmovemle (uae_u16 opcode) -{ - comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); - comprintf ("\tint native=scratchie++;\n"); - comprintf ("\tint i;\n"); - comprintf ("\tint tmp=scratchie++;\n"); - comprintf ("\tsigned char offset=0;\n"); - genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); - - comprintf("\tget_n_addr(srca,native,scratchie);\n"); - - if (table68k[opcode].dmode!=Apdi) { - comprintf("\tfor (i=0;i<16;i++) {\n" - "\t\tif ((mask>>i)&1) {\n"); - switch(table68k[opcode].size) { - case sz_long: - comprintf("\t\t\tmov_l_rr(tmp,i);\n" - "\t\t\tbswap_32(tmp);\n" - "\t\t\tmov_l_Rr(native,tmp,offset);\n" - "\t\t\toffset+=4;\n"); - break; - case sz_word: - comprintf("\t\t\tmov_l_rr(tmp,i);\n" - "\t\t\tbswap_16(tmp);\n" - "\t\t\tmov_w_Rr(native,tmp,offset);\n" - "\t\t\toffset+=2;\n"); - break; - default: abort(); - } - } - else { /* Pre-decrement */ - comprintf("\tfor (i=0;i<16;i++) {\n" - "\t\tif ((mask>>i)&1) {\n"); - switch(table68k[opcode].size) { - case sz_long: - comprintf("\t\t\toffset-=4;\n" - "\t\t\tmov_l_rr(tmp,15-i);\n" - "\t\t\tbswap_32(tmp);\n" - "\t\t\tmov_l_Rr(native,tmp,offset);\n" - ); - break; - case sz_word: - comprintf("\t\t\toffset-=2;\n" - "\t\t\tmov_l_rr(tmp,15-i);\n" - "\t\t\tbswap_16(tmp);\n" - "\t\t\tmov_w_Rr(native,tmp,offset);\n" - ); - break; - default: abort(); - } - } - - - comprintf("\t\t}\n" - "\t}"); - if (table68k[opcode].dmode == Apdi) { - comprintf("\t\t\tlea_l_brr(8+dstreg,srca,(uae_s32)offset);\n"); - } -} - - -static void -duplicate_carry (void) -{ - comprintf ("\tif (needed_flags&FLAG_X) duplicate_carry();\n"); -} - -typedef enum -{ - flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, - flag_addx, flag_subx, flag_zn, flag_av, flag_sv, flag_and, flag_or, - flag_eor, flag_mov -} -flagtypes; - - -static void -genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst) -{ - if (noflags) { - switch(type) { - case flag_cmp: - comprintf("\tdont_care_flags();\n"); - comprintf("/* Weird --- CMP with noflags ;-) */\n"); - return; - case flag_add: - case flag_sub: - comprintf("\tdont_care_flags();\n"); - { - char* op; - switch(type) { - case flag_add: op="add"; break; - case flag_sub: op="sub"; break; - default: abort(); - } - switch (size) - { - case sz_byte: - comprintf("\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\t%s_l(%s,%s);\n",op,dst,src); - break; - } - return; - } - break; - - case flag_and: - comprintf("\tdont_care_flags();\n"); - switch (size) - { - case sz_byte: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); - comprintf("\tor_l_ri(scratchie,0xffffff00);\n"); - comprintf("\tand_l(%s,scratchie);\n",dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\tand_b(%s,%s);\n",dst,src); - break; - case sz_word: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); - comprintf("\tor_l_ri(scratchie,0xffff0000);\n"); - comprintf("\tand_l(%s,scratchie);\n",dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\tand_w(%s,%s);\n",dst,src); - break; - case sz_long: - comprintf("\tand_l(%s,%s);\n",dst,src); - break; - } - return; - - case flag_mov: - comprintf("\tdont_care_flags();\n"); - switch (size) - { - case sz_byte: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); - comprintf("\tand_l_ri(%s,0xffffff00);\n",dst); - comprintf("\tor_l(%s,scratchie);\n",dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\tmov_b_rr(%s,%s);\n",dst,src); - break; - case sz_word: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); - comprintf("\tand_l_ri(%s,0xffff0000);\n",dst); - comprintf("\tor_l(%s,scratchie);\n",dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\tmov_w_rr(%s,%s);\n",dst,src); - break; - case sz_long: - comprintf("\tmov_l_rr(%s,%s);\n",dst,src); - break; - } - return; - - case flag_or: - case flag_eor: - comprintf("\tdont_care_flags();\n"); - start_brace(); - { - char* op; - switch(type) { - case flag_or: op="or"; break; - case flag_eor: op="xor"; break; - default: abort(); - } - switch (size) - { - case sz_byte: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); - comprintf("\t%s_l(%s,scratchie);\n",op,dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); - comprintf("\t%s_l(%s,scratchie);\n",op,dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\t%s_l(%s,%s);\n",op,dst,src); - break; - } - close_brace(); - return; - } - - - case flag_addx: - case flag_subx: - comprintf("\tdont_care_flags();\n"); - { - char* op; - switch(type) { - case flag_addx: op="adc"; break; - case flag_subx: op="sbb"; break; - default: abort(); - } - comprintf("\trestore_carry();\n"); /* Reload the X flag into C */ - switch (size) - { - case sz_byte: - comprintf("\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\t%s_l(%s,%s);\n",op,dst,src); - break; - } - return; - } - break; - default: return; - } - } - - /* Need the flags, but possibly not all of them */ - switch (type) - { - case flag_logical_noclobber: - failure; - - case flag_and: - case flag_or: - case flag_eor: - comprintf("\tdont_care_flags();\n"); - start_brace(); - { - char* op; - switch(type) { - case flag_and: op="and"; break; - case flag_or: op="or"; break; - case flag_eor: op="xor"; break; - default: abort(); - } - switch (size) - { - case sz_byte: - comprintf("\tstart_needflags();\n" - "\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("\tstart_needflags();\n" - "\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\tstart_needflags();\n" - "\t%s_l(%s,%s);\n",op,dst,src); - break; - } - comprintf("\tlive_flags();\n"); - comprintf("\tend_needflags();\n"); - close_brace(); - return; - } - - case flag_mov: - comprintf("\tdont_care_flags();\n"); - start_brace(); - { - switch (size) - { - case sz_byte: - comprintf("\tif (%s!=%s) {\n",src,dst); - comprintf("\tmov_b_ri(%s,0);\n" - "\tstart_needflags();\n",dst); - comprintf("\tor_b(%s,%s);\n",dst,src); - comprintf("\t} else {\n"); - comprintf("\tmov_b_rr(%s,%s);\n",dst,src); - comprintf("\ttest_b_rr(%s,%s);\n",dst,dst); - comprintf("\t}\n"); - break; - case sz_word: - comprintf("\tif (%s!=%s) {\n",src,dst); - comprintf("\tmov_w_ri(%s,0);\n" - "\tstart_needflags();\n",dst); - comprintf("\tor_w(%s,%s);\n",dst,src); - comprintf("\t} else {\n"); - comprintf("\tmov_w_rr(%s,%s);\n",dst,src); - comprintf("\ttest_w_rr(%s,%s);\n",dst,dst); - comprintf("\t}\n"); - break; - case sz_long: - comprintf("\tif (%s!=%s) {\n",src,dst); - comprintf("\tmov_l_ri(%s,0);\n" - "\tstart_needflags();\n",dst); - comprintf("\tor_l(%s,%s);\n",dst,src); - comprintf("\t} else {\n"); - comprintf("\tmov_l_rr(%s,%s);\n",dst,src); - comprintf("\ttest_l_rr(%s,%s);\n",dst,dst); - comprintf("\t}\n"); - break; - } - comprintf("\tlive_flags();\n"); - comprintf("\tend_needflags();\n"); - close_brace(); - return; - } - - case flag_logical: - comprintf("\tdont_care_flags();\n"); - start_brace(); - switch (size) - { - case sz_byte: - comprintf("\tstart_needflags();\n" - "\ttest_b_rr(%s,%s);\n",value,value); - break; - case sz_word: - comprintf("\tstart_needflags();\n" - "\ttest_w_rr(%s,%s);\n",value,value); - break; - case sz_long: - comprintf("\tstart_needflags();\n" - "\ttest_l_rr(%s,%s);\n",value,value); - break; - } - comprintf("\tlive_flags();\n"); - comprintf("\tend_needflags();\n"); - close_brace(); - return; - - - case flag_add: - case flag_sub: - case flag_cmp: - comprintf("\tdont_care_flags();\n"); - { - char* op; - switch(type) { - case flag_add: op="add"; break; - case flag_sub: op="sub"; break; - case flag_cmp: op="cmp"; break; - default: abort(); - } - switch (size) - { - case sz_byte: - comprintf("\tstart_needflags();\n" - "\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("\tstart_needflags();\n" - "\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\tstart_needflags();\n" - "\t%s_l(%s,%s);\n",op,dst,src); - break; - } - comprintf("\tlive_flags();\n"); - comprintf("\tend_needflags();\n"); - if (type!=flag_cmp) { - duplicate_carry(); - } - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - - return; - } - - case flag_addx: - case flag_subx: - uses_cmov; - comprintf("\tdont_care_flags();\n"); - { - char* op; - switch(type) { - case flag_addx: op="adc"; break; - case flag_subx: op="sbb"; break; - default: abort(); - } - start_brace(); - comprintf("\tint zero=scratchie++;\n" - "\tint one=scratchie++;\n" - "\tif (needed_flags&FLAG_Z) {\n" - "\tmov_l_ri(zero,0);\n" - "\tmov_l_ri(one,-1);\n" - "\tmake_flags_live();\n" - "\tcmov_l_rr(zero,one,5);\n" - "\t}\n"); - comprintf("\trestore_carry();\n"); /* Reload the X flag into C */ - switch (size) - { - case sz_byte: - comprintf("\tstart_needflags();\n" - "\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("\tstart_needflags();\n" - "\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\tstart_needflags();\n" - "\t%s_l(%s,%s);\n",op,dst,src); - break; - } - comprintf("\tlive_flags();\n"); - comprintf("\tif (needed_flags&FLAG_Z) {\n" - "\tcmov_l_rr(zero,one,5);\n" - "\tset_zero(zero, one);\n" /* No longer need one */ - "\tlive_flags();\n" - "\t}\n"); - comprintf("\tend_needflags();\n"); - duplicate_carry(); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - return; - } - default: - failure; - break; - } -} - -static void -force_range_for_rox (const char *var, wordsizes size) -{ - /* Could do a modulo operation here... which one is faster? */ - switch (size) - { - case sz_long: - comprintf ("\tif (%s >= 33) %s -= 33;\n", var, var); - break; - case sz_word: - comprintf ("\tif (%s >= 34) %s -= 34;\n", var, var); - comprintf ("\tif (%s >= 17) %s -= 17;\n", var, var); - break; - case sz_byte: - comprintf ("\tif (%s >= 36) %s -= 36;\n", var, var); - comprintf ("\tif (%s >= 18) %s -= 18;\n", var, var); - comprintf ("\tif (%s >= 9) %s -= 9;\n", var, var); - break; - } -} - -static const char * -cmask (wordsizes size) -{ - switch (size) - { - case sz_byte: - return "0x80"; - case sz_word: - return "0x8000"; - case sz_long: - return "0x80000000"; - default: - abort (); - } -} - -static int -source_is_imm1_8 (struct instr *i) -{ - return i->stype == 3; -} - -static int /* returns zero for success, non-zero for failure */ -gen_opcode (unsigned long int opcode) -{ - struct instr *curi = table68k + opcode; - char* ssize=NULL; - - insn_n_cycles = 2; - global_failure=0; - long_opcode=0; - global_isjump=0; - global_iscjump=0; - global_isaddx=0; - global_cmov=0; - global_fpu=0; - global_mayfail=0; - hack_opcode=opcode; - endstr[0]=0; - - start_brace (); - comprintf("\tuae_u8 scratchie=S1;\n"); - switch (curi->plev) - { - case 0: /* not privileged */ - break; - case 1: /* unprivileged only on 68000 */ - if (cpu_level == 0) - break; - if (next_cpu_level < 0) - next_cpu_level = 0; - - /* fall through */ - case 2: /* priviledged */ - failure; /* Easy ones first */ - break; - case 3: /* privileged if size == word */ - if (curi->size == sz_byte) - break; - failure; - break; - } - switch (curi->size) { - case sz_byte: ssize="b"; break; - case sz_word: ssize="w"; break; - case sz_long: ssize="l"; break; - default: abort(); - } - - switch (curi->mnemo) - { - case i_OR: - case i_AND: - case i_EOR: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - switch(curi->mnemo) { - case i_OR: genflags (flag_or, curi->size, "", "src", "dst"); break; - case i_AND: genflags (flag_and, curi->size, "", "src", "dst"); break; - case i_EOR: genflags (flag_eor, curi->size, "", "src", "dst"); break; - } - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; - - case i_ORSR: - case i_EORSR: - failure; - isjump; - break; - case i_ANDSR: - failure; - isjump; - break; - case i_SUB: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - genflags (flag_sub, curi->size, "", "src", "dst"); - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; - case i_SUBA: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); - start_brace(); - comprintf("\tint tmp=scratchie++;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break; - case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break; - case sz_long: comprintf("\ttmp=src;\n"); break; - default: abort(); - } - comprintf("\tsub_l(dst,tmp);\n"); - genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); - break; - case i_SUBX: - isaddx; - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - genflags (flag_subx, curi->size, "", "src", "dst"); - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; - case i_SBCD: - failure; - /* I don't think so! */ - break; - case i_ADD: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - genflags (flag_add, curi->size, "", "src", "dst"); - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; - case i_ADDA: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); - start_brace(); - comprintf("\tint tmp=scratchie++;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break; - case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break; - case sz_long: comprintf("\ttmp=src;\n"); break; - default: abort(); - } - comprintf("\tadd_l(dst,tmp);\n"); - genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); - break; - case i_ADDX: - isaddx; - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - start_brace(); - genflags (flag_addx, curi->size, "", "src", "dst"); - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; - case i_ABCD: - failure; - /* No BCD maths for me.... */ - break; - case i_NEG: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - start_brace (); - comprintf("\tint dst=scratchie++;\n"); - comprintf("\tmov_l_ri(dst,0);\n"); - genflags (flag_sub, curi->size, "", "src", "dst"); - genastore ("dst", curi->smode, "srcreg", curi->size, "src"); - break; - case i_NEGX: - isaddx; - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - start_brace (); - comprintf("\tint dst=scratchie++;\n"); - comprintf("\tmov_l_ri(dst,0);\n"); - genflags (flag_subx, curi->size, "", "src", "dst"); - genastore ("dst", curi->smode, "srcreg", curi->size, "src"); - break; - - case i_NBCD: - failure; - /* Nope! */ - break; - case i_CLR: - genamode (curi->smode, "srcreg", curi->size, "src", 2, 0); - start_brace(); - comprintf("\tint dst=scratchie++;\n"); - comprintf("\tmov_l_ri(dst,0);\n"); - genflags (flag_logical, curi->size, "dst", "", ""); - genastore ("dst", curi->smode, "srcreg", curi->size, "src"); - break; - case i_NOT: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - start_brace (); - comprintf("\tint dst=scratchie++;\n"); - comprintf("\tmov_l_ri(dst,0xffffffff);\n"); - genflags (flag_eor, curi->size, "", "src", "dst"); - genastore ("dst", curi->smode, "srcreg", curi->size, "src"); - break; - case i_TST: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genflags (flag_logical, curi->size, "src", "", ""); - break; - case i_BCHG: - case i_BCLR: - case i_BSET: - case i_BTST: -/* failure; /* NEW: from "Ipswitch Town" release */ - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - start_brace(); - comprintf("\tint s=scratchie++;\n" - "\tint tmp=scratchie++;\n" - "\tmov_l_rr(s,src);\n"); - if (curi->size == sz_byte) - comprintf("\tand_l_ri(s,7);\n"); - else - comprintf("\tand_l_ri(s,31);\n"); - - { - char* op; - int need_write=1; - - switch(curi->mnemo) { - case i_BCHG: op="btc"; break; - case i_BCLR: op="btr"; break; - case i_BSET: op="bts"; break; - case i_BTST: op="bt"; need_write=0; break; - default: abort(); - } - comprintf("\t%s_l_rr(dst,s);\n" /* Answer now in C */ - "\tsbb_l(s,s);\n" /* s is 0 if bit was 0, -1 otherwise */ - "\tmake_flags_live();\n" /* Get the flags back */ - "\tdont_care_flags();\n",op); - if (!noflags) { - comprintf("\tstart_needflags();\n" - "\tset_zero(s,tmp);\n" - "\tlive_flags();\n" - "\tend_needflags();\n"); - } - if (need_write) - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - } - break; - - case i_CMPM: - case i_CMP: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - start_brace (); - genflags (flag_cmp, curi->size, "", "src", "dst"); - break; - case i_CMPA: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); - start_brace(); - comprintf("\tint tmps=scratchie++;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tsign_extend_8_rr(tmps,src);\n"); break; - case sz_word: comprintf("\tsign_extend_16_rr(tmps,src);\n"); break; - case sz_long: comprintf("tmps=src;\n"); break; - default: abort(); - } - genflags (flag_cmp, sz_long, "", "tmps", "dst"); - break; - /* The next two are coded a little unconventional, but they are doing - * weird things... */ - case i_MVPRM: - isjump; - failure; - break; - case i_MVPMR: - isjump; - failure; - break; - case i_MOVE: - switch(curi->dmode) { - case Dreg: - case Areg: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); - genflags (flag_mov, curi->size, "", "src", "dst"); - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; - default: /* It goes to memory, not a register */ - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); - genflags (flag_logical, curi->size, "src", "", ""); - genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); - break; - } - break; - case i_MOVEA: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); - - start_brace(); - comprintf("\tint tmps=scratchie++;\n"); - switch(curi->size) { - case sz_word: comprintf("\tsign_extend_16_rr(dst,src);\n"); break; - case sz_long: comprintf("\tmov_l_rr(dst,src);\n"); break; - default: abort(); - } - genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); - break; - - case i_MVSR2: - isjump; - failure; - break; - case i_MV2SR: - isjump; - failure; - break; - case i_SWAP: - genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); - comprintf("\tdont_care_flags();\n"); - comprintf("\trol_l_ri(src,16);\n"); - genflags (flag_logical, sz_long, "src", "", ""); - genastore ("src", curi->smode, "srcreg", sz_long, "src"); - break; - case i_EXG: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - start_brace(); - comprintf("\tint tmp=scratchie++;\n" - "\tmov_l_rr(tmp,src);\n"); - genastore ("dst", curi->smode, "srcreg", curi->size, "src"); - genastore ("tmp", curi->dmode, "dstreg", curi->size, "dst"); - break; - case i_EXT: - genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); - comprintf("\tdont_care_flags();\n"); - start_brace (); - switch (curi->size) - { - case sz_byte: - comprintf ("\tint dst = src;\n" - "\tsign_extend_8_rr(src,src);\n"); - break; - case sz_word: - comprintf ("\tint dst = scratchie++;\n" - "\tsign_extend_8_rr(dst,src);\n"); - break; - case sz_long: - comprintf ("\tint dst = src;\n" - "\tsign_extend_16_rr(src,src);\n"); - break; - default: - abort (); - } - genflags (flag_logical, - curi->size == sz_word ? sz_word : sz_long, "dst", "", ""); - genastore ("dst", curi->smode, "srcreg", - curi->size == sz_word ? sz_word : sz_long, "src"); - break; - case i_MVMEL: - genmovemel ((uae_u16)opcode); - break; - case i_MVMLE: - genmovemle ((uae_u16)opcode); - break; - case i_TRAP: - isjump; - failure; - break; - case i_MVR2USP: - isjump; - failure; - break; - case i_MVUSP2R: - isjump; - failure; - break; - case i_RESET: - isjump; - failure; - break; - case i_NOP: - break; - case i_STOP: - isjump; - failure; - break; - case i_RTE: - isjump; - failure; - break; - case i_RTD: -/* failure; /* NEW: from "Ipswitch Town" release */ - genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0); - /* offs is constant */ - comprintf("\tadd_l_ri(offs,4);\n"); - start_brace(); - comprintf("\tint newad=scratchie++;\n" - "\treadlong(15,newad,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc,newad);\n" - "\tget_n_addr_jmp(newad,PC_P,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" - "\tm68k_pc_offset=0;\n" - "\tadd_l(15,offs);\n"); - gen_update_next_handler(); - isjump; - break; - case i_LINK: -/* failure; /* NEW: from "Ipswitch Town" release */ - genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0); - comprintf("\tsub_l_ri(15,4);\n" - "\twritelong_clobber(15,src,scratchie);\n" - "\tmov_l_rr(src,15);\n"); - if (curi->size==sz_word) - comprintf("\tsign_extend_16_rr(offs,offs);\n"); - comprintf("\tadd_l(15,offs);\n"); - genastore ("src", curi->smode, "srcreg", sz_long, "src"); - break; - case i_UNLK: -/* failure; /* NEW: from "Ipswitch Town" release */ - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - comprintf("\tmov_l_rr(15,src);\n" - "\treadlong(15,src,scratchie);\n" - "\tadd_l_ri(15,4);\n"); - genastore ("src", curi->smode, "srcreg", curi->size, "src"); - break; - case i_RTS: - comprintf("\tint newad=scratchie++;\n" - "\treadlong(15,newad,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc,newad);\n" - "\tget_n_addr_jmp(newad,PC_P,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" - "\tm68k_pc_offset=0;\n" - "\tlea_l_brr(15,15,4);\n"); - gen_update_next_handler(); - isjump; - break; - case i_TRAPV: - isjump; - failure; - break; - case i_RTR: - isjump; - failure; - break; - case i_JSR: - isjump; - genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); - start_brace(); - comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); - comprintf("\tint ret=scratchie++;\n" - "\tmov_l_ri(ret,retadd);\n" - "\tsub_l_ri(15,4);\n" - "\twritelong_clobber(15,ret,scratchie);\n"); - comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n" - "\tget_n_addr_jmp(srca,PC_P,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" - "\tm68k_pc_offset=0;\n"); - gen_update_next_handler(); - break; - case i_JMP: - isjump; - genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); - comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n" - "\tget_n_addr_jmp(srca,PC_P,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" - "\tm68k_pc_offset=0;\n"); - gen_update_next_handler(); - break; - case i_BSR: - is_const_jump; - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - start_brace(); - comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); - comprintf("\tint ret=scratchie++;\n" - "\tmov_l_ri(ret,retadd);\n" - "\tsub_l_ri(15,4);\n" - "\twritelong_clobber(15,ret,scratchie);\n"); - comprintf("\tadd_l_ri(src,m68k_pc_offset_thisinst+2);\n"); - comprintf("\tm68k_pc_offset=0;\n"); - comprintf("\tadd_l(PC_P,src);\n"); - - comprintf("\tcomp_pc_p=(uae_u8*)get_const(PC_P);\n"); - break; - case i_Bcc: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - /* That source is an immediate, so we can clobber it with abandon */ - switch(curi->size) { - case sz_byte: comprintf("\tsign_extend_8_rr(src,src);\n"); break; - case sz_word: comprintf("\tsign_extend_16_rr(src,src);\n"); break; - case sz_long: break; - } - comprintf("\tsub_l_ri(src,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); - /* Leave the following as "add" --- it will allow it to be optimized - away due to src being a constant ;-) */ - comprintf("\tadd_l_ri(src,(uintptr)comp_pc_p);\n"); - comprintf("\tmov_l_ri(PC_P,(uintptr)comp_pc_p);\n"); - /* Now they are both constant. Might as well fold in m68k_pc_offset */ - comprintf("\tadd_l_ri(src,m68k_pc_offset);\n"); - comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n"); - comprintf("\tm68k_pc_offset=0;\n"); - - if (curi->cc>=2) { - comprintf("\tuae_u32 v1=get_const(PC_P);\n" - "\tuae_u32 v2=get_const(src);\n" - "\tregister_branch(v1,v2,%d);\n", - cond_codes_x86[curi->cc]); - comprintf("\tmake_flags_live();\n"); /* Load the flags */ - isjump; - } - else { - is_const_jump; - } - - switch(curi->cc) { - case 0: /* Unconditional jump */ - comprintf("\tmov_l_rr(PC_P,src);\n"); - comprintf("\tcomp_pc_p=(uae_u8*)get_const(PC_P);\n"); - break; - case 1: break; /* This is silly! */ - case 8: failure; break; /* Work out details! FIXME */ - case 9: failure; break; /* Not critical, though! */ - - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - break; - default: abort(); - } - break; - case i_LEA: - genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); - genastore ("srca", curi->dmode, "dstreg", curi->size, "dst"); - break; - case i_PEA: - if (table68k[opcode].smode==Areg || - table68k[opcode].smode==Aind || - table68k[opcode].smode==Aipi || - table68k[opcode].smode==Apdi || - table68k[opcode].smode==Ad16 || - table68k[opcode].smode==Ad8r) - comprintf("if (srcreg==7) dodgy=1;\n"); - - genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); - genamode (Apdi, "7", sz_long, "dst", 2, 0); - genastore ("srca", Apdi, "7", sz_long, "dst"); - break; - case i_DBcc: - isjump; - uses_cmov; - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0); - - /* That offs is an immediate, so we can clobber it with abandon */ - switch(curi->size) { - case sz_word: comprintf("\tsign_extend_16_rr(offs,offs);\n"); break; - default: abort(); /* Seems this only comes in word flavour */ - } - comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); - comprintf("\tadd_l_ri(offs,(uintptr)comp_pc_p);\n"); /* New PC, - once the - offset_68k is - * also added */ - /* Let's fold in the m68k_pc_offset at this point */ - comprintf("\tadd_l_ri(offs,m68k_pc_offset);\n"); - comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n"); - comprintf("\tm68k_pc_offset=0;\n"); - - start_brace(); - comprintf("\tint nsrc=scratchie++;\n"); - - if (curi->cc>=2) { - comprintf("\tmake_flags_live();\n"); /* Load the flags */ - } - - if (curi->size!=sz_word) - abort(); - - - switch(curi->cc) { - case 0: /* This is an elaborate nop? */ - break; - case 1: - comprintf("\tstart_needflags();\n"); - comprintf("\tsub_w_ri(src,1);\n"); - comprintf("\t end_needflags();\n"); - start_brace(); - comprintf("\tuae_u32 v1=get_const(PC_P);\n"); - comprintf("\tuae_u32 v2=get_const(offs);\n" - "\tregister_branch(v1,v2,3);\n"); - break; - - case 8: failure; break; /* Work out details! FIXME */ - case 9: failure; break; /* Not critical, though! */ - - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - comprintf("\tmov_l_rr(nsrc,src);\n"); - comprintf("\tlea_l_brr(scratchie,src,(uae_s32)-1);\n" - "\tmov_w_rr(src,scratchie);\n"); - comprintf("\tcmov_l_rr(offs,PC_P,%d);\n", - cond_codes_x86[curi->cc]); - comprintf("\tcmov_l_rr(src,nsrc,%d);\n", - cond_codes_x86[curi->cc]); - /* OK, now for cc=true, we have src==nsrc and offs==PC_P, - so whether we move them around doesn't matter. However, - if cc=false, we have offs==jump_pc, and src==nsrc-1 */ - - comprintf("\t start_needflags();\n"); - comprintf("\ttest_w_rr(nsrc,nsrc);\n"); - comprintf("\t end_needflags();\n"); - comprintf("\tcmov_l_rr(PC_P,offs,5);\n"); - break; - default: abort(); - } - genastore ("src", curi->smode, "srcreg", curi->size, "src"); - gen_update_next_handler(); - break; - - case i_Scc: -/* failure; /* NEW: from "Ipswitch Town" release */ - genamode (curi->smode, "srcreg", curi->size, "src", 2, 0); - start_brace (); - comprintf ("\tint val = scratchie++;\n"); - - /* We set val to 0 if we really should use 255, and to 1 for real 0 */ - switch(curi->cc) { - case 0: /* Unconditional set */ - comprintf("\tmov_l_ri(val,0);\n"); - break; - case 1: - /* Unconditional not-set */ - comprintf("\tmov_l_ri(val,1);\n"); - break; - case 8: failure; break; /* Work out details! FIXME */ - case 9: failure; break; /* Not critical, though! */ - - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - comprintf("\tmake_flags_live();\n"); /* Load the flags */ - /* All condition codes can be inverted by changing the LSB */ - comprintf("\tsetcc(val,%d);\n", - cond_codes_x86[curi->cc]^1); break; - default: abort(); - } - comprintf("\tsub_b_ri(val,1);\n"); - genastore ("val", curi->smode, "srcreg", curi->size, "src"); - break; - case i_DIVU: - isjump; - failure; - break; - case i_DIVS: - isjump; - failure; - break; - case i_MULU: -/* failure; /* NEW: from "Ipswitch Town" release */ - comprintf("\tdont_care_flags();\n"); - genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); - genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0); - /* To do 16x16 unsigned multiplication, we actually use - 32x32 signed, and zero-extend the registers first. - That solves the problem of MUL needing dedicated registers - on the x86 */ - comprintf("\tzero_extend_16_rr(scratchie,src);\n" - "\tzero_extend_16_rr(dst,dst);\n" - "\timul_32_32(dst,scratchie);\n"); - genflags (flag_logical, sz_long, "dst", "", ""); - genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); - break; - case i_MULS: -/* failure; /* NEW: from "Ipswitch Town" release */ - comprintf("\tdont_care_flags();\n"); - genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); - genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0); - comprintf("\tsign_extend_16_rr(scratchie,src);\n" - "\tsign_extend_16_rr(dst,dst);\n" - "\timul_32_32(dst,scratchie);\n"); - genflags (flag_logical, sz_long, "dst", "", ""); - genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); - break; - case i_CHK: - isjump; - failure; - break; - - case i_CHK2: - isjump; - failure; - break; - - case i_ASR: - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " return;\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); - - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - if (curi->smode!=immi) { -/* failure; /* UNTESTED: NEW: from "Ipswitch Town" release */ - if (!noflags) { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n" - "\tint cdata=scratchie++;\n" - "\tint sdata=scratchie++;\n" - "\tint tmpcnt=scratchie++;\n"); - comprintf("\tmov_l_rr(sdata,data);\n" - "\tmov_l_rr(cdata,data);\n" - "\tmov_l_rr(tmpcnt,cnt);\n"); - switch (curi->size) { - case sz_byte: comprintf("\tshra_b_ri(sdata,7);\n"); break; - case sz_word: comprintf("\tshra_w_ri(sdata,15);\n"); break; - case sz_long: comprintf("\tshra_l_ri(sdata,31);\n"); break; - default: abort(); - } - /* sdata is now the MSB propagated to all bits for the - register of specified size */ - comprintf("\tand_l_ri(tmpcnt,63);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(data,tmpcnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshra_w_rr(data,tmpcnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshra_l_rr(data,tmpcnt);\n" - "\thighmask=0x20;\n"); - break; - } - comprintf("\ttest_l_ri(tmpcnt,highmask);\n"); - switch (curi->size) { - case sz_byte: comprintf("\tcmov_b_rr(data,sdata,NATIVE_CC_NE);\n"); break; - case sz_word: comprintf("\tcmov_w_rr(data,sdata,NATIVE_CC_NE);\n"); break; - case sz_long: comprintf("\tcmov_l_rr(data,sdata,NATIVE_CC_NE);\n"); break; - } - - /* Result of shift is now in data. Now we need to determine - the carry by shifting cdata one less */ - /* NOTE: carry bit is cleared if shift count is zero */ - comprintf("\tmov_l_ri(scratchie,0);\n" - "\ttest_l_rr(tmpcnt,tmpcnt);\n" - "\tcmov_l_rr(sdata,scratchie,NATIVE_CC_EQ);\n" - "\tforget_about(scratchie);\n"); - comprintf("\tsub_l_ri(tmpcnt,1);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(cdata,tmpcnt);\n");break; - case sz_word: comprintf("\tshra_w_rr(cdata,tmpcnt);\n");break; - case sz_long: comprintf("\tshra_l_rr(cdata,tmpcnt);\n");break; - default: abort(); - } - /* If the shift count was higher than the width, we need - to pick up the sign from original data (sdata) */ - /* NOTE: for shift count of zero, the following holds - true and cdata contains 0 so that carry bit is cleared */ - comprintf("\ttest_l_ri(tmpcnt,highmask);\n" - "\tforget_about(tmpcnt);\n" - "\tcmov_l_rr(cdata,sdata,NATIVE_CC_NE);\n"); - - /* And create the flags (preserve X flag if shift count is zero) */ - comprintf("\ttest_l_ri(cnt,63);\n" - "\tcmov_l_rr(FLAGX,cdata,NATIVE_CC_NE);\n"); - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - else { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n" - "\tint width;\n" - "\tint highshift=scratchie++;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n" - "\thighmask=0x38;\n" - "\twidth=8;\n"); - break; - case sz_word: comprintf("\tshra_w_rr(data,cnt);\n" - "\thighmask=0x30;\n" - "\twidth=16;\n"); - break; - case sz_long: comprintf("\tshra_l_rr(data,cnt);\n" - "\thighmask=0x20;\n" - "\twidth=32;\n"); - break; - default: abort(); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(highshift,0);\n" - "mov_l_ri(scratchie,width/2);\n" - "cmov_l_rr(highshift,scratchie,5);\n"); - /* The x86 masks out bits, so we now make sure that things - really get shifted as much as planned */ - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break; - case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break; - case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break; - default: abort(); - } - /* And again */ - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break; - case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break; - case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break; - default: abort(); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - } - else { - start_brace(); - comprintf("\tint tmp=scratchie++;\n" - "\tint bp;\n" - "\tmov_l_rr(tmp,data);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - case sz_word: comprintf("\tshra_w_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - case sz_long: comprintf("\tshra_l_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - default: abort(); - } - - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - break; - - case i_ASL: -/* failure; /* NEW: from "Ipswitch Town" release */ - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " return;\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); - /* Except for the handling of the V flag, this is identical to - LSL. The handling of V is, uhm, unpleasant, so if it's needed, - let the normal emulation handle it. Shoulders of giants kinda - thing ;-) */ - comprintf("if (needed_flags & FLAG_V) {\n" - " FAIL(1);\n" - " return;\n" - "} \n"); - - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - if (curi->smode!=immi) { - if (!noflags) { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n" - "\tint cdata=scratchie++;\n" - "\tint tmpcnt=scratchie++;\n"); - comprintf("\tmov_l_rr(tmpcnt,cnt);\n" - "\tand_l_ri(tmpcnt,63);\n" - "\tmov_l_ri(cdata,0);\n" - "\tcmov_l_rr(cdata,data,5);\n"); - /* cdata is now either data (for shift count!=0) or - 0 (for shift count==0) */ - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); - break; - default: abort(); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(scratchie,data,4);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; - default: abort(); - } - /* Result of shift is now in data. Now we need to determine - the carry by shifting cdata one less */ - comprintf("\tsub_l_ri(tmpcnt,1);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break; - case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break; - case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break; - default: abort(); - } - comprintf("test_l_ri(tmpcnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(cdata,scratchie,5);\n"); - /* And create the flags */ - comprintf("\tstart_needflags();\n"); - - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); - comprintf("\t bt_l_ri(cdata,7);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); - comprintf("\t bt_l_ri(cdata,15);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); - comprintf("\t bt_l_ri(cdata,31);\n"); break; - } - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - else { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); - break; - default: abort(); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(scratchie,data,4);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; - default: abort(); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - } - else { - start_brace(); - comprintf("\tint tmp=scratchie++;\n" - "\tint bp;\n" - "\tmov_l_rr(tmp,data);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n" - "\tbp=8-srcreg;\n"); break; - case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n" - "\tbp=16-srcreg;\n"); break; - case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n" - "\tbp=32-srcreg;\n"); break; - default: abort(); - } - - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - break; - - case i_LSR: -/* failure; /* NEW: from "Ipswitch Town" release */ - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " return;\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); - - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - if (curi->smode!=immi) { - if (!noflags) { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n" - "\tint cdata=scratchie++;\n" - "\tint tmpcnt=scratchie++;\n"); - comprintf("\tmov_l_rr(tmpcnt,cnt);\n" - "\tand_l_ri(tmpcnt,63);\n" - "\tmov_l_ri(cdata,0);\n" - "\tcmov_l_rr(cdata,data,NATIVE_CC_NE);\n"); - /* cdata is now either data (for shift count!=0) or - 0 (for shift count==0) */ - switch(curi->size) { - case sz_byte: comprintf("\tshrl_b_rr(data,tmpcnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshrl_w_rr(data,tmpcnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshrl_l_rr(data,tmpcnt);\n" - "\thighmask=0x20;\n"); - break; - default: abort(); - } - comprintf("\ttest_l_ri(tmpcnt,highmask);\n" - "\rmov_l_ri(scratchie,0);\n"); - if (curi->size == sz_long) - comprintf("\tcmov_l_rr(data,scratchie,NATIVE_CC_NE);\n"); - else { - comprintf("\tcmov_l_rr(scratchie,data,NATIVE_CC_EQ);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - default: abort(); - } - } - /* Result of shift is now in data. Now we need to determine - the carry by shifting cdata one less */ - comprintf("\tsub_l_ri(tmpcnt,1);\n"); - comprintf("\tshrl_l_rr(cdata,tmpcnt);\n"); - comprintf("\ttest_l_ri(tmpcnt,highmask);\n"); - comprintf("\tforget_about(tmpcnt);\n"); - if (curi->size != sz_long) /* scratchie is still live for LSR.L */ - comprintf("\tmov_l_ri(scratchie,0);\n"); - comprintf("\tcmov_l_rr(cdata,scratchie,NATIVE_CC_NE);\n"); - comprintf("\tforget_about(scratchie);\n"); - /* And create the flags (preserve X flag if shift count is zero) */ - comprintf("\ttest_l_ri(cnt,63);\n" - "\tcmov_l_rr(FLAGX,cdata,NATIVE_CC_NE);\n"); - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - else { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); - break; - default: abort(); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(scratchie,data,4);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; - default: abort(); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - } - else { - start_brace(); - comprintf("\tint tmp=scratchie++;\n" - "\tint bp;\n" - "\tmov_l_rr(tmp,data);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshrl_b_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - case sz_word: comprintf("\tshrl_w_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - case sz_long: comprintf("\tshrl_l_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - default: abort(); - } - - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - break; - - case i_LSL: - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " return;\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); - - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - if (curi->smode!=immi) { -/* failure; /* UNTESTED: NEW: from "Ipswitch Town" release */ - if (!noflags) { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n" - "\tint cdata=scratchie++;\n" - "\tint tmpcnt=scratchie++;\n"); - comprintf("\tmov_l_rr(tmpcnt,cnt);\n" - "\tand_l_ri(tmpcnt,63);\n" - "\tmov_l_ri(cdata,0);\n" - "\tcmov_l_rr(cdata,data,NATIVE_CC_NE);\n"); - /* cdata is now either data (for shift count!=0) or - 0 (for shift count==0) */ - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_rr(data,tmpcnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshll_w_rr(data,tmpcnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshll_l_rr(data,tmpcnt);\n" - "\thighmask=0x20;\n"); - break; - default: abort(); - } - comprintf("\ttest_l_ri(tmpcnt,highmask);\n" - "\tmov_l_ri(scratchie,0);\n"); - if (curi->size == sz_long) - comprintf("\tcmov_l_rr(data,scratchie,NATIVE_CC_NE);\n"); - else { - comprintf("\tcmov_l_rr(scratchie,data,NATIVE_CC_EQ);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - default: abort(); - } - } - /* Result of shift is now in data. Now we need to determine - the carry by shifting cdata one less */ - comprintf("\tsub_l_ri(tmpcnt,1);\n"); - comprintf("\tshll_l_rr(cdata,tmpcnt);\n"); - comprintf("\ttest_l_ri(tmpcnt,highmask);\n"); - comprintf("\tforget_about(tmpcnt);\n"); - if (curi->size != sz_long) /* scratchie is still live for LSL.L */ - comprintf("\tmov_l_ri(scratchie,0);\n"); - comprintf("\tcmov_l_rr(cdata,scratchie,NATIVE_CC_NE);\n"); - comprintf("\tforget_about(scratchie);\n"); - /* And create the flags (preserve X flag if shift count is zero) */ - switch (curi->size) { - case sz_byte: comprintf("\tshrl_l_ri(cdata,7);\n"); break; - case sz_word: comprintf("\tshrl_l_ri(cdata,15);\n"); break; - case sz_long: comprintf("\tshrl_l_ri(cdata,31);\n"); break; - } - comprintf("\ttest_l_ri(cnt,63);\n" - "\tcmov_l_rr(FLAGX,cdata,NATIVE_CC_NE);\n"); - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(cdata,0);\n"); - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - else { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); - break; - default: abort(); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(scratchie,data,4);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; - default: abort(); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - } - else { - start_brace(); - comprintf("\tint tmp=scratchie++;\n" - "\tint bp;\n" - "\tmov_l_rr(tmp,data);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n" - "\tbp=8-srcreg;\n"); break; - case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n" - "\tbp=16-srcreg;\n"); break; - case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n" - "\tbp=32-srcreg;\n"); break; - default: abort(); - } - - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - break; - - case i_ROL: - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " return;\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - start_brace (); - - switch(curi->size) { - case sz_long: comprintf("\t rol_l_rr(data,cnt);\n"); break; - case sz_word: comprintf("\t rol_w_rr(data,cnt);\n"); break; - case sz_byte: comprintf("\t rol_b_rr(data,cnt);\n"); break; - } - - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(data,0x00);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - break; - - case i_ROR: - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " return;\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - start_brace (); - - switch(curi->size) { - case sz_long: comprintf("\t ror_l_rr(data,cnt);\n"); break; - case sz_word: comprintf("\t ror_w_rr(data,cnt);\n"); break; - case sz_byte: comprintf("\t ror_b_rr(data,cnt);\n"); break; - } - - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - switch(curi->size) { - case sz_byte: comprintf("\t bt_l_ri(data,0x07);\n"); break; - case sz_word: comprintf("\t bt_l_ri(data,0x0f);\n"); break; - case sz_long: comprintf("\t bt_l_ri(data,0x1f);\n"); break; - } - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - break; - - case i_ROXL: - failure; - break; - case i_ROXR: - failure; - break; - case i_ASRW: - failure; - break; - case i_ASLW: - failure; - break; - case i_LSRW: - failure; - break; - case i_LSLW: - failure; - break; - case i_ROLW: - failure; - break; - case i_RORW: - failure; - break; - case i_ROXLW: - failure; - break; - case i_ROXRW: - failure; - break; - case i_MOVEC2: - isjump; - failure; - break; - case i_MOVE2C: - isjump; - failure; - break; - case i_CAS: - failure; - break; - case i_CAS2: - failure; - break; - case i_MOVES: /* ignore DFC and SFC because we have no MMU */ - isjump; - failure; - break; - case i_BKPT: /* only needed for hardware emulators */ - isjump; - failure; - break; - case i_CALLM: /* not present in 68030 */ - isjump; - failure; - break; - case i_RTM: /* not present in 68030 */ - isjump; - failure; - break; - case i_TRAPcc: - isjump; - failure; - break; - case i_DIVL: - isjump; - failure; - break; - case i_MULL: -/* failure; /* NEW: from "Ipswitch Town" release */ - if (!noflags) { - failure; - break; - } - comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); - comprintf("\tint r2=(extra>>12)&7;\n" - "\tint tmp=scratchie++;\n"); - - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - /* The two operands are in dst and r2 */ - comprintf("\tif (extra&0x0400) {\n" /* Need full 64 bit result */ - "\tint r3=(extra&7);\n" - "\tmov_l_rr(r3,dst);\n"); /* operands now in r3 and r2 */ - comprintf("\tif (extra&0x0800) { \n" /* signed */ - "\t\timul_64_32(r2,r3);\n" - "\t} else { \n" - "\t\tmul_64_32(r2,r3);\n" - "\t} \n"); - /* The result is in r2/tmp, with r2 holding the lower 32 bits */ - comprintf("\t} else {\n"); /* Only want 32 bit result */ - /* operands in dst and r2, result foes into r2 */ - /* shouldn't matter whether it's signed or unsigned?!? */ - comprintf("\timul_32_32(r2,dst);\n" - "\t}\n"); - break; - - case i_BFTST: - case i_BFEXTU: - case i_BFCHG: - case i_BFEXTS: - case i_BFCLR: - case i_BFFFO: - case i_BFSET: - case i_BFINS: - failure; - break; - case i_PACK: - failure; - break; - case i_UNPK: - failure; - break; - case i_TAS: - failure; - break; - case i_FPP: - uses_fpu; -#ifdef USE_JIT_FPU - mayfail; - comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); - swap_opcode(); - comprintf("\tcomp_fpp_opp(opcode,extra);\n"); -#else - failure; -#endif - break; - case i_FBcc: - uses_fpu; -#ifdef USE_JIT_FPU - isjump; - uses_cmov; - mayfail; - swap_opcode(); - comprintf("\tcomp_fbcc_opp(opcode);\n"); -#else - isjump; - failure; -#endif - break; - case i_FDBcc: - uses_fpu; - isjump; - failure; - break; - case i_FScc: - uses_fpu; -#ifdef USE_JIT_FPU - mayfail; - uses_cmov; - comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); - swap_opcode(); - comprintf("\tcomp_fscc_opp(opcode,extra);\n"); -#else - failure; -#endif - break; - case i_FTRAPcc: - uses_fpu; - isjump; - failure; - break; - case i_FSAVE: - uses_fpu; - failure; - break; - case i_FRESTORE: - uses_fpu; - failure; - break; - - case i_CINVL: - case i_CINVP: - case i_CINVA: - isjump; /* Not really, but it's probably a good idea to stop - translating at this point */ - failure; - comprintf ("\tflush_icache();\n"); /* Differentiate a bit more? */ - break; - case i_CPUSHL: - case i_CPUSHP: - case i_CPUSHA: - isjump; /* Not really, but it's probably a good idea to stop - translating at this point */ - failure; - break; - case i_MOVE16: - genmov16(opcode, curi); - break; - - case i_EMULOP_RETURN: - isjump; - failure; - break; - - case i_EMULOP: - failure; - break; - - case i_MMUOP: - isjump; - failure; - break; - default: - abort (); - break; - } - comprintf("%s",endstr); - finish_braces (); - sync_m68k_pc (); - if (global_mayfail) - comprintf("\tif (failure) m68k_pc_offset=m68k_pc_offset_thisinst;\n"); - return global_failure; -} - -static void -generate_includes (FILE * f) -{ - fprintf (f, "#include \"sysdeps.h\"\n"); - fprintf (f, "#include \"m68k.h\"\n"); - fprintf (f, "#include \"memory.h\"\n"); - fprintf (f, "#include \"readcpu.h\"\n"); - fprintf (f, "#include \"newcpu.h\"\n"); - fprintf (f, "#include \"comptbl.h\"\n"); -} - -static int postfix; - -static void -generate_one_opcode (int rp, int noflags) -{ - uae_u16 smsk, dmsk; - const long int opcode = opcode_map[rp]; - const char *opcode_str; - int aborted=0; - int have_srcreg=0; - int have_dstreg=0; - - if (table68k[opcode].mnemo == i_ILLG - || table68k[opcode].clev > cpu_level) - return; - - if (table68k[opcode].handler != -1) - return; - - switch (table68k[opcode].stype) - { - case 0: - smsk = 7; - break; - case 1: - smsk = 255; - break; - case 2: - smsk = 15; - break; - case 3: - smsk = 7; - break; - case 4: - smsk = 7; - break; - case 5: - smsk = 63; - break; - case 6: - smsk = 255; - break; - case 7: - smsk = 3; - break; - default: - abort (); - } - dmsk = 7; - - next_cpu_level = -1; - if (table68k[opcode].suse - && table68k[opcode].smode != imm && table68k[opcode].smode != imm0 - && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2 - && table68k[opcode].smode != absw && table68k[opcode].smode != absl - && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16) - { - have_srcreg=1; - if (table68k[opcode].spos == -1) - { - if (((int) table68k[opcode].sreg) >= 128) - comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg); - else - comprintf ("\tuae_s32 srcreg = %d;\n", (int) table68k[opcode].sreg); - } - else - { - char source[100]; - int pos = table68k[opcode].spos; - - comprintf ("#ifdef HAVE_GET_WORD_UNSWAPPED\n"); - - if (pos < 8 && (smsk >> (8 - pos)) != 0) - sprintf (source, "(((opcode >> %d) | (opcode << %d)) & %d)", - pos ^ 8, 8 - pos, dmsk); - else if (pos != 8) - sprintf (source, "((opcode >> %d) & %d)", pos ^ 8, smsk); - else - sprintf (source, "(opcode & %d)", smsk); - - if (table68k[opcode].stype == 3) - comprintf ("\tuae_u32 srcreg = imm8_table[%s];\n", source); - else if (table68k[opcode].stype == 1) - comprintf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source); - else - comprintf ("\tuae_u32 srcreg = %s;\n", source); - - comprintf ("#else\n"); - - if (pos) - sprintf (source, "((opcode >> %d) & %d)", pos, smsk); - else - sprintf (source, "(opcode & %d)", smsk); - - if (table68k[opcode].stype == 3) - comprintf ("\tuae_s32 srcreg = imm8_table[%s];\n", source); - else if (table68k[opcode].stype == 1) - comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%s;\n", source); - else - comprintf ("\tuae_s32 srcreg = %s;\n", source); - - comprintf ("#endif\n"); - } - } - if (table68k[opcode].duse - /* Yes, the dmode can be imm, in case of LINK or DBcc */ - && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0 - && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2 - && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) - { - have_dstreg=1; - if (table68k[opcode].dpos == -1) - { - if (((int) table68k[opcode].dreg) >= 128) - comprintf ("\tuae_s32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg); - else - comprintf ("\tuae_s32 dstreg = %d;\n", (int) table68k[opcode].dreg); - } - else - { - int pos = table68k[opcode].dpos; - - comprintf ("#ifdef HAVE_GET_WORD_UNSWAPPED\n"); - - if (pos < 8 && (dmsk >> (8 - pos)) != 0) - comprintf ("\tuae_u32 dstreg = ((opcode >> %d) | (opcode << %d)) & %d;\n", - pos ^ 8, 8 - pos, dmsk); - else if (pos != 8) - comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", - pos ^ 8, dmsk); - else - comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk); - - comprintf ("#else\n"); - - if (pos) - comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", - pos, dmsk); - else - comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk); - - comprintf ("#endif\n"); - } - } - - if (have_srcreg && have_dstreg && - (table68k[opcode].dmode==Areg || - table68k[opcode].dmode==Aind || - table68k[opcode].dmode==Aipi || - table68k[opcode].dmode==Apdi || - table68k[opcode].dmode==Ad16 || - table68k[opcode].dmode==Ad8r) && - (table68k[opcode].smode==Areg || - table68k[opcode].smode==Aind || - table68k[opcode].smode==Aipi || - table68k[opcode].smode==Apdi || - table68k[opcode].smode==Ad16 || - table68k[opcode].smode==Ad8r) - ) { - comprintf("\tuae_u32 dodgy=(srcreg==(uae_s32)dstreg);\n"); - } - else { - comprintf("\tuae_u32 dodgy=0;\n"); - } - comprintf("\tuae_u32 m68k_pc_offset_thisinst=m68k_pc_offset;\n"); - comprintf("\tm68k_pc_offset+=2;\n"); - - opcode_str = get_instruction_string (opcode); - - aborted=gen_opcode (opcode); - { - int flags=0; - if (global_isjump) flags|=1; - if (long_opcode) flags|=2; - if (global_cmov) flags|=4; - if (global_isaddx) flags|=8; - if (global_iscjump) flags|=16; - if (global_fpu) flags|=32; - - comprintf ("}\n"); - - if (aborted) { - fprintf (stblfile, "{ NULL, 0x%08x, %ld }, /* %s */\n", flags, opcode, opcode_str); - com_discard(); - } - else { - if (noflags) { - fprintf (stblfile, "{ op_%lx_%d_comp_nf, 0x%08x, %ld }, /* %s */\n", opcode, postfix, flags, opcode, opcode_str); - fprintf (headerfile, "extern compop_func op_%lx_%d_comp_nf;\n", opcode, postfix); - printf ("void REGPARAM2 op_%lx_%d_comp_nf(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, opcode_str); - } - else { - fprintf (stblfile, "{ op_%lx_%d_comp_ff, 0x%08x, %ld }, /* %s */\n", opcode, postfix, flags, opcode, opcode_str); - fprintf (headerfile, "extern compop_func op_%lx_%d_comp_ff;\n", opcode, postfix); - printf ("void REGPARAM2 op_%lx_%d_comp_ff(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, opcode_str); - } - com_flush(); - } - } - opcode_next_clev[rp] = next_cpu_level; - opcode_last_postfix[rp] = postfix; -} - -static void -generate_func (int noflags) -{ - int i, j, rp; - - using_prefetch = 0; - using_exception_3 = 0; - for (i = 0; i < 1; i++) /* We only do one level! */ - { - cpu_level = 4 - i; - postfix = i; - - if (noflags) - fprintf (stblfile, "struct comptbl op_smalltbl_%d_comp_nf[] = {\n", postfix); - else - fprintf (stblfile, "struct comptbl op_smalltbl_%d_comp_ff[] = {\n", postfix); - - - /* sam: this is for people with low memory (eg. me :)) */ - printf ("\n" - "#if !defined(PART_1) && !defined(PART_2) && " - "!defined(PART_3) && !defined(PART_4) && " - "!defined(PART_5) && !defined(PART_6) && " - "!defined(PART_7) && !defined(PART_8)" - "\n" - "#define PART_1 1\n" - "#define PART_2 1\n" - "#define PART_3 1\n" - "#define PART_4 1\n" - "#define PART_5 1\n" - "#define PART_6 1\n" - "#define PART_7 1\n" - "#define PART_8 1\n" - "#endif\n\n"); - - rp = 0; - for (j = 1; j <= 8; ++j) - { - int k = (j * nr_cpuop_funcs) / 8; - printf ("#ifdef PART_%d\n", j); - for (; rp < k; rp++) - generate_one_opcode (rp,noflags); - printf ("#endif\n\n"); - } - - fprintf (stblfile, "{ 0, 0,65536 }};\n"); - } - -} - -int -main (int argc, char **argv) -{ - read_table68k (); - do_merges (); - - opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - counts = (unsigned long *) malloc (65536 * sizeof (unsigned long)); - read_counts (); - - /* It would be a lot nicer to put all in one file (we'd also get rid of - * cputbl.h that way), but cpuopti can't cope. That could be fixed, but - * I don't dare to touch the 68k version. */ - - headerfile = fopen ("comptbl.h", "wb"); - stblfile = fopen ("compstbl.cpp", "wb"); - freopen ("compemu.cpp", "wb", stdout); - - generate_includes (stdout); - generate_includes (stblfile); - - printf("#include \"compiler/compemu.h\"\n"); - - noflags=0; - generate_func (noflags); - - free(opcode_map); - free(opcode_last_postfix); - free(opcode_next_clev); - free(counts); - - opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - counts = (unsigned long *) malloc (65536 * sizeof (unsigned long)); - read_counts (); - noflags=1; - generate_func (noflags); - - free(opcode_map); - free(opcode_last_postfix); - free(opcode_next_clev); - free(counts); - - free (table68k); - fclose (stblfile); - fclose (headerfile); - fflush (stdout); - return 0; -} diff --git a/BasiliskII/src/uae_cpu/compiler/test_codegen_x86.cpp b/BasiliskII/src/uae_cpu/compiler/test_codegen_x86.cpp deleted file mode 100644 index 236a2d5e..00000000 --- a/BasiliskII/src/uae_cpu/compiler/test_codegen_x86.cpp +++ /dev/null @@ -1,2254 +0,0 @@ -/******************** -*- mode: C; tab-width: 8 -*- ******************** - * - * Dumb and Brute Force Run-time assembler verifier for IA-32 and AMD64 - * - ***********************************************************************/ - - -/*********************************************************************** - * - * Copyright 2004-2008 Gwenole Beauchesne - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - ***********************************************************************/ - -/* - * STATUS: 26M variations covering unary register based operations, - * reg/reg operations, imm/reg operations. - * - * TODO: - * - Rewrite to use internal BFD/opcodes format instead of string compares - * - Add reg/mem, imm/mem variations - */ - -#define _BSD_SOURCE 1 -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" - -static int verbose = 2; - -#define TEST_INST_ALU 1 -#define TEST_INST_FPU 1 -#define TEST_INST_MMX 1 -#define TEST_INST_SSE 1 -#if TEST_INST_ALU -#define TEST_INST_ALU_REG 1 -#define TEST_INST_ALU_REG_REG 1 -#define TEST_INST_ALU_CNT_REG 1 -#define TEST_INST_ALU_IMM_REG 1 -#define TEST_INST_ALU_MEM_REG 1 -#endif -#if TEST_INST_FPU -#define TEST_INST_FPU_UNARY 1 -#define TEST_INST_FPU_REG 1 -#define TEST_INST_FPU_MEM 1 -#endif -#if TEST_INST_MMX -#define TEST_INST_MMX_REG_REG 1 -#define TEST_INST_MMX_IMM_REG 1 -#define TEST_INST_MMX_MEM_REG 1 -#endif -#if TEST_INST_SSE -#define TEST_INST_SSE_REG 1 -#define TEST_INST_SSE_REG_REG 1 -#define TEST_INST_SSE_MEM_REG 1 -#endif - -#undef abort -#define abort() do { \ - fprintf(stderr, "ABORT: %s, line %d\n", __FILE__, __LINE__); \ - (abort)(); \ -} while (0) - -#define X86_TARGET_64BIT 1 -#define X86_FLAT_REGISTERS 0 -#define X86_OPTIMIZE_ALU 1 -#define X86_OPTIMIZE_ROTSHI 1 -#define X86_RIP_RELATIVE_ADDR 0 -#include "compiler/codegen_x86.h" - -#if X86_TARGET_64BIT -#define X86_MAX_ALU_REGS 16 -#define X86_MAX_SSE_REGS 16 -#else -#define X86_MAX_ALU_REGS 8 -#define X86_MAX_SSE_REGS 8 -#endif -#define X86_MAX_FPU_REGS 8 -#define X86_MAX_MMX_REGS 8 - -#define VALID_REG(r, b, n) (((unsigned)((r) - X86_##b)) < (n)) -#if X86_TARGET_64BIT -#define VALID_REG8(r) (VALID_REG(r, AL, 16) || VALID_REG(r, AH, 4)) -#define VALID_REG64(r) VALID_REG(r, RAX, X86_MAX_ALU_REGS) -#else -#define VALID_REG8(r) (VALID_REG(r, AL, 4) || VALID_REG(r, AH, 4)) -#define VALID_REG64(r) (0) -#endif -#define VALID_REG16(r) VALID_REG(r, AX, X86_MAX_ALU_REGS) -#define VALID_REG32(r) VALID_REG(r, EAX, X86_MAX_ALU_REGS) - -#define x86_emit_byte(B) emit_byte(B) -#define x86_emit_word(W) emit_word(W) -#define x86_emit_long(L) emit_long(L) -#define x86_emit_quad(Q) emit_quad(Q) -#define x86_get_target() get_target() -#define x86_emit_failure(MSG) jit_fail(MSG, __FILE__, __LINE__, __FUNCTION__) - -static void jit_fail(const char *msg, const char *file, int line, const char *function) -{ - fprintf(stderr, "JIT failure in function %s from file %s at line %d: %s\n", - function, file, line, msg); - abort(); -} - -static uint8 *target; - -static inline void emit_byte(uint8 x) -{ - *target++ = x; -} - -static inline void emit_word(uint16 x) -{ - *((uint16 *)target) = x; - target += 2; -} - -static inline void emit_long(uint32 x) -{ - *((uint32 *)target) = x; - target += 4; -} - -static inline void emit_quad(uint64 x) -{ - *((uint64 *)target) = x; - target += 8; -} - -static inline void set_target(uint8 *t) -{ - target = t; -} - -static inline uint8 *get_target(void) -{ - return target; -} - -static uint32 mon_read_byte(uintptr addr) -{ - uint8 *m = (uint8 *)addr; - return (uint32)(*m); -} - -extern "C" { -#include "disass/dis-asm.h" - -int buffer_read_memory(bfd_vma from, bfd_byte *to, unsigned int length, struct disassemble_info *info) -{ - while (length--) - *to++ = mon_read_byte(from++); - return 0; -} - -void perror_memory(int status, bfd_vma memaddr, struct disassemble_info *info) -{ - info->fprintf_func(info->stream, "Unknown error %d\n", status); -} - -void generic_print_address(bfd_vma addr, struct disassemble_info *info) -{ - if (addr >= UVAL64(0x100000000)) - info->fprintf_func(info->stream, "$%08x%08x", (uint32)(addr >> 32), (uint32)addr); - else - info->fprintf_func(info->stream, "$%08x", (uint32)addr); -} - -int generic_symbol_at_address(bfd_vma addr, struct disassemble_info *info) -{ - return 0; -} -} - -struct SFILE { - char *buffer; - char *current; -}; - -static int mon_sprintf(SFILE *f, const char *format, ...) -{ - int n; - va_list args; - va_start(args, format); - vsprintf(f->current, format, args); - f->current += n = strlen(f->current); - va_end(args); - return n; -} - -static int disass_x86(char *buf, uintptr adr) -{ - disassemble_info info; - SFILE sfile; - sfile.buffer = buf; - sfile.current = buf; - INIT_DISASSEMBLE_INFO(info, (FILE *)&sfile, (fprintf_ftype)mon_sprintf); - info.mach = X86_TARGET_64BIT ? bfd_mach_x86_64 : bfd_mach_i386_i386; - info.disassembler_options = "suffix"; - return print_insn_i386(adr, &info); -} - -enum { - op_disp, - op_reg, - op_base, - op_index, - op_scale, - op_imm, -}; -struct operand_t { - int32 disp; - int8 reg; - int8 base; - int8 index; - int8 scale; - int64 imm; - - void clear() { - disp = imm = 0; - reg = base = index = -1; - scale = 1; - } - - void fill(int optype, int value) { - switch (optype) { - case op_disp: disp = value; break; - case op_reg: reg = value; break; - case op_base: base = value; break; - case op_index: index = value; break; - case op_scale: scale = value; break; - case op_imm: imm = value; break; - default: abort(); - } - } -}; - -#define MAX_INSNS 1024 -#define MAX_INSN_LENGTH 16 -#define MAX_INSN_OPERANDS 3 - -struct insn_t { - char name[16]; - int n_operands; - operand_t operands[MAX_INSN_OPERANDS]; - - void clear() { - memset(name, 0, sizeof(name)); - n_operands = 0; - for (int i = 0; i < MAX_INSN_OPERANDS; i++) - operands[i].clear(); - } - - void pretty_print() { - printf("%s, %d operands\n", name, n_operands); - for (int i = 0; i < n_operands; i++) { - operand_t *op = &operands[i]; - if (op->reg != -1) - printf(" reg r%d\n", op->reg); - else { - printf(" mem 0x%08x(", op->disp); - if (op->base != -1) - printf("r%d", op->base); - printf(","); - if (op->index != -1) - printf("r%d", op->index); - printf(","); - if (op->base != -1 || op->index != -1) - printf("%d", op->scale); - printf(")\n"); - } - } - } -}; - -static inline char *find_blanks(char *p) -{ - while (*p && !isspace(*p)) - ++p; - return p; -} - -static inline char *skip_blanks(char *p) -{ - while (*p && isspace(*p)) - ++p; - return p; -} - -static int parse_reg(operand_t *op, int optype, char *buf) -{ - int reg = X86_NOREG; - int len = 0; - char *p = buf; - switch (p[0]) { - case 'a': case 'A': - len = 2; - switch (p[1]) { - case 'l': case 'L': reg = X86_AL; break; - case 'h': case 'H': reg = X86_AH; break; - case 'x': case 'X': reg = X86_AX; break; - } - break; - case 'b': case 'B': - len = 2; - switch (p[1]) { - case 'l': case 'L': reg = X86_BL; break; - case 'h': case 'H': reg = X86_BH; break; - case 'x': case 'X': reg = X86_BX; break; - case 'p': case 'P': - switch (p[2]) { -#if X86_TARGET_64BIT - case 'l': case 'L': reg = X86_BPL, ++len; break; -#endif - default: reg = X86_BP; break; - } - break; - } - break; - case 'c': case 'C': - len = 2; - switch (p[1]) { - case 'l': case 'L': reg = X86_CL; break; - case 'h': case 'H': reg = X86_CH; break; - case 'x': case 'X': reg = X86_CX; break; - } - break; - case 'd': case 'D': - len = 2; - switch (p[1]) { - case 'l': case 'L': reg = X86_DL; break; - case 'h': case 'H': reg = X86_DH; break; - case 'x': case 'X': reg = X86_DX; break; - case 'i': case 'I': - switch (p[2]) { -#if X86_TARGET_64BIT - case 'l': case 'L': reg = X86_DIL; ++len; break; -#endif - default: reg = X86_DI; break; - } - break; - } - break; - case 's': case 'S': - len = 2; - switch (p[2]) { -#if X86_TARGET_64BIT - case 'l': case 'L': - ++len; - switch (p[1]) { - case 'p': case 'P': reg = X86_SPL; break; - case 'i': case 'I': reg = X86_SIL; break; - } - break; -#endif - case '(': - if ((p[1] == 't' || p[1] == 'T') && isdigit(p[3]) && p[4] == ')') - len += 3, reg = X86_ST0 + (p[3] - '0'); - break; - default: - switch (p[1]) { - case 't': case 'T': reg = X86_ST0; break; - case 'p': case 'P': reg = X86_SP; break; - case 'i': case 'I': reg = X86_SI; break; - } - break; - } - break; - case 'e': case 'E': - len = 3; - switch (p[2]) { - case 'x': case 'X': - switch (p[1]) { - case 'a': case 'A': reg = X86_EAX; break; - case 'b': case 'B': reg = X86_EBX; break; - case 'c': case 'C': reg = X86_ECX; break; - case 'd': case 'D': reg = X86_EDX; break; - } - break; - case 'i': case 'I': - switch (p[1]) { - case 's': case 'S': reg = X86_ESI; break; - case 'd': case 'D': reg = X86_EDI; break; - } - break; - case 'p': case 'P': - switch (p[1]) { - case 'b': case 'B': reg = X86_EBP; break; - case 's': case 'S': reg = X86_ESP; break; - } - break; - } - break; -#if X86_TARGET_64BIT - case 'r': case 'R': - len = 3; - switch (p[2]) { - case 'x': case 'X': - switch (p[1]) { - case 'a': case 'A': reg = X86_RAX; break; - case 'b': case 'B': reg = X86_RBX; break; - case 'c': case 'C': reg = X86_RCX; break; - case 'd': case 'D': reg = X86_RDX; break; - } - break; - case 'i': case 'I': - switch (p[1]) { - case 's': case 'S': reg = X86_RSI; break; - case 'd': case 'D': reg = X86_RDI; break; - } - break; - case 'p': case 'P': - switch (p[1]) { - case 'b': case 'B': reg = X86_RBP; break; - case 's': case 'S': reg = X86_RSP; break; - } - break; - case 'b': case 'B': - switch (p[1]) { - case '8': reg = X86_R8B; break; - case '9': reg = X86_R9B; break; - } - break; - case 'w': case 'W': - switch (p[1]) { - case '8': reg = X86_R8W; break; - case '9': reg = X86_R9W; break; - } - break; - case 'd': case 'D': - switch (p[1]) { - case '8': reg = X86_R8D; break; - case '9': reg = X86_R9D; break; - } - break; - case '0': case '1': case '2': case '3': case '4': case '5': - if (p[1] == '1') { - const int r = p[2] - '0'; - switch (p[3]) { - case 'b': case 'B': reg = X86_R10B + r, ++len; break; - case 'w': case 'W': reg = X86_R10W + r, ++len; break; - case 'd': case 'D': reg = X86_R10D + r, ++len; break; - default: reg = X86_R10 + r; break; - } - } - break; - default: - switch (p[1]) { - case '8': reg = X86_R8, len = 2; break; - case '9': reg = X86_R9, len = 2; break; - } - break; - } - break; -#endif - case 'm': case 'M': - if ((p[1] == 'm' || p[1] == 'M') && isdigit(p[2])) - reg = X86_MM0 + (p[2] - '0'), len = 3; - break; - case 'x': case 'X': - if ((p[1] == 'm' || p[1] == 'M') && (p[2] == 'm' || p[2] == 'M')) { -#if X86_TARGET_64BIT - if (p[3] == '1' && isdigit(p[4])) - reg = X86_XMM10 + (p[4] - '0'), len = 5; - else -#endif - if (isdigit(p[3])) - reg = X86_XMM0 + (p[3] - '0'), len = 4; - } - break; - } - - if (len > 0 && reg != X86_NOREG) { - op->fill(optype, reg); - return len; - } - - return X86_NOREG; -} - -static unsigned long parse_imm(char *nptr, char **endptr, int base = 0) -{ - errno = 0; -#if X86_TARGET_64BIT - if (sizeof(unsigned long) != 8) { - unsigned long long val = strtoull(nptr, endptr, 0); - if (errno == 0) - return val; - abort(); - } -#endif - unsigned long val = strtoul(nptr, endptr, 0); - if (errno == 0) - return val; - abort(); - return 0; -} - -static int parse_mem(operand_t *op, char *buf) -{ - char *p = buf; - - if (strncmp(buf, "0x", 2) == 0) - op->disp = parse_imm(buf, &p, 16); - - if (*p == '(') { - p++; - - if (*p == '%') { - p++; - - int n = parse_reg(op, op_base, p); - if (n <= 0) - return -3; - p += n; - } - - if (*p == ',') { - p++; - - if (*p == '%') { - int n = parse_reg(op, op_index, ++p); - if (n <= 0) - return -4; - p += n; - - if (*p != ',') - return -5; - p++; - - goto do_parse_scale; - } - else if (isdigit(*p)) { - do_parse_scale: - long val = strtol(p, &p, 10); - if (val == 0 && errno == EINVAL) - abort(); - op->scale = val; - } - } - - if (*p != ')') - return -6; - p++; - } - - return p - buf; -} - -static void parse_insn(insn_t *ii, char *buf) -{ - char *p = buf; - ii->clear(); - -#if 0 - printf("BUF: %s\n", buf); -#endif - - if (strncmp(p, "rex64", 5) == 0) { - char *q = find_blanks(p); - if (verbose > 1) { - char prefix[16]; - memset(prefix, 0, sizeof(prefix)); - memcpy(prefix, p, q - p); - fprintf(stderr, "Instruction '%s', skip REX prefix '%s'\n", buf, prefix); - } - p = skip_blanks(q); - } - - if (strncmp(p, "rep", 3) == 0) { - char *q = find_blanks(p); - if (verbose > 1) { - char prefix[16]; - memset(prefix, 0, sizeof(prefix)); - memcpy(prefix, p, q - p); - fprintf(stderr, "Instruction '%s', skip REP prefix '%s'\n", buf, prefix); - } - p = skip_blanks(q); - } - - for (int i = 0; !isspace(*p); i++) - ii->name[i] = *p++; - - while (*p && isspace(*p)) - p++; - if (*p == '\0') - return; - - int n_operands = 0; - int optype = op_reg; - bool done = false; - while (!done) { - int n; - switch (*p) { - case '%': - n = parse_reg(&ii->operands[n_operands], optype, ++p); - if (n <= 0) { - fprintf(stderr, "parse_reg(%s) error %d\n", p, n); - abort(); - } - p += n; - break; - case '0': case '(': - n = parse_mem(&ii->operands[n_operands], p); - if (n <= 0) { - fprintf(stderr, "parse_mem(%s) error %d\n", p, n); - abort(); - } - p += n; - break; - case '$': { - ii->operands[n_operands].imm = parse_imm(++p, &p, 0); - break; - } - case '*': - p++; - break; - case ',': - n_operands++; - p++; - break; - case ' ': case '\t': - p++; - break; - case '\0': - done = true; - break; - default: - fprintf(stderr, "parse error> %s\n", p); - abort(); - } - } - ii->n_operands = n_operands + 1; -} - -static unsigned long n_tests, n_failures; -static unsigned long n_all_tests, n_all_failures; - -static bool check_unary(insn_t *ii, const char *name) -{ - if (strcasecmp(ii->name, name) != 0) { - fprintf(stderr, "ERROR: instruction mismatch, expected %s, got %s\n", name, ii->name); - return false; - } - - if (ii->n_operands != 0) { - fprintf(stderr, "ERROR: instruction expected 0 operand, got %d\n", ii->n_operands); - return false; - } - - return true; -} - -static bool check_reg(insn_t *ii, const char *name, int r) -{ - if (strcasecmp(ii->name, name) != 0) { - fprintf(stderr, "ERROR: instruction mismatch, expected %s, got %s\n", name, ii->name); - return false; - } - - if (ii->n_operands != 1) { - fprintf(stderr, "ERROR: instruction expected 1 operand, got %d\n", ii->n_operands); - return false; - } - - int reg = ii->operands[0].reg; - - if (reg != r) { - fprintf(stderr, "ERROR: instruction expected r%d as source, got ", r); - if (reg == -1) - fprintf(stderr, "nothing\n"); - else - fprintf(stderr, "r%d\n", reg); - return false; - } - - return true; -} - -static bool check_reg_reg(insn_t *ii, const char *name, int s, int d) -{ - if (strcasecmp(ii->name, name) != 0) { - fprintf(stderr, "ERROR: instruction mismatch, expected %s, got %s\n", name, ii->name); - return false; - } - - if (ii->n_operands != 2) { - fprintf(stderr, "ERROR: instruction expected 2 operands, got %d\n", ii->n_operands); - return false; - } - - int srcreg = ii->operands[0].reg; - int dstreg = ii->operands[1].reg; - - if (srcreg != s) { - fprintf(stderr, "ERROR: instruction expected r%d as source, got ", s); - if (srcreg == -1) - fprintf(stderr, "nothing\n"); - else - fprintf(stderr, "r%d\n", srcreg); - return false; - } - - if (dstreg != d) { - fprintf(stderr, "ERROR: instruction expected r%d as destination, got ", d); - if (dstreg == -1) - fprintf(stderr, "nothing\n"); - else - fprintf(stderr, "r%d\n", dstreg); - return false; - } - - return true; -} - -static bool check_imm_reg(insn_t *ii, const char *name, uint32 v, int d, int mode = -1) -{ - if (strcasecmp(ii->name, name) != 0) { - fprintf(stderr, "ERROR: instruction mismatch, expected %s, got %s\n", name, ii->name); - return false; - } - - if (ii->n_operands != 2) { - fprintf(stderr, "ERROR: instruction expected 2 operands, got %d\n", ii->n_operands); - return false; - } - - uint32 imm = ii->operands[0].imm; - int dstreg = ii->operands[1].reg; - - if (mode == -1) { - char suffix = name[strlen(name) - 1]; - switch (suffix) { - case 'b': mode = 1; break; - case 'w': mode = 2; break; - case 'l': mode = 4; break; - case 'q': mode = 8; break; - } - } - switch (mode) { - case 1: v &= 0xff; break; - case 2: v &= 0xffff; break; - } - - if (imm != v) { - fprintf(stderr, "ERROR: instruction expected 0x%08x as immediate, got ", v); - if (imm == -1) - fprintf(stderr, "nothing\n"); - else - fprintf(stderr, "0x%08x\n", imm); - return false; - } - - if (dstreg != d) { - fprintf(stderr, "ERROR: instruction expected r%d as destination, got ", d); - if (dstreg == -1) - fprintf(stderr, "nothing\n"); - else - fprintf(stderr, "%d\n", dstreg); - return false; - } - - return true; -} - -static bool do_check_mem(insn_t *ii, uint32 D, int B, int I, int S, int Mpos) -{ - operand_t *mem = &ii->operands[Mpos]; - uint32 d = mem->disp; - int b = mem->base; - int i = mem->index; - int s = mem->scale; - - if (d != D) { - fprintf(stderr, "ERROR: instruction expected 0x%08x as displacement, got 0x%08x\n", D, d); - return false; - } - - if (b != B) { - fprintf(stderr, "ERROR: instruction expected r%d as base, got r%d\n", B, b); - return false; - } - - if (i != I) { - fprintf(stderr, "ERROR: instruction expected r%d as index, got r%d\n", I, i); - return false; - } - - if (s != S) { - fprintf(stderr, "ERROR: instruction expected %d as scale factor, got %d\n", S, s); - return false; - } - - return true; -} - -static bool check_mem(insn_t *ii, const char *name, uint32 D, int B, int I, int S) -{ - if (strcasecmp(ii->name, name) != 0) { - fprintf(stderr, "ERROR: instruction mismatch, expected %s, got %s\n", name, ii->name); - return false; - } - - if (ii->n_operands != 1) { - fprintf(stderr, "ERROR: instruction expected 1 operand, got %d\n", ii->n_operands); - return false; - } - - return do_check_mem(ii, D, B, I, S, 0); -} - -static bool check_mem_reg(insn_t *ii, const char *name, uint32 D, int B, int I, int S, int R, int Rpos = 1) -{ - if (strcasecmp(ii->name, name) != 0) { - fprintf(stderr, "ERROR: instruction mismatch, expected %s, got %s\n", name, ii->name); - return false; - } - - if (ii->n_operands != 2) { - fprintf(stderr, "ERROR: instruction expected 2 operands, got %d\n", ii->n_operands); - return false; - } - - if (!do_check_mem(ii, D, B, I, S, Rpos ^ 1)) - return false; - - int r = ii->operands[Rpos].reg; - - if (r != R) { - fprintf(stderr, "ERROR: instruction expected r%d as reg operand, got r%d\n", R, r); - return false; - } - - return true; -} - -static inline bool check_reg_mem(insn_t *ii, const char *name, uint32 D, int B, int I, int S, int R) -{ - return check_mem_reg(ii, name, D, B, I, S, R, 0); -} - -static void show_instruction(const char *buffer, const uint8 *bytes) -{ - if (verbose > 1) { - if (1) { - for (int j = 0; j < MAX_INSN_LENGTH; j++) - fprintf(stderr, "%02x ", bytes[j]); - fprintf(stderr, "| "); - } - fprintf(stderr, "%s\n", buffer); - } -} - -static void show_status(unsigned long n_tests) -{ -#if 1 - const unsigned long N_STEPS = 100000; - static const char cursors[] = { '-', '\\', '|', '/' }; - if ((n_tests % N_STEPS) == 0) { - printf(" %c (%d)\r", cursors[(n_tests/N_STEPS)%sizeof(cursors)], n_tests); - fflush(stdout); - } -#else - const unsigned long N_STEPS = 1000000; - if ((n_tests % N_STEPS) == 0) - printf(" ... %d\n", n_tests); -#endif -} - -int main(void) -{ - static char buffer[1024]; - static uint8 block[MAX_INSNS * MAX_INSN_LENGTH]; - static char *insns[MAX_INSNS]; - static int modes[MAX_INSNS]; - n_all_tests = n_all_failures = 0; - -#if TEST_INST_ALU_REG - printf("Testing reg forms\n"); - n_tests = n_failures = 0; - for (int r = 0; r < X86_MAX_ALU_REGS; r++) { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GEN(INSN, GENOP) do { \ - insns[i++] = INSN; \ - GENOP##r(r); \ -} while (0) -#define GEN64(INSN, GENOP) do { \ - if (X86_TARGET_64BIT) \ - GEN(INSN, GENOP); \ -} while (0) -#define GENA(INSN, GENOP) do { \ - if (VALID_REG8(r)) \ - GEN(INSN "b", GENOP##B); \ - GEN(INSN "w", GENOP##W); \ - GEN(INSN "l", GENOP##L); \ - GEN64(INSN "q", GENOP##Q); \ -} while (0) - GENA("not", NOT); - GENA("neg", NEG); - GENA("mul", MUL); - GENA("imul", IMUL); - GENA("div", DIV); - GENA("idiv", IDIV); - GENA("dec", DEC); - GENA("inc", INC); - if (X86_TARGET_64BIT) { - GEN("callq", CALLs); - GEN("jmpq", JMPs); - GEN("pushq", PUSHQ); - GEN("popq", POPQ); - } - else { - GEN("calll", CALLs); - GEN("jmpl", JMPs); - GEN("pushl", PUSHL); - GEN("popl", POPL); - } - GEN("bswap", BSWAPL); // FIXME: disass bug? no suffix - GEN64("bswap", BSWAPQ); // FIXME: disass bug? no suffix - if (VALID_REG8(r)) { - GEN("seto", SETO); - GEN("setno", SETNO); - GEN("setb", SETB); - GEN("setae", SETAE); - GEN("sete", SETE); - GEN("setne", SETNE); - GEN("setbe", SETBE); - GEN("seta", SETA); - GEN("sets", SETS); - GEN("setns", SETNS); - GEN("setp", SETP); - GEN("setnp", SETNP); - GEN("setl", SETL); - GEN("setge", SETGE); - GEN("setle", SETLE); - GEN("setg", SETG); - } -#undef GENA -#undef GEN64 -#undef GEN - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_reg(&ii, insns[i], r)) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - } - if (i != last_insn) - abort(); - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - -#if TEST_INST_ALU_REG_REG - printf("Testing reg,reg forms\n"); - n_tests = n_failures = 0; - for (int s = 0; s < X86_MAX_ALU_REGS; s++) { - for (int d = 0; d < X86_MAX_ALU_REGS; d++) { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GEN(INSN, GENOP) do { \ - insns[i++] = INSN; \ - GENOP##rr(s, d); \ -} while (0) -#define GEN64(INSN, GENOP) do { \ - if (X86_TARGET_64BIT) \ - GEN(INSN, GENOP); \ -} while (0) -#define GEN1(INSN, GENOP, OP) do { \ - insns[i++] = INSN; \ - GENOP##rr(OP, s, d); \ -} while (0) -#define GENA(INSN, GENOP) do { \ - if (VALID_REG8(s) && VALID_REG8(d)) \ - GEN(INSN "b", GENOP##B); \ - GEN(INSN "w", GENOP##W); \ - GEN(INSN "l", GENOP##L); \ - GEN64(INSN "q", GENOP##Q); \ -} while (0) - GENA("adc", ADC); - GENA("add", ADD); - GENA("and", AND); - GENA("cmp", CMP); - GENA("or", OR); - GENA("sbb", SBB); - GENA("sub", SUB); - GENA("xor", XOR); - GENA("mov", MOV); - GEN("btw", BTW); - GEN("btl", BTL); - GEN64("btq", BTQ); - GEN("btcw", BTCW); - GEN("btcl", BTCL); - GEN64("btcq", BTCQ); - GEN("btrw", BTRW); - GEN("btrl", BTRL); - GEN64("btrq", BTRQ); - GEN("btsw", BTSW); - GEN("btsl", BTSL); - GEN64("btsq", BTSQ); - GEN("imulw", IMULW); - GEN("imull", IMULL); - GEN64("imulq", IMULQ); - GEN1("cmove", CMOVW, X86_CC_Z); - GEN1("cmove", CMOVL, X86_CC_Z); - if (X86_TARGET_64BIT) - GEN1("cmove", CMOVQ, X86_CC_Z); - GENA("test", TEST); - GENA("cmpxchg", CMPXCHG); - GENA("xadd", XADD); - GENA("xchg", XCHG); - GEN("bsfw", BSFW); - GEN("bsfl", BSFL); - GEN64("bsfq", BSFQ); - GEN("bsrw", BSRW); - GEN("bsrl", BSRL); - GEN64("bsrq", BSRQ); - if (VALID_REG8(s)) { - GEN("movsbw", MOVSBW); - GEN("movsbl", MOVSBL); - GEN64("movsbq", MOVSBQ); - GEN("movzbw", MOVZBW); - GEN("movzbl", MOVZBL); - GEN64("movzbq", MOVZBQ); - } - GEN("movswl", MOVSWL); - GEN64("movswq", MOVSWQ); - GEN("movzwl", MOVZWL); - GEN64("movzwq", MOVZWQ); - GEN64("movslq", MOVSLQ); -#undef GENA -#undef GEN1 -#undef GEN64 -#undef GEN - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_reg_reg(&ii, insns[i], s, d)) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - } - if (i != last_insn) - abort(); - } - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - -#if TEST_INST_ALU_CNT_REG - printf("Testing cl,reg forms\n"); - n_tests = n_failures = 0; - for (int d = 0; d < X86_MAX_ALU_REGS; d++) { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GEN(INSN, GENOP) do { \ - insns[i++] = INSN; \ - GENOP##rr(X86_CL, d); \ -} while (0) -#define GEN64(INSN, GENOP) do { \ - if (X86_TARGET_64BIT) \ - GEN(INSN, GENOP); \ -} while (0) -#define GENA(INSN, GENOP) do { \ - if (VALID_REG8(d)) \ - GEN(INSN "b", GENOP##B); \ - GEN(INSN "w", GENOP##W); \ - GEN(INSN "l", GENOP##L); \ - GEN64(INSN "q", GENOP##Q); \ -} while (0) - GENA("rol", ROL); - GENA("ror", ROR); - GENA("rcl", RCL); - GENA("rcr", RCR); - GENA("shl", SHL); - GENA("shr", SHR); - GENA("sar", SAR); -#undef GENA -#undef GEN64 -#undef GEN - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_reg_reg(&ii, insns[i], X86_CL, d)) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - } - if (i != last_insn) - abort(); - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - - static const uint32 imm_table[] = { - 0x00000000, 0x00000001, 0x00000002, 0x00000004, - 0x00000008, 0x00000010, 0x00000020, 0x00000040, - 0x00000080, 0x000000fe, 0x000000ff, 0x00000100, - 0x00000101, 0x00000102, 0xfffffffe, 0xffffffff, - 0x00000000, 0x10000000, 0x20000000, 0x30000000, - 0x40000000, 0x50000000, 0x60000000, 0x70000000, - 0x80000000, 0x90000000, 0xa0000000, 0xb0000000, - 0xc0000000, 0xd0000000, 0xe0000000, 0xf0000000, - 0xfffffffd, 0xfffffffe, 0xffffffff, 0x00000001, - 0x00000002, 0x00000003, 0x11111111, 0x22222222, - 0x33333333, 0x44444444, 0x55555555, 0x66666666, - 0x77777777, 0x88888888, 0x99999999, 0xaaaaaaaa, - 0xbbbbbbbb, 0xcccccccc, 0xdddddddd, 0xeeeeeeee, - }; - const int n_imm_tab_count = sizeof(imm_table)/sizeof(imm_table[0]); - -#if TEST_INST_ALU_IMM_REG - printf("Testing imm,reg forms\n"); - n_tests = n_failures = 0; - for (int j = 0; j < n_imm_tab_count; j++) { - const uint32 value = imm_table[j]; - for (int d = 0; d < X86_MAX_ALU_REGS; d++) { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GEN(INSN, GENOP) do { \ - insns[i] = INSN; \ - modes[i] = -1; \ - i++; GENOP##ir(value, d); \ - } while (0) -#define GEN64(INSN, GENOP) do { \ - if (X86_TARGET_64BIT) \ - GEN(INSN, GENOP); \ - } while (0) -#define GENM(INSN, GENOP, MODE) do { \ - insns[i] = INSN; \ - modes[i] = MODE; \ - i++; GENOP##ir(value, d); \ - } while (0) -#define GENM64(INSN, GENOP, MODE) do { \ - if (X86_TARGET_64BIT) \ - GENM(INSN, GENOP, MODE); \ - } while (0) -#define GENA(INSN, GENOP) do { \ - if (VALID_REG8(d)) \ - GEN(INSN "b", GENOP##B); \ - GEN(INSN "w", GENOP##W); \ - GEN(INSN "l", GENOP##L); \ - GEN64(INSN "q", GENOP##Q); \ - } while (0) -#define GENAM(INSN, GENOP, MODE) do { \ - if (VALID_REG8(d)) \ - GENM(INSN "b", GENOP##B, MODE); \ - GENM(INSN "w", GENOP##W, MODE); \ - GENM(INSN "l", GENOP##L, MODE); \ - GENM64(INSN "q", GENOP##Q, MODE); \ - } while (0) - GENA("adc", ADC); - GENA("add", ADD); - GENA("and", AND); - GENA("cmp", CMP); - GENA("or", OR); - GENA("sbb", SBB); - GENA("sub", SUB); - GENA("xor", XOR); - GENA("mov", MOV); - GENM("btw", BTW, 1); - GENM("btl", BTL, 1); - GENM64("btq", BTQ, 1); - GENM("btcw", BTCW, 1); - GENM("btcl", BTCL, 1); - GENM64("btcq", BTCQ, 1); - GENM("btrw", BTRW, 1); - GENM("btrl", BTRL, 1); - GENM64("btrq", BTRQ, 1); - GENM("btsw", BTSW, 1); - GENM("btsl", BTSL, 1); - GENM64("btsq", BTSQ, 1); - if (value != 1) { - GENAM("rol", ROL, 1); - GENAM("ror", ROR, 1); - GENAM("rcl", RCL, 1); - GENAM("rcr", RCR, 1); - GENAM("shl", SHL, 1); - GENAM("shr", SHR, 1); - GENAM("sar", SAR, 1); - } - GENA("test", TEST); -#undef GENAM -#undef GENA -#undef GENM64 -#undef GENM -#undef GEN64 -#undef GEN - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_imm_reg(&ii, insns[i], value, d, modes[i])) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - } - if (i != last_insn) - abort(); - } - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - - static const uint32 off_table[] = { - 0x00000000, - 0x00000001, - 0x00000040, - 0x00000080, - 0x000000ff, - 0x00000100, - 0xfffffffe, - 0xffffffff, - }; - const int off_table_count = sizeof(off_table) / sizeof(off_table[0]); - -#if TEST_INST_ALU_MEM_REG - printf("Testing mem,reg forms\n"); - n_tests = n_failures = 0; - for (int d = 0; d < off_table_count; d++) { - const uint32 D = off_table[d]; - for (int B = -1; B < X86_MAX_ALU_REGS; B++) { - for (int I = -1; I < X86_MAX_ALU_REGS; I++) { - if (I == X86_RSP) - continue; - for (int S = 1; S < 16; S *= 2) { - if (I == -1 && S > 1) - continue; - for (int r = 0; r < X86_MAX_ALU_REGS; r++) { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GEN(INSN, GENOP) do { \ - insns[i++] = INSN; \ - GENOP##mr(D, B, I, S, r); \ - } while (0) -#define GEN64(INSN, GENOP) do { \ - if (X86_TARGET_64BIT) \ - GEN(INSN, GENOP); \ - } while (0) -#define GENA(INSN, GENOP) do { \ - if (VALID_REG8(r)) \ - GEN(INSN "b", GENOP##B); \ - GEN(INSN "w", GENOP##W); \ - GEN(INSN "l", GENOP##L); \ - GEN64(INSN "q", GENOP##Q); \ - } while (0) - GENA("adc", ADC); - GENA("add", ADD); - GENA("and", AND); - GENA("cmp", CMP); - GENA("or", OR); - GENA("sbb", SBB); - GENA("sub", SUB); - GENA("xor", XOR); - GENA("mov", MOV); - GEN("imulw", IMULW); - GEN("imull", IMULL); - GEN64("imulq", IMULQ); - GEN("bsfw", BSFW); - GEN("bsfl", BSFL); - GEN64("bsfq", BSFQ); - GEN("bsrw", BSRW); - GEN("bsrl", BSRL); - GEN64("bsrq", BSRQ); - GEN("movsbw", MOVSBW); - GEN("movsbl", MOVSBL); - GEN64("movsbq", MOVSBQ); - GEN("movzbw", MOVZBW); - GEN("movzbl", MOVZBL); - GEN64("movzbq", MOVZBQ); - GEN("movswl", MOVSWL); - GEN64("movswq", MOVSWQ); - GEN("movzwl", MOVZWL); - GEN64("movzwq", MOVZWQ); - GEN64("movslq", MOVSLQ); -#undef GENA -#undef GEN64 -#undef GEN - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_mem_reg(&ii, insns[i], D, B, I, S, r)) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - show_status(n_tests); - } - if (i != last_insn) - abort(); - } - } - } - } - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - -#if TEST_INST_FPU_UNARY - printf("Testing FPU unary forms\n"); - n_tests = n_failures = 0; - { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GEN(INSN, GENOP) do { \ - insns[i++] = INSN; \ - GENOP(); \ -} while (0) - GEN("f2xm1", F2XM1); - GEN("fabs", FABS); - GEN("fchs", FCHS); - GEN("fcompp", FCOMPP); - GEN("fcos", FCOS); - GEN("fdecstp", FDECSTP); - GEN("fincstp", FINCSTP); - GEN("fld1", FLD1); - GEN("fldl2t", FLDL2T); - GEN("fldl2e", FLDL2E); - GEN("fldpi", FLDPI); - GEN("fldlg2", FLDLG2); - GEN("fldln2", FLDLN2); - GEN("fldz", FLDZ); - GEN("fnop", FNOP); - GEN("fpatan", FPATAN); - GEN("fprem", FPREM); - GEN("fprem1", FPREM1); - GEN("fptan", FPTAN); - GEN("frndint", FRNDINT); - GEN("fscale", FSCALE); - GEN("fsin", FSIN); - GEN("fsincos", FSINCOS); - GEN("fsqrt", FSQRT); - GEN("ftst", FTST); - GEN("fucompp", FUCOMPP); - GEN("fxam", FXAM); - GEN("fxtract", FXTRACT); - GEN("fyl2x", FYL2X); - GEN("fyl2xp1", FYL2XP1); -#undef GEN - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_unary(&ii, insns[i])) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - } - if (i != last_insn) - abort(); - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - -#if TEST_INST_FPU_REG - printf("Testing FPU reg forms\n"); - n_tests = n_failures = 0; - for (int r = 0; r < X86_MAX_FPU_REGS; r++) { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GENr(INSN, GENOP) do { \ - insns[i] = INSN; \ - modes[i] = 0; \ - i++, GENOP##r(r); \ -} while (0) -#define GENr0(INSN, GENOP) do { \ - insns[i] = INSN; \ - modes[i] = 1; \ - i++, GENOP##r0(r); \ -} while (0) -#define GEN0r(INSN, GENOP) do { \ - insns[i] = INSN; \ - modes[i] = 2; \ - i++, GENOP##0r(r); \ -} while (0) - GENr("fcom", FCOM); - GENr("fcomp", FCOMP); - GENr("ffree", FFREE); - GENr("fxch", FXCH); - GENr("fst", FST); - GENr("fstp", FSTP); - GENr("fucom", FUCOM); - GENr("fucomp", FUCOMP); - GENr0("fadd", FADD); - GENr0("fcmovb", FCMOVB); - GENr0("fcmove", FCMOVE); - GENr0("fcmovbe", FCMOVBE); - GENr0("fcmovu", FCMOVU); - GENr0("fcmovnb", FCMOVNB); - GENr0("fcmovne", FCMOVNE); - GENr0("fcmovnbe", FCMOVNBE); - GENr0("fcmovnu", FCMOVNU); - GENr0("fcomi", FCOMI); - GENr0("fcomip", FCOMIP); - GENr0("fucomi", FUCOMI); - GENr0("fucomip", FUCOMIP); - GENr0("fdiv", FDIV); - GENr0("fdivr", FDIVR); - GENr0("fmul", FMUL); - GENr0("fsub", FSUB); - GENr0("fsubr", FSUBR); -#undef GEN0r -#undef GENr0 -#undef GENr - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - switch (modes[i]) { - case 0: - if (!check_reg(&ii, insns[i], r)) { - show_instruction(buffer, p); - n_failures++; - } - break; - case 1: - if (!check_reg_reg(&ii, insns[i], r, 0)) { - show_instruction(buffer, p); - n_failures++; - } - break; - case 2: - if (!check_reg_reg(&ii, insns[i], 0, r)) { - show_instruction(buffer, p); - n_failures++; - } - break; - } - - p += n; - i += 1; - n_tests++; - } - if (i != last_insn) - abort(); - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - -#if TEST_INST_FPU_MEM - printf("Testing FPU mem forms\n"); - n_tests = n_failures = 0; - for (int d = 0; d < off_table_count; d++) { - const uint32 D = off_table[d]; - for (int B = -1; B < X86_MAX_ALU_REGS; B++) { - for (int I = -1; I < X86_MAX_ALU_REGS; I++) { - if (I == X86_RSP) - continue; - for (int S = 1; S < 16; S *= 2) { - if (I == -1 && S > 1) - continue; - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GEN(INSN, GENOP) do { \ - insns[i++] = INSN; \ - GENOP##m(D, B, I, S); \ -} while (0) - GEN("fadds", FADDS); - GEN("faddl", FADDD); - GEN("fiadd", FIADDW); - GEN("fiaddl", FIADDL); - GEN("fbld", FBLD); - GEN("fbstp", FBSTP); - GEN("fcoms", FCOMS); - GEN("fcoml", FCOMD); - GEN("fcomps", FCOMPS); - GEN("fcompl", FCOMPD); - GEN("fdivs", FDIVS); - GEN("fdivl", FDIVD); - GEN("fidiv", FIDIVW); - GEN("fidivl", FIDIVL); - GEN("fdivrs", FDIVRS); - GEN("fdivrl", FDIVRD); - GEN("fidivr", FIDIVRW); - GEN("fidivrl", FIDIVRL); - GEN("ficom", FICOMW); - GEN("ficoml", FICOML); - GEN("ficomp", FICOMPW); - GEN("ficompl", FICOMPL); - GEN("fild", FILDW); - GEN("fildl", FILDL); - GEN("fildll", FILDQ); - GEN("fist", FISTW); - GEN("fistl", FISTL); - GEN("fistp", FISTPW); - GEN("fistpl", FISTPL); - GEN("fistpll", FISTPQ); - GEN("fisttp", FISTTPW); - GEN("fisttpl", FISTTPL); - GEN("fisttpll", FISTTPQ); - GEN("flds", FLDS); - GEN("fldl", FLDD); - GEN("fldt", FLDT); - GEN("fmuls", FMULS); - GEN("fmull", FMULD); - GEN("fimul", FIMULW); - GEN("fimull", FIMULL); - GEN("fsts", FSTS); - GEN("fstl", FSTD); - GEN("fstps", FSTPS); - GEN("fstpl", FSTPD); - GEN("fstpt", FSTPT); - GEN("fsubs", FSUBS); - GEN("fsubl", FSUBD); - GEN("fisub", FISUBW); - GEN("fisubl", FISUBL); - GEN("fsubrs", FSUBRS); - GEN("fsubrl", FSUBRD); - GEN("fisubr", FISUBRW); - GEN("fisubrl", FISUBRL); -#undef GEN - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_mem(&ii, insns[i], D, B, I, S)) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - show_status(n_tests); - } - if (i != last_insn) - abort(); - } - } - } - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - -#if TEST_INST_MMX_REG_REG - printf("Testing MMX reg,reg forms\n"); - n_tests = n_failures = 0; - for (int s = 0; s < X86_MAX_MMX_REGS; s++) { - for (int d = 0; d < X86_MAX_MMX_REGS; d++) { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GEN(INSN, GENOP) do { \ - insns[i++] = INSN; \ - MMX_##GENOP##rr(s, d); \ -} while (0) -#define GEN64(INSN, GENOP) do { \ - if (X86_TARGET_64BIT) \ - GEN(INSN, GENOP); \ -} while (0) - GEN("movq", MOVQ); - GEN("packsswb", PACKSSWB); - GEN("packssdw", PACKSSDW); - GEN("packuswb", PACKUSWB); - GEN("paddb", PADDB); - GEN("paddw", PADDW); - GEN("paddd", PADDD); - GEN("paddq", PADDQ); - GEN("paddsb", PADDSB); - GEN("paddsw", PADDSW); - GEN("paddusb", PADDUSB); - GEN("paddusw", PADDUSW); - GEN("pand", PAND); - GEN("pandn", PANDN); - GEN("pavgb", PAVGB); - GEN("pavgw", PAVGW); - GEN("pcmpeqb", PCMPEQB); - GEN("pcmpeqw", PCMPEQW); - GEN("pcmpeqd", PCMPEQD); - GEN("pcmpgtb", PCMPGTB); - GEN("pcmpgtw", PCMPGTW); - GEN("pcmpgtd", PCMPGTD); - GEN("pmaddwd", PMADDWD); - GEN("pmaxsw", PMAXSW); - GEN("pmaxub", PMAXUB); - GEN("pminsw", PMINSW); - GEN("pminub", PMINUB); - GEN("pmulhuw", PMULHUW); - GEN("pmulhw", PMULHW); - GEN("pmullw", PMULLW); - GEN("pmuludq", PMULUDQ); - GEN("por", POR); - GEN("psadbw", PSADBW); - GEN("psllw", PSLLW); - GEN("pslld", PSLLD); - GEN("psllq", PSLLQ); - GEN("psraw", PSRAW); - GEN("psrad", PSRAD); - GEN("psrlw", PSRLW); - GEN("psrld", PSRLD); - GEN("psrlq", PSRLQ); - GEN("psubb", PSUBB); - GEN("psubw", PSUBW); - GEN("psubd", PSUBD); - GEN("psubq", PSUBQ); - GEN("psubsb", PSUBSB); - GEN("psubsw", PSUBSW); - GEN("psubusb", PSUBUSB); - GEN("psubusw", PSUBUSW); - GEN("punpckhbw", PUNPCKHBW); - GEN("punpckhwd", PUNPCKHWD); - GEN("punpckhdq", PUNPCKHDQ); - GEN("punpcklbw", PUNPCKLBW); - GEN("punpcklwd", PUNPCKLWD); - GEN("punpckldq", PUNPCKLDQ); - GEN("pxor", PXOR); - GEN("pabsb", PABSB); - GEN("pabsw", PABSW); - GEN("pabsd", PABSD); - GEN("phaddw", PHADDW); - GEN("phaddd", PHADDD); - GEN("phaddsw", PHADDSW); - GEN("phsubw", PHSUBW); - GEN("phsubd", PHSUBD); - GEN("phsubsw", PHSUBSW); - GEN("pmaddubsw", PMADDUBSW); - GEN("pmulhrsw", PMULHRSW); - GEN("pshufb", PSHUFB); - GEN("psignb", PSIGNB); - GEN("psignw", PSIGNW); - GEN("psignd", PSIGND); -#undef GEN64 -#undef GEN - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_reg_reg(&ii, insns[i], s, d)) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - } - if (i != last_insn) - abort(); - } - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - - static const uint8 imm8_table[] = { - 0x00, 0x01, 0x02, 0x03, - 0x06, 0x07, 0x08, 0x09, - 0x0e, 0x0f, 0x10, 0x11, - 0x1e, 0x1f, 0x20, 0x21, - 0xfc, 0xfd, 0xfe, 0xff, - }; - const int n_imm8_tab_count = sizeof(imm8_table)/sizeof(imm8_table[0]); - -#if TEST_INST_MMX_IMM_REG - printf("Testing imm,reg forms\n"); - n_tests = n_failures = 0; - for (int j = 0; j < n_imm8_tab_count; j++) { - const uint8 value = imm8_table[j]; - for (int d = 0; d < X86_MAX_MMX_REGS; d++) { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GEN(INSN, GENOP) do { \ - insns[i] = INSN; \ - modes[i] = 1; \ - i++; MMX_##GENOP##ir(value, d); \ -} while (0) - GEN("psllw", PSLLW); - GEN("pslld", PSLLD); - GEN("psllq", PSLLQ); - GEN("psraw", PSRAW); - GEN("psrad", PSRAD); - GEN("psrlw", PSRLW); - GEN("psrld", PSRLD); - GEN("psrlq", PSRLQ); -#undef GEN - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_imm_reg(&ii, insns[i], value, d, modes[i])) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - } - if (i != last_insn) - abort(); - } - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - -#if TEST_INST_MMX_MEM_REG - printf("Testing MMX mem,reg forms\n"); - n_tests = n_failures = 0; - for (int d = 0; d < off_table_count; d++) { - const uint32 D = off_table[d]; - for (int B = -1; B < X86_MAX_ALU_REGS; B++) { - for (int I = -1; I < X86_MAX_ALU_REGS; I++) { - if (I == X86_RSP) - continue; - for (int S = 1; S < 16; S *= 2) { - if (I == -1 && S > 1) - continue; - for (int r = 0; r < X86_MAX_MMX_REGS; r++) { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define _GENrm(INSN, GENOP) do { \ - insns[i] = INSN; \ - modes[i] = 0; \ - i++; MMX_##GENOP##rm(r, D, B, I, S); \ -} while (0) -#define _GENmr(INSN, GENOP) do { \ - insns[i] = INSN; \ - modes[i] = 1; \ - i++; MMX_##GENOP##mr(D, B, I, S, r); \ -} while (0) -#define GEN(INSN, GENOP) do { \ - _GENmr(INSN, GENOP); \ -} while (0) - _GENmr("movd", MOVD); - _GENrm("movd", MOVD); - _GENmr("movq", MOVQ); - _GENrm("movq", MOVQ); - GEN("packsswb", PACKSSWB); - GEN("packssdw", PACKSSDW); - GEN("packuswb", PACKUSWB); - GEN("paddb", PADDB); - GEN("paddw", PADDW); - GEN("paddd", PADDD); - GEN("paddq", PADDQ); - GEN("paddsb", PADDSB); - GEN("paddsw", PADDSW); - GEN("paddusb", PADDUSB); - GEN("paddusw", PADDUSW); - GEN("pand", PAND); - GEN("pandn", PANDN); - GEN("pavgb", PAVGB); - GEN("pavgw", PAVGW); - GEN("pcmpeqb", PCMPEQB); - GEN("pcmpeqw", PCMPEQW); - GEN("pcmpeqd", PCMPEQD); - GEN("pcmpgtb", PCMPGTB); - GEN("pcmpgtw", PCMPGTW); - GEN("pcmpgtd", PCMPGTD); - GEN("pmaddwd", PMADDWD); - GEN("pmaxsw", PMAXSW); - GEN("pmaxub", PMAXUB); - GEN("pminsw", PMINSW); - GEN("pminub", PMINUB); - GEN("pmulhuw", PMULHUW); - GEN("pmulhw", PMULHW); - GEN("pmullw", PMULLW); - GEN("pmuludq", PMULUDQ); - GEN("por", POR); - GEN("psadbw", PSADBW); - GEN("psllw", PSLLW); - GEN("pslld", PSLLD); - GEN("psllq", PSLLQ); - GEN("psraw", PSRAW); - GEN("psrad", PSRAD); - GEN("psrlw", PSRLW); - GEN("psrld", PSRLD); - GEN("psrlq", PSRLQ); - GEN("psubb", PSUBB); - GEN("psubw", PSUBW); - GEN("psubd", PSUBD); - GEN("psubq", PSUBQ); - GEN("psubsb", PSUBSB); - GEN("psubsw", PSUBSW); - GEN("psubusb", PSUBUSB); - GEN("psubusw", PSUBUSW); - GEN("punpckhbw", PUNPCKHBW); - GEN("punpckhwd", PUNPCKHWD); - GEN("punpckhdq", PUNPCKHDQ); - GEN("punpcklbw", PUNPCKLBW); - GEN("punpcklwd", PUNPCKLWD); - GEN("punpckldq", PUNPCKLDQ); - GEN("pxor", PXOR); - GEN("pabsb", PABSB); - GEN("pabsw", PABSW); - GEN("pabsd", PABSD); - GEN("phaddw", PHADDW); - GEN("phaddd", PHADDD); - GEN("phaddsw", PHADDSW); - GEN("phsubw", PHSUBW); - GEN("phsubd", PHSUBD); - GEN("phsubsw", PHSUBSW); - GEN("pmaddubsw", PMADDUBSW); - GEN("pmulhrsw", PMULHRSW); - GEN("pshufb", PSHUFB); - GEN("psignb", PSIGNB); - GEN("psignw", PSIGNW); - GEN("psignd", PSIGND); -#undef GEN -#undef _GENmr -#undef _GENrm - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_mem_reg(&ii, insns[i], D, B, I, S, r, modes[i])) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - show_status(n_tests); - } - if (i != last_insn) - abort(); - } - } - } - } - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - -#if TEST_INST_SSE_REG_REG - printf("Testing SSE reg,reg forms\n"); - n_tests = n_failures = 0; - for (int s = 0; s < X86_MAX_SSE_REGS; s++) { - for (int d = 0; d < X86_MAX_SSE_REGS; d++) { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GEN(INSN, GENOP) do { \ - insns[i++] = INSN; \ - GENOP##rr(s, d); \ -} while (0) -#define GEN64(INSN, GENOP) do { \ - if (X86_TARGET_64BIT) \ - GEN(INSN, GENOP); \ -} while (0) -#define GEN1(INSN, GENOP) do { \ - GEN(INSN "s", GENOP##S); \ - GEN(INSN "d", GENOP##D); \ -} while (0) -#define GENA(INSN, GENOP) do { \ - GEN1(INSN "s", GENOP##S); \ - GEN1(INSN "p", GENOP##P); \ -} while (0) -#define GENI(INSN, GENOP, IMM) do { \ - insns[i++] = INSN; \ - GENOP##rr(IMM, s, d); \ -} while (0) -#define GENI1(INSN, GENOP, IMM) do { \ - GENI(INSN "s", GENOP##S, IMM); \ - GENI(INSN "d", GENOP##D, IMM); \ -} while (0) -#define GENIA(INSN, GENOP, IMM) do { \ - GENI1(INSN "s", GENOP##S, IMM); \ - GENI1(INSN "p", GENOP##P, IMM); \ -} while (0) - GEN1("andp", ANDP); - GEN1("andnp", ANDNP); - GEN1("orp", ORP); - GEN1("xorp", XORP); - GENA("add", ADD); - GENA("sub", SUB); - GENA("mul", MUL); - GENA("div", DIV); - GEN1("comis", COMIS); - GEN1("ucomis", UCOMIS); - GENA("min", MIN); - GENA("max", MAX); - GEN("rcpss", RCPSS); - GEN("rcpps", RCPPS); - GEN("rsqrtss", RSQRTSS); - GEN("rsqrtps", RSQRTPS); - GENA("sqrt", SQRT); - GENIA("cmpeq", CMP, X86_SSE_CC_EQ); - GENIA("cmplt", CMP, X86_SSE_CC_LT); - GENIA("cmple", CMP, X86_SSE_CC_LE); - GENIA("cmpunord", CMP, X86_SSE_CC_U); - GENIA("cmpneq", CMP, X86_SSE_CC_NEQ); - GENIA("cmpnlt", CMP, X86_SSE_CC_NLT); - GENIA("cmpnle", CMP, X86_SSE_CC_NLE); - GENIA("cmpord", CMP, X86_SSE_CC_O); - GEN1("movap", MOVAP); - GEN("movdqa", MOVDQA); - GEN("movdqu", MOVDQU); - GEN("movd", MOVDXD); - GEN64("movd", MOVQXD); // FIXME: disass bug? "movq" expected - GEN("movd", MOVDXS); - GEN64("movd", MOVQXS); // FIXME: disass bug? "movq" expected - GEN("cvtdq2pd", CVTDQ2PD); - GEN("cvtdq2ps", CVTDQ2PS); - GEN("cvtpd2dq", CVTPD2DQ); - GEN("cvtpd2ps", CVTPD2PS); - GEN("cvtps2dq", CVTPS2DQ); - GEN("cvtps2pd", CVTPS2PD); - GEN("cvtsd2si", CVTSD2SIL); - GEN64("cvtsd2siq", CVTSD2SIQ); - GEN("cvtsd2ss", CVTSD2SS); - GEN("cvtsi2sd", CVTSI2SDL); - GEN64("cvtsi2sdq", CVTSI2SDQ); - GEN("cvtsi2ss", CVTSI2SSL); - GEN64("cvtsi2ssq", CVTSI2SSQ); - GEN("cvtss2sd", CVTSS2SD); - GEN("cvtss2si", CVTSS2SIL); - GEN64("cvtss2siq", CVTSS2SIQ); - GEN("cvttpd2dq", CVTTPD2DQ); - GEN("cvttps2dq", CVTTPS2DQ); - GEN("cvttsd2si", CVTTSD2SIL); - GEN64("cvttsd2siq", CVTTSD2SIQ); - GEN("cvttss2si", CVTTSS2SIL); - GEN64("cvttss2siq", CVTTSS2SIQ); - if (s < 8) { - // MMX source register - GEN("cvtpi2pd", CVTPI2PD); - GEN("cvtpi2ps", CVTPI2PS); - } - if (d < 8) { - // MMX dest register - GEN("cvtpd2pi", CVTPD2PI); - GEN("cvtps2pi", CVTPS2PI); - GEN("cvttpd2pi", CVTTPD2PI); - GEN("cvttps2pi", CVTTPS2PI); - } -#undef GENIA -#undef GENI1 -#undef GENI -#undef GENA -#undef GEN1 -#undef GEN64 -#undef GEN - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_reg_reg(&ii, insns[i], s, d)) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - } - if (i != last_insn) - abort(); - } - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - -#if TEST_INST_SSE_MEM_REG - printf("Testing SSE mem,reg forms\n"); - n_tests = n_failures = 0; - for (int d = 0; d < off_table_count; d++) { - const uint32 D = off_table[d]; - for (int B = -1; B < X86_MAX_ALU_REGS; B++) { - for (int I = -1; I < X86_MAX_ALU_REGS; I++) { - if (I == X86_RSP) - continue; - for (int S = 1; S < 16; S *= 2) { - if (I == -1 && S > 1) - continue; - for (int r = 0; r < X86_MAX_SSE_REGS; r++) { - set_target(block); - uint8 *b = get_target(); - int i = 0; -#define GEN(INSN, GENOP) do { \ - insns[i++] = INSN; \ - GENOP##mr(D, B, I, S, r); \ -} while (0) -#define GEN64(INSN, GENOP) do { \ - if (X86_TARGET_64BIT) \ - GEN(INSN, GENOP); \ -} while (0) -#define GEN1(INSN, GENOP) do { \ - GEN(INSN "s", GENOP##S); \ - GEN(INSN "d", GENOP##D); \ -} while (0) -#define GENA(INSN, GENOP) do { \ - GEN1(INSN "s", GENOP##S); \ - GEN1(INSN "p", GENOP##P); \ -} while (0) -#define GENI(INSN, GENOP, IMM) do { \ - insns[i++] = INSN; \ - GENOP##mr(IMM, D, B, I, S, r); \ -} while (0) -#define GENI1(INSN, GENOP, IMM) do { \ - GENI(INSN "s", GENOP##S, IMM); \ - GENI(INSN "d", GENOP##D, IMM); \ -} while (0) -#define GENIA(INSN, GENOP, IMM) do { \ - GENI1(INSN "s", GENOP##S, IMM); \ - GENI1(INSN "p", GENOP##P, IMM); \ -} while (0) - GEN1("andp", ANDP); - GEN1("andnp", ANDNP); - GEN1("orp", ORP); - GEN1("xorp", XORP); - GENA("add", ADD); - GENA("sub", SUB); - GENA("mul", MUL); - GENA("div", DIV); - GEN1("comis", COMIS); - GEN1("ucomis", UCOMIS); - GENA("min", MIN); - GENA("max", MAX); - GEN("rcpss", RCPSS); - GEN("rcpps", RCPPS); - GEN("rsqrtss", RSQRTSS); - GEN("rsqrtps", RSQRTPS); - GENA("sqrt", SQRT); - GENIA("cmpeq", CMP, X86_SSE_CC_EQ); - GENIA("cmplt", CMP, X86_SSE_CC_LT); - GENIA("cmple", CMP, X86_SSE_CC_LE); - GENIA("cmpunord", CMP, X86_SSE_CC_U); - GENIA("cmpneq", CMP, X86_SSE_CC_NEQ); - GENIA("cmpnlt", CMP, X86_SSE_CC_NLT); - GENIA("cmpnle", CMP, X86_SSE_CC_NLE); - GENIA("cmpord", CMP, X86_SSE_CC_O); - GEN1("movap", MOVAP); - GEN("movdqa", MOVDQA); - GEN("movdqu", MOVDQU); -#if 0 - // FIXME: extraneous REX bits generated - GEN("movd", MOVDXD); - GEN64("movd", MOVQXD); // FIXME: disass bug? "movq" expected -#endif - GEN("cvtdq2pd", CVTDQ2PD); - GEN("cvtdq2ps", CVTDQ2PS); - GEN("cvtpd2dq", CVTPD2DQ); - GEN("cvtpd2ps", CVTPD2PS); - GEN("cvtps2dq", CVTPS2DQ); - GEN("cvtps2pd", CVTPS2PD); - GEN("cvtsd2si", CVTSD2SIL); - GEN64("cvtsd2siq", CVTSD2SIQ); - GEN("cvtsd2ss", CVTSD2SS); - GEN("cvtsi2sd", CVTSI2SDL); - GEN64("cvtsi2sdq", CVTSI2SDQ); - GEN("cvtsi2ss", CVTSI2SSL); - GEN64("cvtsi2ssq", CVTSI2SSQ); - GEN("cvtss2sd", CVTSS2SD); - GEN("cvtss2si", CVTSS2SIL); - GEN64("cvtss2siq", CVTSS2SIQ); - GEN("cvttpd2dq", CVTTPD2DQ); - GEN("cvttps2dq", CVTTPS2DQ); - GEN("cvttsd2si", CVTTSD2SIL); - GEN64("cvttsd2siq", CVTTSD2SIQ); - GEN("cvttss2si", CVTTSS2SIL); - GEN64("cvttss2siq", CVTTSS2SIQ); - if (r < 8) { - // MMX dest register - GEN("cvtpd2pi", CVTPD2PI); - GEN("cvtps2pi", CVTPS2PI); - GEN("cvttpd2pi", CVTTPD2PI); - GEN("cvttps2pi", CVTTPS2PI); - } -#undef GENIA -#undef GENI1 -#undef GENI -#undef GENA -#undef GEN1 -#undef GEN64 -#undef GEN - int last_insn = i; - uint8 *e = get_target(); - - uint8 *p = b; - i = 0; - while (p < e) { - int n = disass_x86(buffer, (uintptr)p); - insn_t ii; - parse_insn(&ii, buffer); - - if (!check_mem_reg(&ii, insns[i], D, B, I, S, r)) { - show_instruction(buffer, p); - n_failures++; - } - - p += n; - i += 1; - n_tests++; - show_status(n_tests); - } - if (i != last_insn) - abort(); - } - } - } - } - } - printf(" done %ld/%ld\n", n_tests - n_failures, n_tests); - n_all_tests += n_tests; - n_all_failures += n_failures; -#endif - - printf("\n"); - printf("All %ld tests run, %ld failures\n", n_all_tests, n_all_failures); -} diff --git a/BasiliskII/src/uae_cpu/cpu_emulation.h b/BasiliskII/src/uae_cpu/cpu_emulation.h index cd588ec1..809959c9 100644 --- a/BasiliskII/src/uae_cpu/cpu_emulation.h +++ b/BasiliskII/src/uae_cpu/cpu_emulation.h @@ -37,14 +37,6 @@ extern uint32 ROMBaseMac; // ROM base (Mac address space) extern uint8 *ROMBaseHost; // ROM base (host address space) extern uint32 ROMSize; // Size of ROM -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING -// If we are not using real or direct addressing, the Mac frame buffer gets -// mapped to this location. The memory must be allocated by VideoInit(). -// If multiple monitors are used, they must share the frame buffer -const uint32 MacFrameBaseMac = 0xa0000000; -extern uint8 *MacFrameBaseHost; // Frame buffer base (host address space) -extern uint32 MacFrameSize; // Size of frame buffer -#endif extern int MacFrameLayout; // Frame buffer layout (see defines below) // Possible frame buffer layouts @@ -82,13 +74,6 @@ extern bool Init680x0(void); // This routine may want to look at CPUType/FPUType extern void Exit680x0(void); extern void InitFrameBufferMapping(void); -// 680x0 dynamic recompilation activation flag -#if USE_JIT -extern bool UseJIT; -#else -const bool UseJIT = false; -#endif - // 680x0 emulation functions struct M68kRegisters; extern void Start680x0(void); // Reset and start 680x0 diff --git a/BasiliskII/src/uae_cpu/fpu/flags.h b/BasiliskII/src/uae_cpu/fpu/flags.h index 7c0c5b74..5983e15e 100644 --- a/BasiliskII/src/uae_cpu/fpu/flags.h +++ b/BasiliskII/src/uae_cpu/fpu/flags.h @@ -66,12 +66,6 @@ # define FPU_USE_LAZY_FLAGS #endif -/* JIT Compilation for FPU only works with lazy evaluation of FPU flags */ -#if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY) && defined(USE_JIT_FPU) -# undef FPU_USE_GENERIC_FLAGS -# define FPU_USE_LAZY_FLAGS -#endif - #ifdef FPU_IMPLEMENTATION /* -------------------------------------------------------------------------- */ diff --git a/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp b/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp deleted file mode 100644 index f5a1aeb4..00000000 --- a/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp +++ /dev/null @@ -1,2152 +0,0 @@ -/* - * fpu/fpu_ieee.cpp - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * MC68881/68040 fpu emulation - * - * Original UAE FPU, copyright 1996 Herman ten Brugge - * Rewrite for x86, copyright 1999-2000 Lauri Pesonen - * New framework, copyright 2000 Gwenole Beauchesne - * Adapted for JIT compilation (c) Bernd Meyer, 2000 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Following fixes by Lauri Pesonen, July 1999: - * - * FMOVEM list handling: - * The lookup tables did not work correctly, rewritten. - * FINT: - * (int) cast does not work, fixed. - * Further, now honors the FPU fpcr rounding modes. - * FINTRZ: - * (int) cast cannot be used, fixed. - * FGETEXP: - * Input argument value 0 returned erroneous value. - * FMOD: - * (int) cast cannot be used. Replaced by proper rounding. - * Quotient byte handling was missing. - * FREM: - * (int) cast cannot be used. Replaced by proper rounding. - * Quotient byte handling was missing. - * FSCALE: - * Input argument value 0 was not handled correctly. - * FMOVEM Control Registers to/from address FPU registers An: - * A bug caused the code never been called. - * FMOVEM Control Registers pre-decrement: - * Moving of control regs from memory to FPP was not handled properly, - * if not all of the three FPU registers were moved. - * Condition code "Not Greater Than or Equal": - * Returned erroneous value. - * FSINCOS: - * Cosine must be loaded first if same register. - * FMOVECR: - * Status register was not updated (yes, this affects it). - * FMOVE -> reg: - * Status register was not updated (yes, this affects it). - * FMOVE reg -> reg: - * Status register was not updated. - * FDBcc: - * The loop termination condition was wrong. - * Possible leak from int16 to int32 fixed. - * get_fp_value: - * Immediate addressing mode && Operation Length == Byte -> - * Use the low-order byte of the extension word. - * Now FPU fpcr high 16 bits are always read as zeroes, no matter what was - * written to them. - * - * Other: - * - Optimized single/double/extended to/from conversion functions. - * Huge speed boost, but not (necessarily) portable to other systems. - * Enabled/disabled by #define FPU_HAVE_IEEE_DOUBLE 1 - * - Optimized versions of FSCALE, FGETEXP, FGETMAN - * - Conversion routines now handle NaN and infinity better. - * - Some constants precalculated. Not all compilers can optimize the - * expressions previously used. - * - * TODO: - * - Floating point exceptions. - * - More Infinity/NaN/overflow/underflow checking. - * - FPU instruction_address (only needed when exceptions are implemented) - * - Should be written in assembly to support long doubles. - * - Precision rounding single/double - */ - -#include "sysdeps.h" -#include -#include "memory.h" -#include "readcpu.h" -#include "newcpu.h" -#include "main.h" -#define FPU_IMPLEMENTATION -#include "fpu/fpu.h" -#include "fpu/fpu_ieee.h" - -/* Global FPU context */ -fpu_t fpu; - -/* -------------------------------------------------------------------------- */ -/* --- Scopes Definition --- */ -/* -------------------------------------------------------------------------- */ - -#undef PUBLIC -#define PUBLIC /**/ - -#undef PRIVATE -#define PRIVATE static - -#undef FFPU -#define FFPU /**/ - -#undef FPU -#define FPU fpu. - -/* -------------------------------------------------------------------------- */ -/* --- Native Support --- */ -/* -------------------------------------------------------------------------- */ - -#include "fpu/mathlib.h" -#include "fpu/flags.h" -#include "fpu/exceptions.h" -#include "fpu/rounding.h" -#include "fpu/impl.h" - -#include "fpu/mathlib.cpp" -#include "fpu/flags.cpp" -#include "fpu/exceptions.cpp" -#include "fpu/rounding.cpp" - -/* -------------------------------------------------------------------------- */ -/* --- Debugging --- */ -/* -------------------------------------------------------------------------- */ - -PUBLIC void FFPU fpu_dump_registers(void) -{ - for (int i = 0; i < 8; i++){ - printf ("FP%d: %g ", i, fpu_get_register(i)); - if ((i & 3) == 3) - printf ("\n"); - } -} - -PUBLIC void FFPU fpu_dump_flags(void) -{ - printf ("N=%d Z=%d I=%d NAN=%d\n", - (get_fpsr() & FPSR_CCB_NEGATIVE) != 0, - (get_fpsr() & FPSR_CCB_ZERO)!= 0, - (get_fpsr() & FPSR_CCB_INFINITY) != 0, - (get_fpsr() & FPSR_CCB_NAN) != 0); -} - -PRIVATE void FFPU dump_registers(const char * str) -{ -#if FPU_DEBUG && FPU_DUMP_REGISTERS - char temp_str[512]; - - sprintf(temp_str, "%s: %.04f, %.04f, %.04f, %.04f, %.04f, %.04f, %.04f, %.04f\n", - str, - fpu_get_register(0), fpu_get_register(1), fpu_get_register(2), - fpu_get_register(3), fpu_get_register(4), fpu_get_register(5), - fpu_get_register(6), fpu_get_register(7) ); - - fpu_debug((temp_str)); -#endif -} - -PRIVATE void FFPU dump_first_bytes(uae_u8 * buffer, uae_s32 actual) -{ -#if FPU_DEBUG && FPU_DUMP_FIRST_BYTES - char temp_buf1[256], temp_buf2[10]; - int bytes = sizeof(temp_buf1)/3-1-3; - if (actual < bytes) - bytes = actual; - - temp_buf1[0] = 0; - for (int i = 0; i < bytes; i++) { - sprintf(temp_buf2, "%02x ", (uae_u32)buffer[i]); - strcat(temp_buf1, temp_buf2); - } - - strcat(temp_buf1, "\n"); - fpu_debug((temp_buf1)); -#endif -} - -// Quotient Byte is loaded with the sign and least significant -// seven bits of the quotient. -PRIVATE inline void FFPU make_quotient(fpu_register const & quotient, uae_u32 sign) -{ - uae_u32 lsb = (uae_u32)fp_fabs(quotient) & 0x7f; - FPU fpsr.quotient = sign | (lsb << 16); -} - -// to_single -PRIVATE inline fpu_register FFPU make_single(uae_u32 value) -{ -#if 1 - // Use a single, otherwise some checks for NaN, Inf, Zero would have to - // be performed - fpu_single result = 0; // = 0 to workaround a compiler bug on SPARC - fp_declare_init_shape(srp, result, single); - srp->ieee.negative = (value >> 31) & 1; - srp->ieee.exponent = (value >> 23) & FP_SINGLE_EXP_MAX; - srp->ieee.mantissa = value & 0x007fffff; - fpu_debug(("make_single (%X) = %.04f\n",value,(double)result)); - return result; -#elif 0 /* Original code */ - if ((value & 0x7fffffff) == 0) - return (0.0); - - fpu_register result; - uae_u32 * p = (uae_u32 *)&result; - - uae_u32 sign = (value & 0x80000000); - uae_u32 exp = ((value & 0x7F800000) >> 23) + 1023 - 127; - - p[FLO] = value << 29; - p[FHI] = sign | (exp << 20) | ((value & 0x007FFFFF) >> 3); - - fpu_debug(("make_single (%X) = %.04f\n",value,(double)result)); - - return(result); -#endif -} - -// from_single -PRIVATE inline uae_u32 FFPU extract_single(fpu_register const & src) -{ -#if 1 - fpu_single input = (fpu_single) src; - fp_declare_init_shape(sip, input, single); - uae_u32 result = (sip->ieee.negative << 31) - | (sip->ieee.exponent << 23) - | sip->ieee.mantissa; - fpu_debug(("extract_single (%.04f) = %X\n",(double)src,result)); - return result; -#elif 0 /* Original code */ - if (src == 0.0) - return 0; - - uae_u32 result; - uae_u32 *p = (uae_u32 *)&src; - - uae_u32 sign = (p[FHI] & 0x80000000); - uae_u32 exp = (p[FHI] & 0x7FF00000) >> 20; - - if(exp + 127 < 1023) { - exp = 0; - } else if(exp > 1023 + 127) { - exp = 255; - } else { - exp = exp + 127 - 1023; - } - - result = sign | (exp << 23) | ((p[FHI] & 0x000FFFFF) << 3) | (p[FLO] >> 29); - - fpu_debug(("extract_single (%.04f) = %X\n",(double)src,result)); - - return (result); -#endif -} - -// to_exten -PRIVATE inline fpu_register FFPU make_extended(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) -{ - // is it zero? - if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) - return 0.0; - - fpu_register result; -#if USE_QUAD_DOUBLE - // is it NaN? - if ((wrd1 & 0x7fff0000) == 0x7fff0000 && wrd2 != 0 && wrd3 != 0) { - make_nan(result); - return result; - } - // is it inf? - if ((wrd1 & 0x7ffff000) == 0x7fff0000 && wrd2 == 0 && wrd3 == 0) { - if ((wrd1 & 0x80000000) == 0) - make_inf_positive(result); - else - make_inf_negative(result); - return result; - } - fp_declare_init_shape(srp, result, extended); - srp->ieee.negative = (wrd1 >> 31) & 1; - srp->ieee.exponent = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX; - srp->ieee.mantissa0 = (wrd2 >> 16) & 0xffff; - srp->ieee.mantissa1 = ((wrd2 & 0xffff) << 16) | ((wrd3 >> 16) & 0xffff); - srp->ieee.mantissa2 = (wrd3 & 0xffff) << 16; - srp->ieee.mantissa3 = 0; -#elif USE_LONG_DOUBLE - fp_declare_init_shape(srp, result, extended); - srp->ieee.negative = (wrd1 >> 31) & 1; - srp->ieee.exponent = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX; - srp->ieee.mantissa0 = wrd2; - srp->ieee.mantissa1 = wrd3; -#else - uae_u32 sgn = (wrd1 >> 31) & 1; - uae_u32 exp = (wrd1 >> 16) & 0x7fff; - - // the explicit integer bit is not set, must normalize - if ((wrd2 & 0x80000000) == 0) { - fpu_debug(("make_extended denormalized mantissa (%X,%X,%X)\n",wrd1,wrd2,wrd3)); - if (wrd2 | wrd3) { - // mantissa, not fraction. - uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3; - while (exp > 0 && (man & UVAL64(0x8000000000000000)) == 0) { - man <<= 1; - exp--; - } - wrd2 = (uae_u32)(man >> 32); - wrd3 = (uae_u32)(man & 0xFFFFFFFF); - } - else if (exp != 0x7fff) // zero - exp = FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS; - } - - if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS) - exp = 0; - else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS) - exp = FP_DOUBLE_EXP_MAX; - else - exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS; - - fp_declare_init_shape(srp, result, double); - srp->ieee.negative = sgn; - srp->ieee.exponent = exp; - // drop the explicit integer bit - srp->ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11; - srp->ieee.mantissa1 = (wrd2 << 21) | (wrd3 >> 11); -#endif - fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result)); - return result; -} - -/* - Would be so much easier with full size floats :( - ... this is so vague. -*/ -// make_extended_no_normalize -PRIVATE inline void FFPU make_extended_no_normalize( - uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & result -) -{ - // is it zero? - if ((wrd1 && 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) { - make_zero_positive(result); - return; - } - // is it NaN? - if ((wrd1 & 0x7fff0000) == 0x7fff0000 && wrd2 != 0 && wrd3 != 0) { - make_nan(result); - return; - } -#if USE_QUAD_DOUBLE - // is it inf? - if ((wrd1 & 0x7ffff000) == 0x7fff0000 && wrd2 == 0 && wrd3 == 0) { - if ((wrd1 & 0x80000000) == 0) - make_inf_positive(result); - else - make_inf_negative(result); - return; - } - fp_declare_init_shape(srp, result, extended); - srp->ieee.negative = (wrd1 >> 31) & 1; - srp->ieee.exponent = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX; - srp->ieee.mantissa0 = (wrd2 >> 16) & 0xffff; - srp->ieee.mantissa1 = ((wrd2 & 0xffff) << 16) | ((wrd3 >> 16) & 0xffff); - srp->ieee.mantissa2 = (wrd3 & 0xffff) << 16; - srp->ieee.mantissa3 = 0; -#elif USE_LONG_DOUBLE - fp_declare_init_shape(srp, result, extended); - srp->ieee.negative = (wrd1 >> 31) & 1; - srp->ieee.exponent = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX; - srp->ieee.mantissa0 = wrd2; - srp->ieee.mantissa1 = wrd3; -#else - uae_u32 exp = (wrd1 >> 16) & 0x7fff; - if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS) - exp = 0; - else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS) - exp = FP_DOUBLE_EXP_MAX; - else - exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS; - - fp_declare_init_shape(srp, result, double); - srp->ieee.negative = (wrd1 >> 31) & 1; - srp->ieee.exponent = exp; - // drop the explicit integer bit - srp->ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11; - srp->ieee.mantissa1 = (wrd2 << 21) | (wrd3 >> 11); -#endif - fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result)); -} - -// from_exten -PRIVATE inline void FFPU extract_extended(fpu_register const & src, - uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3 -) -{ - if (src == 0.0) { - *wrd1 = *wrd2 = *wrd3 = 0; - return; - } -#if USE_QUAD_DOUBLE - // FIXME: deal with denormals? - fp_declare_init_shape(srp, src, extended); - *wrd1 = (srp->ieee.negative << 31) | (srp->ieee.exponent << 16); - // always set the explicit integer bit. - *wrd2 = 0x80000000 | (srp->ieee.mantissa0 << 15) | ((srp->ieee.mantissa1 & 0xfffe0000) >> 17); - *wrd3 = (srp->ieee.mantissa1 << 15) | ((srp->ieee.mantissa2 & 0xfffe0000) >> 17); -#elif USE_LONG_DOUBLE - uae_u32 *p = (uae_u32 *)&src; -#ifdef WORDS_BIGENDIAN - *wrd1 = p[0]; - *wrd2 = p[1]; - *wrd3 = p[2]; -#else - *wrd3 = p[0]; - *wrd2 = p[1]; - *wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16; -#endif -#else - fp_declare_init_shape(srp, src, double); - fpu_debug(("extract_extended (%d,%d,%X,%X)\n", - srp->ieee.negative , srp->ieee.exponent, - srp->ieee.mantissa0, srp->ieee.mantissa1)); - - uae_u32 exp = srp->ieee.exponent; - - if (exp == FP_DOUBLE_EXP_MAX) - exp = FP_EXTENDED_EXP_MAX; - else - exp += FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS; - - *wrd1 = (srp->ieee.negative << 31) | (exp << 16); - // always set the explicit integer bit. - *wrd2 = 0x80000000 | (srp->ieee.mantissa0 << 11) | ((srp->ieee.mantissa1 & 0xffe00000) >> 21); - *wrd3 = srp->ieee.mantissa1 << 11; -#endif - fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3)); -} - -// to_double -PRIVATE inline fpu_register FFPU make_double(uae_u32 wrd1, uae_u32 wrd2) -{ - union { - fpu_double value; - uae_u32 parts[2]; - } dest; -#ifdef WORDS_BIGENDIAN - dest.parts[0] = wrd1; - dest.parts[1] = wrd2; -#else - dest.parts[0] = wrd2; - dest.parts[1] = wrd1; -#endif - fpu_debug(("make_double (%X,%X) = %.04f\n",wrd1,wrd2,dest.value)); - return (fpu_register)(dest.value); -} - -// from_double -PRIVATE inline void FFPU extract_double(fpu_register const & src, - uae_u32 * wrd1, uae_u32 * wrd2 -) -{ - union { - fpu_double value; - uae_u32 parts[2]; - } dest; - dest.value = (fpu_double)src; -#ifdef WORDS_BIGENDIAN - *wrd1 = dest.parts[0]; - *wrd2 = dest.parts[1]; -#else - *wrd2 = dest.parts[0]; - *wrd1 = dest.parts[1]; -#endif - fpu_debug(("extract_double (%.04f) = %X,%X\n",(double)src,*wrd1,*wrd2)); -} - -// to_pack -PRIVATE inline fpu_register FFPU make_packed(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) -{ - fpu_double d; - char *cp; - char str[100]; - - cp = str; - if (wrd1 & 0x80000000) - *cp++ = '-'; - *cp++ = (char)((wrd1 & 0xf) + '0'); - *cp++ = '.'; - *cp++ = (char)(((wrd2 >> 28) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 24) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 20) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 16) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 12) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 8) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 4) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 0) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 28) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 24) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 20) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 16) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 12) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 8) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 4) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 0) & 0xf) + '0'); - *cp++ = 'E'; - if (wrd1 & 0x40000000) - *cp++ = '-'; - *cp++ = (char)(((wrd1 >> 24) & 0xf) + '0'); - *cp++ = (char)(((wrd1 >> 20) & 0xf) + '0'); - *cp++ = (char)(((wrd1 >> 16) & 0xf) + '0'); - *cp = 0; - sscanf(str, "%le", &d); - - fpu_debug(("make_packed str = %s\n",str)); - - fpu_debug(("make_packed(%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)d)); - return d; -} - -// from_pack -PRIVATE inline void FFPU extract_packed(fpu_register const & src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) -{ - int i; - int t; - char *cp; - char str[100]; - - sprintf(str, "%.16e", src); - - fpu_debug(("extract_packed(%.04f,%s)\n",(double)src,str)); - - cp = str; - *wrd1 = *wrd2 = *wrd3 = 0; - if (*cp == '-') { - cp++; - *wrd1 = 0x80000000; - } - if (*cp == '+') - cp++; - *wrd1 |= (*cp++ - '0'); - if (*cp == '.') - cp++; - for (i = 0; i < 8; i++) { - *wrd2 <<= 4; - if (*cp >= '0' && *cp <= '9') - *wrd2 |= *cp++ - '0'; - } - for (i = 0; i < 8; i++) { - *wrd3 <<= 4; - if (*cp >= '0' && *cp <= '9') - *wrd3 |= *cp++ - '0'; - } - if (*cp == 'e' || *cp == 'E') { - cp++; - if (*cp == '-') { - cp++; - *wrd1 |= 0x40000000; - } - if (*cp == '+') - cp++; - t = 0; - for (i = 0; i < 3; i++) { - if (*cp >= '0' && *cp <= '9') - t = (t << 4) | (*cp++ - '0'); - } - *wrd1 |= t << 16; - } - - fpu_debug(("extract_packed(%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3)); -} - -PRIVATE inline int FFPU get_fp_value (uae_u32 opcode, uae_u16 extra, fpu_register & src) -{ - uaecptr tmppc; - uae_u16 tmp; - int size; - int mode; - int reg; - uae_u32 ad = 0; - static int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; - static int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; - - // fpu_debug(("get_fp_value(%X,%X)\n",(int)opcode,(int)extra)); - // dump_first_bytes( regs.pc_p-4, 16 ); - - if ((extra & 0x4000) == 0) { - src = FPU registers[(extra >> 10) & 7]; - return 1; - } - mode = (opcode >> 3) & 7; - reg = opcode & 7; - size = (extra >> 10) & 7; - - fpu_debug(("get_fp_value mode=%d, reg=%d, size=%d\n",(int)mode,(int)reg,(int)size)); - - switch (mode) { - case 0: - switch (size) { - case 6: - src = (fpu_register) (uae_s8) m68k_dreg (regs, reg); - break; - case 4: - src = (fpu_register) (uae_s16) m68k_dreg (regs, reg); - break; - case 0: - src = (fpu_register) (uae_s32) m68k_dreg (regs, reg); - break; - case 1: - src = make_single(m68k_dreg (regs, reg)); - break; - default: - return 0; - } - return 1; - case 1: - return 0; - case 2: - ad = m68k_areg (regs, reg); - break; - case 3: - ad = m68k_areg (regs, reg); - m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; - break; - case 4: - m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; - ad = m68k_areg (regs, reg); - break; - case 5: - ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); - break; - case 6: - ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); - break; - case 7: - switch (reg) { - case 0: - ad = (uae_s32) (uae_s16) next_iword(); - break; - case 1: - ad = next_ilong(); - break; - case 2: - ad = m68k_getpc (); - ad += (uae_s32) (uae_s16) next_iword(); - fpu_debug(("get_fp_value next_iword()=%X\n",ad-m68k_getpc()-2)); - break; - case 3: - tmppc = m68k_getpc (); - tmp = (uae_u16)next_iword(); - ad = get_disp_ea_020 (tmppc, tmp); - break; - case 4: - ad = m68k_getpc (); - m68k_setpc (ad + sz2[size]); - // Immediate addressing mode && Operation Length == Byte -> - // Use the low-order byte of the extension word. - if(size == 6) ad++; - break; - default: - return 0; - } - } - - fpu_debug(("get_fp_value m68k_getpc()=%X\n",m68k_getpc())); - fpu_debug(("get_fp_value ad=%X\n",ad)); - fpu_debug(("get_fp_value get_long (ad)=%X\n",get_long (ad))); - dump_first_bytes( get_real_address(ad)-64, 64 ); - dump_first_bytes( get_real_address(ad), 64 ); - - switch (size) { - case 0: - src = (fpu_register) (uae_s32) get_long (ad); - break; - case 1: - src = make_single(get_long (ad)); - break; - case 2: { - uae_u32 wrd1, wrd2, wrd3; - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - ad += 4; - wrd3 = get_long (ad); - src = make_extended(wrd1, wrd2, wrd3); - break; - } - case 3: { - uae_u32 wrd1, wrd2, wrd3; - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - ad += 4; - wrd3 = get_long (ad); - src = make_packed(wrd1, wrd2, wrd3); - break; - } - case 4: - src = (fpu_register) (uae_s16) get_word(ad); - break; - case 5: { - uae_u32 wrd1, wrd2; - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - src = make_double(wrd1, wrd2); - break; - } - case 6: - src = (fpu_register) (uae_s8) get_byte(ad); - break; - default: - return 0; - } - - // fpu_debug(("get_fp_value result = %.04f\n",(float)src)); - return 1; -} - -/* Convert the FP value to integer according to the current m68k rounding mode */ -PRIVATE inline uae_s32 FFPU toint(fpu_register const & src) -{ - fpu_register result; - switch (get_fpcr() & 0x30) { - case FPCR_ROUND_ZERO: - result = fp_round_to_zero(src); - break; - case FPCR_ROUND_MINF: - result = fp_round_to_minus_infinity(src); - break; - case FPCR_ROUND_NEAR: - result = fp_round_to_nearest(src); - break; - case FPCR_ROUND_PINF: - result = fp_round_to_plus_infinity(src); - break; - default: - result = src; /* should never be reached */ - break; - } - return (uae_s32)result; -} - -PRIVATE inline int FFPU put_fp_value (uae_u32 opcode, uae_u16 extra, fpu_register const & value) -{ - uae_u16 tmp; - uaecptr tmppc; - int size; - int mode; - int reg; - uae_u32 ad; - static int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; - static int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; - - // fpu_debug(("put_fp_value(%.04f,%X,%X)\n",(float)value,(int)opcode,(int)extra)); - - if ((extra & 0x4000) == 0) { - int dest_reg = (extra >> 10) & 7; - FPU registers[dest_reg] = value; - make_fpsr(FPU registers[dest_reg]); - return 1; - } - mode = (opcode >> 3) & 7; - reg = opcode & 7; - size = (extra >> 10) & 7; - ad = 0xffffffff; - switch (mode) { - case 0: - switch (size) { - case 6: - m68k_dreg (regs, reg) = ((toint(value) & 0xff) - | (m68k_dreg (regs, reg) & ~0xff)); - break; - case 4: - m68k_dreg (regs, reg) = ((toint(value) & 0xffff) - | (m68k_dreg (regs, reg) & ~0xffff)); - break; - case 0: - m68k_dreg (regs, reg) = toint(value); - break; - case 1: - m68k_dreg (regs, reg) = extract_single(value); - break; - default: - return 0; - } - return 1; - case 1: - return 0; - case 2: - ad = m68k_areg (regs, reg); - break; - case 3: - ad = m68k_areg (regs, reg); - m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; - break; - case 4: - m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; - ad = m68k_areg (regs, reg); - break; - case 5: - ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); - break; - case 6: - ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); - break; - case 7: - switch (reg) { - case 0: - ad = (uae_s32) (uae_s16) next_iword(); - break; - case 1: - ad = next_ilong(); - break; - case 2: - ad = m68k_getpc (); - ad += (uae_s32) (uae_s16) next_iword(); - break; - case 3: - tmppc = m68k_getpc (); - tmp = (uae_u16)next_iword(); - ad = get_disp_ea_020 (tmppc, tmp); - break; - case 4: - ad = m68k_getpc (); - m68k_setpc (ad + sz2[size]); - break; - default: - return 0; - } - } - switch (size) { - case 0: - put_long (ad, toint(value)); - break; - case 1: - put_long (ad, extract_single(value)); - break; - case 2: { - uae_u32 wrd1, wrd2, wrd3; - extract_extended(value, &wrd1, &wrd2, &wrd3); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - ad += 4; - put_long (ad, wrd3); - break; - } - case 3: { - uae_u32 wrd1, wrd2, wrd3; - extract_packed(value, &wrd1, &wrd2, &wrd3); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - ad += 4; - put_long (ad, wrd3); - break; - } - case 4: - put_word(ad, (uae_s16) toint(value)); - break; - case 5: { - uae_u32 wrd1, wrd2; - extract_double(value, &wrd1, &wrd2); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - break; - } - case 6: - put_byte(ad, (uae_s8) toint(value)); - break; - default: - return 0; - } - return 1; -} - -PRIVATE inline int FFPU get_fp_ad(uae_u32 opcode, uae_u32 * ad) -{ - uae_u16 tmp; - uaecptr tmppc; - int mode; - int reg; - - mode = (opcode >> 3) & 7; - reg = opcode & 7; - switch (mode) { - case 0: - case 1: - return 0; - case 2: - *ad = m68k_areg (regs, reg); - break; - case 3: - *ad = m68k_areg (regs, reg); - break; - case 4: - *ad = m68k_areg (regs, reg); - break; - case 5: - *ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); - break; - case 6: - *ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); - break; - case 7: - switch (reg) { - case 0: - *ad = (uae_s32) (uae_s16) next_iword(); - break; - case 1: - *ad = next_ilong(); - break; - case 2: - *ad = m68k_getpc (); - *ad += (uae_s32) (uae_s16) next_iword(); - break; - case 3: - tmppc = m68k_getpc (); - tmp = (uae_u16)next_iword(); - *ad = get_disp_ea_020 (tmppc, tmp); - break; - default: - return 0; - } - } - return 1; -} - -#if FPU_DEBUG -# define CONDRET(s,x) fpu_debug(("fpp_cond %s = %d\n",s,(uint32)(x))); return (x) -#else -# define CONDRET(s,x) return (x) -#endif - -PRIVATE inline int FFPU fpp_cond(int condition) -{ - int N = (FPU result < 0.0); - int Z = (FPU result == 0.0); - int NaN = isnan(FPU result); - - if (NaN) - N = Z = 0; - - switch (condition) { - case 0x00: CONDRET("False",0); - case 0x01: CONDRET("Equal",Z); - case 0x02: CONDRET("Ordered Greater Than",!(NaN || Z || N)); - case 0x03: CONDRET("Ordered Greater Than or Equal",Z || !(NaN || N)); - case 0x04: CONDRET("Ordered Less Than",N && !(NaN || Z)); - case 0x05: CONDRET("Ordered Less Than or Equal",Z || (N && !NaN)); - case 0x06: CONDRET("Ordered Greater or Less Than",!(NaN || Z)); - case 0x07: CONDRET("Ordered",!NaN); - case 0x08: CONDRET("Unordered",NaN); - case 0x09: CONDRET("Unordered or Equal",NaN || Z); - case 0x0a: CONDRET("Unordered or Greater Than",NaN || !(N || Z)); - case 0x0b: CONDRET("Unordered or Greater or Equal",NaN || Z || !N); - case 0x0c: CONDRET("Unordered or Less Than",NaN || (N && !Z)); - case 0x0d: CONDRET("Unordered or Less or Equal",NaN || Z || N); - case 0x0e: CONDRET("Not Equal",!Z); - case 0x0f: CONDRET("True",1); - case 0x10: CONDRET("Signaling False",0); - case 0x11: CONDRET("Signaling Equal",Z); - case 0x12: CONDRET("Greater Than",!(NaN || Z || N)); - case 0x13: CONDRET("Greater Than or Equal",Z || !(NaN || N)); - case 0x14: CONDRET("Less Than",N && !(NaN || Z)); - case 0x15: CONDRET("Less Than or Equal",Z || (N && !NaN)); - case 0x16: CONDRET("Greater or Less Than",!(NaN || Z)); - case 0x17: CONDRET("Greater, Less or Equal",!NaN); - case 0x18: CONDRET("Not Greater, Less or Equal",NaN); - case 0x19: CONDRET("Not Greater or Less Than",NaN || Z); - case 0x1a: CONDRET("Not Less Than or Equal",NaN || !(N || Z)); - case 0x1b: CONDRET("Not Less Than",NaN || Z || !N); - case 0x1c: CONDRET("Not Greater Than or Equal", NaN || (N && !Z)); - case 0x1d: CONDRET("Not Greater Than",NaN || Z || N); - case 0x1e: CONDRET("Signaling Not Equal",!Z); - case 0x1f: CONDRET("Signaling True",1); - default: CONDRET("",-1); - } -} - -void FFPU fpuop_dbcc(uae_u32 opcode, uae_u32 extra) -{ - fpu_debug(("fdbcc_opp %X, %X at %08lx\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); - - uaecptr pc = (uae_u32) m68k_getpc (); - uae_s32 disp = (uae_s32) (uae_s16) next_iword(); - int cc = fpp_cond(extra & 0x3f); - if (cc == -1) { - m68k_setpc (pc - 4); - op_illg (opcode); - } else if (!cc) { - int reg = opcode & 0x7; - - // this may have leaked. - /* - m68k_dreg (regs, reg) = ((m68k_dreg (regs, reg) & ~0xffff) - | ((m68k_dreg (regs, reg) - 1) & 0xffff)); - */ - m68k_dreg (regs, reg) = ((m68k_dreg (regs, reg) & 0xffff0000) - | (((m68k_dreg (regs, reg) & 0xffff) - 1) & 0xffff)); - - - // condition reversed. - // if ((m68k_dreg (regs, reg) & 0xffff) == 0xffff) - if ((m68k_dreg (regs, reg) & 0xffff) != 0xffff) - m68k_setpc (pc + disp); - } -} - -void FFPU fpuop_scc(uae_u32 opcode, uae_u32 extra) -{ - fpu_debug(("fscc_opp %X, %X at %08lx\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); - - uae_u32 ad; - int cc = fpp_cond(extra & 0x3f); - if (cc == -1) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - } - else if ((opcode & 0x38) == 0) { - m68k_dreg (regs, opcode & 7) = (m68k_dreg (regs, opcode & 7) & ~0xff) | - (cc ? 0xff : 0x00); - } - else if (get_fp_ad(opcode, &ad) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - } - else - put_byte(ad, cc ? 0xff : 0x00); -} - -void FFPU fpuop_trapcc(uae_u32 opcode, uaecptr oldpc) -{ - fpu_debug(("ftrapcc_opp %X at %08lx\n", (uae_u32)opcode, m68k_getpc ())); - - int cc = fpp_cond(opcode & 0x3f); - if (cc == -1) { - m68k_setpc (oldpc); - op_illg (opcode); - } - if (cc) - Exception(7, oldpc - 2); -} - -// NOTE that we get here also when there is a FNOP (nontrapping false, displ 0) -void FFPU fpuop_bcc(uae_u32 opcode, uaecptr pc, uae_u32 extra) -{ - fpu_debug(("fbcc_opp %X, %X at %08lx, jumpto=%X\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc (), extra )); - - int cc = fpp_cond(opcode & 0x3f); - if (cc == -1) { - m68k_setpc (pc); - op_illg (opcode); - } - else if (cc) { - if ((opcode & 0x40) == 0) - extra = (uae_s32) (uae_s16) extra; - m68k_setpc (pc + extra); - } -} - -// FSAVE has no post-increment -// 0x1f180000 == IDLE state frame, coprocessor version number 1F -void FFPU fpuop_save(uae_u32 opcode) -{ - fpu_debug(("fsave_opp at %08lx\n", m68k_getpc ())); - - uae_u32 ad; - int incr = (opcode & 0x38) == 0x20 ? -1 : 1; - int i; - - if (get_fp_ad(opcode, &ad) == 0) { - m68k_setpc (m68k_getpc () - 2); - op_illg (opcode); - return; - } - - if (CPUType == 4) { - // Put 4 byte 68040 IDLE frame. - if (incr < 0) { - ad -= 4; - put_long (ad, 0x41000000); - } - else { - put_long (ad, 0x41000000); - ad += 4; - } - } else { - // Put 28 byte 68881 IDLE frame. - if (incr < 0) { - fpu_debug(("fsave_opp pre-decrement\n")); - ad -= 4; - // What's this? Some BIU flags, or (incorrectly placed) command/condition? - put_long (ad, 0x70000000); - for (i = 0; i < 5; i++) { - ad -= 4; - put_long (ad, 0x00000000); - } - ad -= 4; - put_long (ad, 0x1f180000); // IDLE, vers 1f - } - else { - put_long (ad, 0x1f180000); // IDLE, vers 1f - ad += 4; - for (i = 0; i < 5; i++) { - put_long (ad, 0x00000000); - ad += 4; - } - // What's this? Some BIU flags, or (incorrectly placed) command/condition? - put_long (ad, 0x70000000); - ad += 4; - } - } - if ((opcode & 0x38) == 0x18) { - m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881 - fpu_debug(("PROBLEM: fsave_opp post-increment\n")); - } - if ((opcode & 0x38) == 0x20) { - m68k_areg (regs, opcode & 7) = ad; - fpu_debug(("fsave_opp pre-decrement %X -> A%d\n",ad,opcode & 7)); - } -} - -// FRESTORE has no pre-decrement -void FFPU fpuop_restore(uae_u32 opcode) -{ - fpu_debug(("frestore_opp at %08lx\n", m68k_getpc ())); - - uae_u32 ad; - uae_u32 d; - int incr = (opcode & 0x38) == 0x20 ? -1 : 1; - - if (get_fp_ad(opcode, &ad) == 0) { - m68k_setpc (m68k_getpc () - 2); - op_illg (opcode); - return; - } - - if (CPUType == 4) { - // 68040 - if (incr < 0) { - fpu_debug(("PROBLEM: frestore_opp incr < 0\n")); - // this may be wrong, but it's never called. - ad -= 4; - d = get_long (ad); - if ((d & 0xff000000) != 0) { // Not a NULL frame? - if ((d & 0x00ff0000) == 0) { // IDLE - fpu_debug(("frestore_opp found IDLE frame at %X\n",ad-4)); - } - else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP - fpu_debug(("PROBLEM: frestore_opp found UNIMP frame at %X\n",ad-4)); - ad -= 44; - } - else if ((d & 0x00ff0000) == 0x00600000) { // BUSY - fpu_debug(("PROBLEM: frestore_opp found BUSY frame at %X\n",ad-4)); - ad -= 92; - } - } - } - else { - d = get_long (ad); - fpu_debug(("frestore_opp frame at %X = %X\n",ad,d)); - ad += 4; - if ((d & 0xff000000) != 0) { // Not a NULL frame? - if ((d & 0x00ff0000) == 0) { // IDLE - fpu_debug(("frestore_opp found IDLE frame at %X\n",ad-4)); - } - else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP - fpu_debug(("PROBLEM: frestore_opp found UNIMP frame at %X\n",ad-4)); - ad += 44; - } - else if ((d & 0x00ff0000) == 0x00600000) { // BUSY - fpu_debug(("PROBLEM: frestore_opp found BUSY frame at %X\n",ad-4)); - ad += 92; - } - } - } - } - else { - // 68881 - if (incr < 0) { - fpu_debug(("PROBLEM: frestore_opp incr < 0\n")); - // this may be wrong, but it's never called. - ad -= 4; - d = get_long (ad); - if ((d & 0xff000000) != 0) { - if ((d & 0x00ff0000) == 0x00180000) - ad -= 6 * 4; - else if ((d & 0x00ff0000) == 0x00380000) - ad -= 14 * 4; - else if ((d & 0x00ff0000) == 0x00b40000) - ad -= 45 * 4; - } - } - else { - d = get_long (ad); - fpu_debug(("frestore_opp frame at %X = %X\n",ad,d)); - ad += 4; - if ((d & 0xff000000) != 0) { // Not a NULL frame? - if ((d & 0x00ff0000) == 0x00180000) { // IDLE - fpu_debug(("frestore_opp found IDLE frame at %X\n",ad-4)); - ad += 6 * 4; - } - else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C? - ad += 14 * 4; - fpu_debug(("PROBLEM: frestore_opp found UNIMP? frame at %X\n",ad-4)); - } - else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY - fpu_debug(("PROBLEM: frestore_opp found BUSY frame at %X\n",ad-4)); - ad += 45 * 4; - } - } - } - } - if ((opcode & 0x38) == 0x18) { - m68k_areg (regs, opcode & 7) = ad; - fpu_debug(("frestore_opp post-increment %X -> A%d\n",ad,opcode & 7)); - } - if ((opcode & 0x38) == 0x20) { - m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881 - fpu_debug(("PROBLEM: frestore_opp pre-decrement\n")); - } -} - -void FFPU fpuop_arithmetic(uae_u32 opcode, uae_u32 extra) -{ - int reg; - fpu_register src; - - fpu_debug(("FPP %04lx %04x at %08lx\n", opcode & 0xffff, extra & 0xffff, - m68k_getpc () - 4)); - - dump_registers( "START"); - - switch ((extra >> 13) & 0x7) { - case 3: - fpu_debug(("FMOVE -> \n")); - if (put_fp_value (opcode, extra, FPU registers[(extra >> 7) & 7]) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - } - dump_registers( "END "); - return; - case 4: - case 5: - if ((opcode & 0x38) == 0) { - if (extra & 0x2000) { // dr bit - if (extra & 0x1000) { - // according to the manual, the msb bits are always zero. - m68k_dreg (regs, opcode & 7) = get_fpcr() & 0xFFFF; - fpu_debug(("FMOVEM FPU fpcr (%X) -> D%d\n", get_fpcr(), opcode & 7)); - } - if (extra & 0x0800) { - m68k_dreg (regs, opcode & 7) = get_fpsr(); - fpu_debug(("FMOVEM FPU fpsr (%X) -> D%d\n", get_fpsr(), opcode & 7)); - } - if (extra & 0x0400) { - m68k_dreg (regs, opcode & 7) = FPU instruction_address; - fpu_debug(("FMOVEM FPU instruction_address (%X) -> D%d\n", FPU instruction_address, opcode & 7)); - } - } - else { - if (extra & 0x1000) { - set_fpcr( m68k_dreg (regs, opcode & 7) ); - fpu_debug(("FMOVEM D%d (%X) -> FPU fpcr\n", opcode & 7, get_fpcr())); - } - if (extra & 0x0800) { - set_fpsr( m68k_dreg (regs, opcode & 7) ); - fpu_debug(("FMOVEM D%d (%X) -> FPU fpsr\n", opcode & 7, get_fpsr())); - } - if (extra & 0x0400) { - FPU instruction_address = m68k_dreg (regs, opcode & 7); - fpu_debug(("FMOVEM D%d (%X) -> FPU instruction_address\n", opcode & 7, FPU instruction_address)); - } - } -// } else if ((opcode & 0x38) == 1) { - } - else if ((opcode & 0x38) == 8) { - if (extra & 0x2000) { // dr bit - if (extra & 0x1000) { - // according to the manual, the msb bits are always zero. - m68k_areg (regs, opcode & 7) = get_fpcr() & 0xFFFF; - fpu_debug(("FMOVEM FPU fpcr (%X) -> A%d\n", get_fpcr(), opcode & 7)); - } - if (extra & 0x0800) { - m68k_areg (regs, opcode & 7) = get_fpsr(); - fpu_debug(("FMOVEM FPU fpsr (%X) -> A%d\n", get_fpsr(), opcode & 7)); - } - if (extra & 0x0400) { - m68k_areg (regs, opcode & 7) = FPU instruction_address; - fpu_debug(("FMOVEM FPU instruction_address (%X) -> A%d\n", FPU instruction_address, opcode & 7)); - } - } else { - if (extra & 0x1000) { - set_fpcr( m68k_areg (regs, opcode & 7) ); - fpu_debug(("FMOVEM A%d (%X) -> FPU fpcr\n", opcode & 7, get_fpcr())); - } - if (extra & 0x0800) { - set_fpsr( m68k_areg (regs, opcode & 7) ); - fpu_debug(("FMOVEM A%d (%X) -> FPU fpsr\n", opcode & 7, get_fpsr())); - } - if (extra & 0x0400) { - FPU instruction_address = m68k_areg (regs, opcode & 7); - fpu_debug(("FMOVEM A%d (%X) -> FPU instruction_address\n", opcode & 7, FPU instruction_address)); - } - } - } - else if ((opcode & 0x3f) == 0x3c) { - if ((extra & 0x2000) == 0) { - if (extra & 0x1000) { - set_fpcr( next_ilong() ); - fpu_debug(("FMOVEM #<%X> -> FPU fpcr\n", get_fpcr())); - } - if (extra & 0x0800) { - set_fpsr( next_ilong() ); - fpu_debug(("FMOVEM #<%X> -> FPU fpsr\n", get_fpsr())); - } - if (extra & 0x0400) { - FPU instruction_address = next_ilong(); - fpu_debug(("FMOVEM #<%X> -> FPU instruction_address\n", FPU instruction_address)); - } - } - } - else if (extra & 0x2000) { - /* FMOVEM FPP->memory */ - uae_u32 ad; - int incr = 0; - - if (get_fp_ad(opcode, &ad) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - if ((opcode & 0x38) == 0x20) { - if (extra & 0x1000) - incr += 4; - if (extra & 0x0800) - incr += 4; - if (extra & 0x0400) - incr += 4; - } - ad -= incr; - if (extra & 0x1000) { - // according to the manual, the msb bits are always zero. - put_long (ad, get_fpcr() & 0xFFFF); - fpu_debug(("FMOVEM FPU fpcr (%X) -> mem %X\n", get_fpcr(), ad )); - ad += 4; - } - if (extra & 0x0800) { - put_long (ad, get_fpsr()); - fpu_debug(("FMOVEM FPU fpsr (%X) -> mem %X\n", get_fpsr(), ad )); - ad += 4; - } - if (extra & 0x0400) { - put_long (ad, FPU instruction_address); - fpu_debug(("FMOVEM FPU instruction_address (%X) -> mem %X\n", FPU instruction_address, ad )); - ad += 4; - } - ad -= incr; - if ((opcode & 0x38) == 0x18) // post-increment? - m68k_areg (regs, opcode & 7) = ad; - if ((opcode & 0x38) == 0x20) // pre-decrement? - m68k_areg (regs, opcode & 7) = ad; - } - else { - /* FMOVEM memory->FPP */ - uae_u32 ad; - - if (get_fp_ad(opcode, &ad) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - - // ad = (opcode & 0x38) == 0x20 ? ad - 12 : ad; - int incr = 0; - if((opcode & 0x38) == 0x20) { - if (extra & 0x1000) - incr += 4; - if (extra & 0x0800) - incr += 4; - if (extra & 0x0400) - incr += 4; - ad = ad - incr; - } - - if (extra & 0x1000) { - set_fpcr( get_long (ad) ); - fpu_debug(("FMOVEM mem %X (%X) -> FPU fpcr\n", ad, get_fpcr() )); - ad += 4; - } - if (extra & 0x0800) { - set_fpsr( get_long (ad) ); - fpu_debug(("FMOVEM mem %X (%X) -> FPU fpsr\n", ad, get_fpsr() )); - ad += 4; - } - if (extra & 0x0400) { - FPU instruction_address = get_long (ad); - fpu_debug(("FMOVEM mem %X (%X) -> FPU instruction_address\n", ad, FPU instruction_address )); - ad += 4; - } - if ((opcode & 0x38) == 0x18) // post-increment? - m68k_areg (regs, opcode & 7) = ad; - if ((opcode & 0x38) == 0x20) // pre-decrement? -// m68k_areg (regs, opcode & 7) = ad - 12; - m68k_areg (regs, opcode & 7) = ad - incr; - } - dump_registers( "END "); - return; - case 6: - case 7: { - uae_u32 ad, list = 0; - int incr = 0; - if (extra & 0x2000) { - /* FMOVEM FPP->memory */ - fpu_debug(("FMOVEM FPP->memory\n")); - - if (get_fp_ad(opcode, &ad) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - switch ((extra >> 11) & 3) { - case 0: /* static pred */ - list = extra & 0xff; - incr = -1; - break; - case 1: /* dynamic pred */ - list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - incr = -1; - break; - case 2: /* static postinc */ - list = extra & 0xff; - incr = 1; - break; - case 3: /* dynamic postinc */ - list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - incr = 1; - break; - } - - if (incr < 0) { - for(reg=7; reg>=0; reg--) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - extract_extended(FPU registers[reg],&wrd1, &wrd2, &wrd3); - ad -= 4; - put_long (ad, wrd3); - ad -= 4; - put_long (ad, wrd2); - ad -= 4; - put_long (ad, wrd1); - } - list <<= 1; - } - } - else { - for(reg=0; reg<8; reg++) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - extract_extended(FPU registers[reg],&wrd1, &wrd2, &wrd3); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - ad += 4; - put_long (ad, wrd3); - ad += 4; - } - list <<= 1; - } - } - if ((opcode & 0x38) == 0x18) // post-increment? - m68k_areg (regs, opcode & 7) = ad; - if ((opcode & 0x38) == 0x20) // pre-decrement? - m68k_areg (regs, opcode & 7) = ad; - } - else { - /* FMOVEM memory->FPP */ - fpu_debug(("FMOVEM memory->FPP\n")); - - if (get_fp_ad(opcode, &ad) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - switch ((extra >> 11) & 3) { - case 0: /* static pred */ - fpu_debug(("memory->FMOVEM FPP not legal mode.\n")); - list = extra & 0xff; - incr = -1; - break; - case 1: /* dynamic pred */ - fpu_debug(("memory->FMOVEM FPP not legal mode.\n")); - list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - incr = -1; - break; - case 2: /* static postinc */ - list = extra & 0xff; - incr = 1; - break; - case 3: /* dynamic postinc */ - list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - incr = 1; - break; - } - - /**/ - if (incr < 0) { - // not reached - for(reg=7; reg>=0; reg--) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - ad -= 4; - wrd3 = get_long (ad); - ad -= 4; - wrd2 = get_long (ad); - ad -= 4; - wrd1 = get_long (ad); - // FPU registers[reg] = make_extended(wrd1, wrd2, wrd3); - make_extended_no_normalize (wrd1, wrd2, wrd3, FPU registers[reg]); - } - list <<= 1; - } - } - else { - for(reg=0; reg<8; reg++) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - ad += 4; - wrd3 = get_long (ad); - ad += 4; - // FPU registers[reg] = make_extended(wrd1, wrd2, wrd3); - make_extended_no_normalize (wrd1, wrd2, wrd3, FPU registers[reg]); - } - list <<= 1; - } - } - if ((opcode & 0x38) == 0x18) // post-increment? - m68k_areg (regs, opcode & 7) = ad; - if ((opcode & 0x38) == 0x20) // pre-decrement? - m68k_areg (regs, opcode & 7) = ad; - } - dump_registers( "END "); - return; - } - case 0: - case 2: - reg = (extra >> 7) & 7; - if ((extra & 0xfc00) == 0x5c00) { - fpu_debug(("FMOVECR memory->FPP\n")); - switch (extra & 0x7f) { - case 0x00: - // FPU registers[reg] = 4.0 * atan(1.0); - FPU registers[reg] = 3.1415926535897932384626433832795; - fpu_debug(("FP const: Pi\n")); - break; - case 0x0b: - // FPU registers[reg] = log10 (2.0); - FPU registers[reg] = 0.30102999566398119521373889472449; - fpu_debug(("FP const: Log 10 (2)\n")); - break; - case 0x0c: - // FPU registers[reg] = exp (1.0); - FPU registers[reg] = 2.7182818284590452353602874713527; - fpu_debug(("FP const: e\n")); - break; - case 0x0d: - // FPU registers[reg] = log (exp (1.0)) / log (2.0); - FPU registers[reg] = 1.4426950408889634073599246810019; - fpu_debug(("FP const: Log 2 (e)\n")); - break; - case 0x0e: - // FPU registers[reg] = log (exp (1.0)) / log (10.0); - FPU registers[reg] = 0.43429448190325182765112891891661; - fpu_debug(("FP const: Log 10 (e)\n")); - break; - case 0x0f: - FPU registers[reg] = 0.0; - fpu_debug(("FP const: zero\n")); - break; - case 0x30: - // FPU registers[reg] = log (2.0); - FPU registers[reg] = 0.69314718055994530941723212145818; - fpu_debug(("FP const: ln(2)\n")); - break; - case 0x31: - // FPU registers[reg] = log (10.0); - FPU registers[reg] = 2.3025850929940456840179914546844; - fpu_debug(("FP const: ln(10)\n")); - break; - case 0x32: - // ?? - FPU registers[reg] = 1.0e0; - fpu_debug(("FP const: 1.0e0\n")); - break; - case 0x33: - FPU registers[reg] = 1.0e1; - fpu_debug(("FP const: 1.0e1\n")); - break; - case 0x34: - FPU registers[reg] = 1.0e2; - fpu_debug(("FP const: 1.0e2\n")); - break; - case 0x35: - FPU registers[reg] = 1.0e4; - fpu_debug(("FP const: 1.0e4\n")); - break; - case 0x36: - FPU registers[reg] = 1.0e8; - fpu_debug(("FP const: 1.0e8\n")); - break; - case 0x37: - FPU registers[reg] = 1.0e16; - fpu_debug(("FP const: 1.0e16\n")); - break; - case 0x38: - FPU registers[reg] = 1.0e32; - fpu_debug(("FP const: 1.0e32\n")); - break; - case 0x39: - FPU registers[reg] = 1.0e64; - fpu_debug(("FP const: 1.0e64\n")); - break; - case 0x3a: - FPU registers[reg] = 1.0e128; - fpu_debug(("FP const: 1.0e128\n")); - break; - case 0x3b: - FPU registers[reg] = 1.0e256; - fpu_debug(("FP const: 1.0e256\n")); - break; -#if USE_LONG_DOUBLE || USE_QUAD_DOUBLE - case 0x3c: - FPU registers[reg] = 1.0e512L; - fpu_debug(("FP const: 1.0e512\n")); - break; - case 0x3d: - FPU registers[reg] = 1.0e1024L; - fpu_debug(("FP const: 1.0e1024\n")); - break; - case 0x3e: - FPU registers[reg] = 1.0e2048L; - fpu_debug(("FP const: 1.0e2048\n")); - break; - case 0x3f: - FPU registers[reg] = 1.0e4096L; - fpu_debug(("FP const: 1.0e4096\n")); -#endif - break; - default: - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - break; - } - // these *do* affect the status reg - make_fpsr(FPU registers[reg]); - dump_registers( "END "); - return; - } - - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - fpu_debug(("returned from get_fp_value m68k_getpc()=%X\n",m68k_getpc())); - - if (FPU is_integral) { - // 68040-specific operations - switch (extra & 0x7f) { - case 0x40: /* FSMOVE */ - fpu_debug(("FSMOVE %.04f\n",(double)src)); - FPU registers[reg] = (float)src; - make_fpsr(FPU registers[reg]); - break; - case 0x44: /* FDMOVE */ - fpu_debug(("FDMOVE %.04f\n",(double)src)); - FPU registers[reg] = (double)src; - make_fpsr(FPU registers[reg]); - break; - case 0x41: /* FSSQRT */ - fpu_debug(("FSQRT %.04f\n",(double)src)); - FPU registers[reg] = (float)fp_sqrt (src); - make_fpsr(FPU registers[reg]); - break; - case 0x45: /* FDSQRT */ - fpu_debug(("FSQRT %.04f\n",(double)src)); - FPU registers[reg] = (double)fp_sqrt (src); - make_fpsr(FPU registers[reg]); - break; - case 0x58: /* FSABS */ - fpu_debug(("FSABS %.04f\n",(double)src)); - FPU registers[reg] = (float)fp_fabs(src); - make_fpsr(FPU registers[reg]); - break; - case 0x5c: /* FDABS */ - fpu_debug(("FDABS %.04f\n",(double)src)); - FPU registers[reg] = (double)fp_fabs(src); - make_fpsr(FPU registers[reg]); - break; - case 0x5a: /* FSNEG */ - fpu_debug(("FSNEG %.04f\n",(double)src)); - FPU registers[reg] = (float)-src; - make_fpsr(FPU registers[reg]); - break; - case 0x5e: /* FDNEG */ - fpu_debug(("FDNEG %.04f\n",(double)src)); - FPU registers[reg] = (double)-src; - make_fpsr(FPU registers[reg]); - break; - case 0x60: /* FSDIV */ - fpu_debug(("FSDIV %.04f\n",(double)src)); - FPU registers[reg] = (float)(FPU registers[reg] / src); - make_fpsr(FPU registers[reg]); - break; - case 0x64: /* FDDIV */ - fpu_debug(("FDDIV %.04f\n",(double)src)); - FPU registers[reg] = (double)(FPU registers[reg] / src); - make_fpsr(FPU registers[reg]); - break; - case 0x62: /* FSADD */ - fpu_debug(("FSADD %.04f\n",(double)src)); - FPU registers[reg] = (float)(FPU registers[reg] + src); - make_fpsr(FPU registers[reg]); - break; - case 0x66: /* FDADD */ - fpu_debug(("FDADD %.04f\n",(double)src)); - FPU registers[reg] = (double)(FPU registers[reg] + src); - make_fpsr(FPU registers[reg]); - break; - case 0x68: /* FSSUB */ - fpu_debug(("FSSUB %.04f\n",(double)src)); - FPU registers[reg] = (float)(FPU registers[reg] - src); - make_fpsr(FPU registers[reg]); - break; - case 0x6c: /* FDSUB */ - fpu_debug(("FDSUB %.04f\n",(double)src)); - FPU registers[reg] = (double)(FPU registers[reg] - src); - make_fpsr(FPU registers[reg]); - break; - case 0x63: /* FSMUL */ - case 0x67: /* FDMUL */ - fpu_debug(("FMUL %.04f\n",(double)src)); - get_dest_flags(FPU registers[reg]); - get_source_flags(src); - if(fl_dest.in_range && fl_source.in_range) { - if ((extra & 0x7f) == 0x63) - FPU registers[reg] = (float)(FPU registers[reg] * src); - else - FPU registers[reg] = (double)(FPU registers[reg] * src); - } - else if (fl_dest.nan || fl_source.nan || - fl_dest.zero && fl_source.infinity || - fl_dest.infinity && fl_source.zero ) { - make_nan( FPU registers[reg] ); - } - else if (fl_dest.zero || fl_source.zero ) { - if (fl_dest.negative && !fl_source.negative || - !fl_dest.negative && fl_source.negative) { - make_zero_negative(FPU registers[reg]); - } - else { - make_zero_positive(FPU registers[reg]); - } - } - else { - if( fl_dest.negative && !fl_source.negative || - !fl_dest.negative && fl_source.negative) { - make_inf_negative(FPU registers[reg]); - } - else { - make_inf_positive(FPU registers[reg]); - } - } - make_fpsr(FPU registers[reg]); - break; - default: - // Continue decode-execute 6888x instructions below - goto process_6888x_instructions; - } - fpu_debug(("END m68k_getpc()=%X\n",m68k_getpc())); - dump_registers( "END "); - return; - } - - process_6888x_instructions: - switch (extra & 0x7f) { - case 0x00: /* FMOVE */ - fpu_debug(("FMOVE %.04f\n",(double)src)); - FPU registers[reg] = src; - make_fpsr(FPU registers[reg]); - break; - case 0x01: /* FINT */ - fpu_debug(("FINT %.04f\n",(double)src)); - FPU registers[reg] = toint(src); - make_fpsr(FPU registers[reg]); - break; - case 0x02: /* FSINH */ - fpu_debug(("FSINH %.04f\n",(double)src)); - FPU registers[reg] = fp_sinh (src); - make_fpsr(FPU registers[reg]); - break; - case 0x03: /* FINTRZ */ - fpu_debug(("FINTRZ %.04f\n",(double)src)); - FPU registers[reg] = fp_round_to_zero(src); - make_fpsr(FPU registers[reg]); - break; - case 0x04: /* FSQRT */ - fpu_debug(("FSQRT %.04f\n",(double)src)); - FPU registers[reg] = fp_sqrt (src); - make_fpsr(FPU registers[reg]); - break; - case 0x06: /* FLOGNP1 */ - fpu_debug(("FLOGNP1 %.04f\n",(double)src)); - FPU registers[reg] = fp_log (src + 1.0); - make_fpsr(FPU registers[reg]); - break; - case 0x08: /* FETOXM1 */ - fpu_debug(("FETOXM1 %.04f\n",(double)src)); - FPU registers[reg] = fp_exp (src) - 1.0; - make_fpsr(FPU registers[reg]); - break; - case 0x09: /* FTANH */ - fpu_debug(("FTANH %.04f\n",(double)src)); - FPU registers[reg] = fp_tanh (src); - make_fpsr(FPU registers[reg]); - break; - case 0x0a: /* FATAN */ - fpu_debug(("FATAN %.04f\n",(double)src)); - FPU registers[reg] = fp_atan (src); - make_fpsr(FPU registers[reg]); - break; - case 0x0c: /* FASIN */ - fpu_debug(("FASIN %.04f\n",(double)src)); - FPU registers[reg] = fp_asin (src); - make_fpsr(FPU registers[reg]); - break; - case 0x0d: /* FATANH */ - fpu_debug(("FATANH %.04f\n",(double)src)); - FPU registers[reg] = fp_atanh (src); - make_fpsr(FPU registers[reg]); - break; - case 0x0e: /* FSIN */ - fpu_debug(("FSIN %.04f\n",(double)src)); - FPU registers[reg] = fp_sin (src); - make_fpsr(FPU registers[reg]); - break; - case 0x0f: /* FTAN */ - fpu_debug(("FTAN %.04f\n",(double)src)); - FPU registers[reg] = fp_tan (src); - make_fpsr(FPU registers[reg]); - break; - case 0x10: /* FETOX */ - fpu_debug(("FETOX %.04f\n",(double)src)); - FPU registers[reg] = fp_exp (src); - make_fpsr(FPU registers[reg]); - break; - case 0x11: /* FTWOTOX */ - fpu_debug(("FTWOTOX %.04f\n",(double)src)); - FPU registers[reg] = fp_pow(2.0, src); - make_fpsr(FPU registers[reg]); - break; - case 0x12: /* FTENTOX */ - fpu_debug(("FTENTOX %.04f\n",(double)src)); - FPU registers[reg] = fp_pow(10.0, src); - make_fpsr(FPU registers[reg]); - break; - case 0x14: /* FLOGN */ - fpu_debug(("FLOGN %.04f\n",(double)src)); - FPU registers[reg] = fp_log (src); - make_fpsr(FPU registers[reg]); - break; - case 0x15: /* FLOG10 */ - fpu_debug(("FLOG10 %.04f\n",(double)src)); - FPU registers[reg] = fp_log10 (src); - make_fpsr(FPU registers[reg]); - break; - case 0x16: /* FLOG2 */ - fpu_debug(("FLOG2 %.04f\n",(double)src)); - FPU registers[reg] = fp_log (src) / fp_log (2.0); - make_fpsr(FPU registers[reg]); - break; - case 0x18: /* FABS */ - fpu_debug(("FABS %.04f\n",(double)src)); - FPU registers[reg] = fp_fabs(src); - make_fpsr(FPU registers[reg]); - break; - case 0x19: /* FCOSH */ - fpu_debug(("FCOSH %.04f\n",(double)src)); - FPU registers[reg] = fp_cosh(src); - make_fpsr(FPU registers[reg]); - break; - case 0x1a: /* FNEG */ - fpu_debug(("FNEG %.04f\n",(double)src)); - FPU registers[reg] = -src; - make_fpsr(FPU registers[reg]); - break; - case 0x1c: /* FACOS */ - fpu_debug(("FACOS %.04f\n",(double)src)); - FPU registers[reg] = fp_acos(src); - make_fpsr(FPU registers[reg]); - break; - case 0x1d: /* FCOS */ - fpu_debug(("FCOS %.04f\n",(double)src)); - FPU registers[reg] = fp_cos(src); - make_fpsr(FPU registers[reg]); - break; - case 0x1e: /* FGETEXP */ - fpu_debug(("FGETEXP %.04f\n",(double)src)); - if( isinf(src) ) { - make_nan( FPU registers[reg] ); - } - else { - FPU registers[reg] = fast_fgetexp( src ); - } - make_fpsr(FPU registers[reg]); - break; - case 0x1f: /* FGETMAN */ - fpu_debug(("FGETMAN %.04f\n",(double)src)); - if( src == 0 ) { - FPU registers[reg] = 0; - } - else if( isinf(src) ) { - make_nan( FPU registers[reg] ); - } - else { - FPU registers[reg] = src; - fast_remove_exponent( FPU registers[reg] ); - } - make_fpsr(FPU registers[reg]); - break; - case 0x20: /* FDIV */ - fpu_debug(("FDIV %.04f\n",(double)src)); - FPU registers[reg] /= src; - make_fpsr(FPU registers[reg]); - break; - case 0x21: /* FMOD */ - fpu_debug(("FMOD %.04f\n",(double)src)); - // FPU registers[reg] = FPU registers[reg] - (fpu_register) ((int) (FPU registers[reg] / src)) * src; - { - fpu_register quot = fp_round_to_zero(FPU registers[reg] / src); - uae_u32 sign = get_quotient_sign(FPU registers[reg],src); - FPU registers[reg] = FPU registers[reg] - quot * src; - make_fpsr(FPU registers[reg]); - make_quotient(quot, sign); - } - break; - case 0x23: /* FMUL */ - fpu_debug(("FMUL %.04f\n",(double)src)); - get_dest_flags(FPU registers[reg]); - get_source_flags(src); - if(fl_dest.in_range && fl_source.in_range) { - FPU registers[reg] *= src; - } - else if (fl_dest.nan || fl_source.nan || - fl_dest.zero && fl_source.infinity || - fl_dest.infinity && fl_source.zero ) { - make_nan( FPU registers[reg] ); - } - else if (fl_dest.zero || fl_source.zero ) { - if (fl_dest.negative && !fl_source.negative || - !fl_dest.negative && fl_source.negative) { - make_zero_negative(FPU registers[reg]); - } - else { - make_zero_positive(FPU registers[reg]); - } - } - else { - if( fl_dest.negative && !fl_source.negative || - !fl_dest.negative && fl_source.negative) { - make_inf_negative(FPU registers[reg]); - } - else { - make_inf_positive(FPU registers[reg]); - } - } - make_fpsr(FPU registers[reg]); - break; - case 0x24: /* FSGLDIV */ - fpu_debug(("FSGLDIV %.04f\n",(double)src)); - FPU registers[reg] = (float)(FPU registers[reg] / src); - make_fpsr(FPU registers[reg]); - break; - case 0x25: /* FREM */ - fpu_debug(("FREM %.04f\n",(double)src)); - // FPU registers[reg] = FPU registers[reg] - (double) ((int) (FPU registers[reg] / src + 0.5)) * src; - { - fpu_register quot = fp_round_to_nearest(FPU registers[reg] / src); - uae_u32 sign = get_quotient_sign(FPU registers[reg],src); - FPU registers[reg] = FPU registers[reg] - quot * src; - make_fpsr(FPU registers[reg]); - make_quotient(quot,sign); - } - break; - - case 0x26: /* FSCALE */ - fpu_debug(("FSCALE %.04f\n",(double)src)); - // TODO: overflow flags - get_dest_flags(FPU registers[reg]); - get_source_flags(src); - if (fl_source.in_range && fl_dest.in_range) { - // When the absolute value of the source operand is >= 2^14, - // an overflow or underflow always results. - // Here (int) cast is okay. - int scale_factor = (int)fp_round_to_zero(src); -#if USE_LONG_DOUBLE || USE_QUAD_DOUBLE - fp_declare_init_shape(sxp, FPU registers[reg], extended); - sxp->ieee.exponent += scale_factor; -#else - fp_declare_init_shape(sxp, FPU registers[reg], double); - uae_u32 exp = sxp->ieee.exponent + scale_factor; - if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS) - exp = 0; - else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS) - exp = FP_DOUBLE_EXP_MAX; - else - exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS; - sxp->ieee.exponent = exp; -#endif - } - else if (fl_source.infinity) { - // Returns NaN for any Infinity source - make_nan( FPU registers[reg] ); - } - make_fpsr(FPU registers[reg]); - break; - case 0x27: /* FSGLMUL */ - fpu_debug(("FSGLMUL %.04f\n",(double)src)); - FPU registers[reg] = (float)(FPU registers[reg] * src); - make_fpsr(FPU registers[reg]); - break; - case 0x28: /* FSUB */ - fpu_debug(("FSUB %.04f\n",(double)src)); - FPU registers[reg] -= src; - make_fpsr(FPU registers[reg]); - break; - case 0x22: /* FADD */ - fpu_debug(("FADD %.04f\n",(double)src)); - FPU registers[reg] += src; - make_fpsr(FPU registers[reg]); - break; - case 0x30: /* FSINCOS */ - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - fpu_debug(("FSINCOS %.04f\n",(double)src)); - // Cosine must be calculated first if same register - FPU registers[extra & 7] = fp_cos(src); - FPU registers[reg] = fp_sin (src); - // Set FPU fpsr according to the sine result - make_fpsr(FPU registers[reg]); - break; - case 0x38: /* FCMP */ - fpu_debug(("FCMP %.04f\n",(double)src)); - set_fpsr(0); - make_fpsr(FPU registers[reg] - src); - break; - case 0x3a: /* FTST */ - fpu_debug(("FTST %.04f\n",(double)src)); - set_fpsr(0); - make_fpsr(src); - break; - default: - fpu_debug(("ILLEGAL F OP %X\n",opcode)); - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - break; - } - fpu_debug(("END m68k_getpc()=%X\n",m68k_getpc())); - dump_registers( "END "); - return; - } - - fpu_debug(("ILLEGAL F OP 2 %X\n",opcode)); - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); -} - -/* -------------------------- Initialization -------------------------- */ - -PRIVATE uae_u8 m_fpu_state_original[108]; // 90/94/108 - -PUBLIC void FFPU fpu_init (bool integral_68040) -{ - fpu_debug(("fpu_init\n")); - - static bool initialized_lookup_tables = false; - if (!initialized_lookup_tables) { - fpu_init_native_fflags(); - fpu_init_native_exceptions(); - fpu_init_native_accrued_exceptions(); - initialized_lookup_tables = true; - } - - FPU is_integral = integral_68040; - FPU instruction_address = 0; - FPU fpsr.quotient = 0; - set_fpcr(0); - set_fpsr(0); - -#if defined(FPU_USE_X86_ROUNDING) - // Initial state after boot, reset and frestore(null frame) - x86_control_word = CW_INITIAL; -#elif defined(USE_X87_ASSEMBLY) - volatile unsigned short int cw; - __asm__ __volatile__("fnstcw %0" : "=m" (cw)); - cw &= ~0x0300; cw |= 0x0300; // CW_PC_EXTENDED - cw &= ~0x0C00; cw |= 0x0000; // CW_RC_NEAR - __asm__ __volatile__("fldcw %0" : : "m" (cw)); -#endif - - FPU result = 1; - - for (int i = 0; i < 8; i++) - make_nan(FPU registers[i]); -} - -PUBLIC void FFPU fpu_exit (void) -{ - fpu_debug(("fpu_exit\n")); -} - -PUBLIC void FFPU fpu_reset (void) -{ - fpu_debug(("fpu_reset\n")); - fpu_exit(); - fpu_init(FPU is_integral); -} diff --git a/BasiliskII/src/uae_cpu/fpu/fpu_ieee.h b/BasiliskII/src/uae_cpu/fpu/fpu_ieee.h deleted file mode 100644 index 89501956..00000000 --- a/BasiliskII/src/uae_cpu/fpu/fpu_ieee.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * fpu/fpu_uae.h - Extra Definitions for the old UAE FPU core - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * MC68881/68040 fpu emulation - * - * Original UAE FPU, copyright 1996 Herman ten Brugge - * Rewrite for x86, copyright 1999-2000 Lauri Pesonen - * New framework, copyright 2000 Gwenole Beauchesne - * Adapted for JIT compilation (c) Bernd Meyer, 2000 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef FPU_IEEE_H -#define FPU_IEEE_H - -/* NOTE: this file shall be included from fpu/fpu_uae.cpp */ -#undef PUBLIC -#define PUBLIC extern - -#undef PRIVATE -#define PRIVATE static - -#undef FFPU -#define FFPU /**/ - -#undef FPU -#define FPU fpu. - -// Lauri-- full words to avoid partial register stalls. -struct double_flags { - uae_u32 in_range; - uae_u32 zero; - uae_u32 infinity; - uae_u32 nan; - uae_u32 negative; -}; -PRIVATE double_flags fl_source; -PRIVATE double_flags fl_dest; -PRIVATE inline void FFPU get_dest_flags(fpu_register const & r); -PRIVATE inline void FFPU get_source_flags(fpu_register const & r); - -PRIVATE inline void FFPU make_nan(fpu_register & r); -PRIVATE inline void FFPU make_zero_positive(fpu_register & r); -PRIVATE inline void FFPU make_zero_negative(fpu_register & r); -PRIVATE inline void FFPU make_inf_positive(fpu_register & r); -PRIVATE inline void FFPU make_inf_negative(fpu_register & r); - -PRIVATE inline void FFPU fast_scale(fpu_register & r, int add); -PRIVATE inline fpu_register FFPU fast_fgetexp(fpu_register const & r); - -// May be optimized for particular processors -#ifndef FPU_USE_NATIVE_FLAGS -PRIVATE inline void FFPU make_fpsr(fpu_register const & r); -#endif - -// Normalize to range 1..2 -PRIVATE inline void FFPU fast_remove_exponent(fpu_register & r); - -// The sign of the quotient is the exclusive-OR of the sign bits -// of the source and destination operands. -PRIVATE inline uae_u32 FFPU get_quotient_sign( - fpu_register const & ra, fpu_register const & rb -); - -// Quotient Byte is loaded with the sign and least significant -// seven bits of the quotient. -PRIVATE inline void FFPU make_quotient( - fpu_register const & quotient, uae_u32 sign -); - -// to_single -PRIVATE inline fpu_register FFPU make_single( - uae_u32 value -); - -// from_single -PRIVATE inline uae_u32 FFPU extract_single( - fpu_register const & src -); - -// to_exten -PRIVATE inline fpu_register FFPU make_extended( - uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3 -); - -/* - Would be so much easier with full size floats :( - ... this is so vague. -*/ -// to_exten_no_normalize -PRIVATE inline void FFPU make_extended_no_normalize( - uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & result -); - -// from_exten -PRIVATE inline void FFPU extract_extended(fpu_register const & src, - uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3 -); - -// to_double -PRIVATE inline fpu_register FFPU make_double( - uae_u32 wrd1, uae_u32 wrd2 -); - -// from_double -PRIVATE inline void FFPU extract_double(fpu_register const & src, - uae_u32 * wrd1, uae_u32 * wrd2 -); - -PRIVATE inline fpu_register FFPU make_packed( - uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3 -); - -PRIVATE inline void FFPU extract_packed( - fpu_register const & src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3 -); - -PRIVATE inline int FFPU get_fp_value( - uae_u32 opcode, uae_u16 extra, fpu_register & src -); - -PRIVATE inline int FFPU put_fp_value( - uae_u32 opcode, uae_u16 extra, fpu_register const & value -); - -PRIVATE inline int FFPU get_fp_ad( - uae_u32 opcode, uae_u32 * ad -); - -PRIVATE inline int FFPU fpp_cond( - int condition -); - -#endif /* FPU_IEEE_H */ diff --git a/BasiliskII/src/uae_cpu/fpu/fpu_x86.cpp b/BasiliskII/src/uae_cpu/fpu/fpu_x86.cpp deleted file mode 100644 index 70e59086..00000000 --- a/BasiliskII/src/uae_cpu/fpu/fpu_x86.cpp +++ /dev/null @@ -1,6126 +0,0 @@ -/* - * fpu_x86.cpp - 68881/68040 fpu code for x86/Windows an Linux/x86. - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * MC68881/68040 fpu emulation - * - * Based on UAE FPU, original copyright 1996 Herman ten Brugge, - * rewritten for x86 by Lauri Pesonen 1999-2000, - * accomodated to GCC's Extended Asm syntax by Gwenole Beauchesne 2000. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * Interface - * Almost the same as original. Please see the comments in "fpu.h". - * - * - * Why assembly? - * The reason is not really speed, but to get infinities, - * NANs and flags finally working. - * - * - * How to maintain Mac and x86 FPU flags -- plan B - * - * regs.piar is not updated. - * - * regs.FPU fpcr always contains the real 68881/68040 control word. - * - * regs.FPU fpsr is not kept up-to-date, for efficiency reasons. - * Most of the FPU commands update this in a way or another, but it is not - * read nearly that often. Therefore, three host-specific words hold the - * status byte and exception byte ("x86_status_word"), accrued exception - * byte ("x86_status_word_accrued") and the quotient byte ("FPU fpsr.quotient"), - * as explained below. - * - * CONDITION CODE - QUOTIENT - EXCEPTION STATUS - ACCRUED EXCEPTION - * CONDITION CODE (N,Z,I,NAN) - * - updated after each opcode, if needed. - * - x86 assembly opcodes call FXAM and store the status word to - * "x86_status_word". - * - When regs.FPU fpsr is actually used, the value of "x86_status_word" - * is translated. - * QUOTIENT BYTE - * - Updated by frem, fmod, frestore(null frame) - * - Stored in "FPU fpsr.quotient" in correct bit position, combined when - * regs.FPU fpsr is actually used. - * EXCEPTION STATUS (BSUN,SNAN,OPERR,OVFL,UNFL,DZ,INEX2,INEX1) - * - updated after each opcode, if needed. - * - Saved in x86 form in "x86_status_word". - * - When regs.FPU fpsr is actually used, the value of "x86_status_word" - * is translated. - * - Only fcc_op can set BSUN - * ACCRUED EXCEPTION (ACCR_IOP,ACCR_OVFL,ACCR_UNFL,ACCR_DZ,ACCR_INEX) - * - updated after each opcode, if needed. - * - Logically OR'ed in x86 form to "x86_status_word_accrued". - * - When regs.FPU fpsr is actually used, the value of - * "x86_status_word_accrued" is translated. - * - * When "x86_status_word" and "x86_status_word_accrued" are stored, - * all pending x86 FPU exceptions are cleared, if there are any. - * - * Writing to "regs.FPU fpsr" reverse-maps to x86 status/exception values and - * stores the values in "x86_status_word", "x86_status_word_accrued" - * and "FPU fpsr.quotient". - * - * So, "x86_status_word" and "x86_status_word_accrued" are not in - * correct bit positions and have x86 values, but "FPU fpsr.quotient" is at - * correct position. - * - * Note that it does not matter that the reverse-mapping is not exact - * (both SW_IE and SW_DE are mapped to ACCR_IOP, but ACCR_IOP maps to - * SW_IE only), the MacOS always sees the correct exception bits. - * - * Also note the usage of the fake BSUN flag SW_FAKE_BSUN. If you change - * the x86 FPU code, you must make sure that you don't generate any FPU - * stack faults. - * - * - * x86 co-processor initialization: - * - * Bit Code Use - * 0 IM Invalid operation exception mask 1 Disabled - * 1 DM Denormalized operand exception mask 1 Disabled - * 2 ZM Zerodivide exception mask 1 Disabled - * 3 OM Overflow exception mask 1 Disabled - * 4 UM Underflow exception mask 1 Disabled - * 5 PM Precision exception mask 1 Disabled - * 6 - - - - - * 7 IEM Interrupt enable mask 0 Enabled - * 8 PC Precision control\ 1 - 64 bits - * 9 PC Precision control/ 1 / - * 10 RC Rounding control\ 0 - Nearest even - * 11 RC Rounding control/ 0 / - * 12 IC Infinity control 1 Affine - * 13 - - - - - * 14 - - - - - * 15 - - - - - * - * - * TODO: - * - Exceptions are not implemented. - * - All tbyte variables should be aligned to 16-byte boundaries. - * (for best efficiency). - * - FTRAPcc code looks like broken. - * - If USE_3_BIT_QUOTIENT is 0, exceptions should be checked after - * float -> int rounding (frem,fmod). - * - The speed can be greatly improved. Do this only after you are sure - * that there are no major bugs. - * - Support for big-endian byte order (but all assembly code needs to - * be rewritten anyway) - * I have some non-portable code like *((uae_u16 *)&m68k_dreg(regs, reg)) = newv; - * Sorry about that, you need to change these. I could do it myself, but better - * not, I would have no way to test them out. - * I tried to mark all spots with a comment TODO_BIGENDIAN. - * - to_double() may need renormalization code. Or then again, maybe not. - * - Signaling NANs should be handled better. The current mapping of - * signaling nan exception to denormalized operand exception is only - * based on the idea that the (possible) handler sees that "something - * seriously wrong" and takes the same action. Should not really get (m)any - * of those since normalization is handled on to_exten() - * - */ - -#include -#include -#include -#include - -#include "sysdeps.h" -#include "memory.h" -#include "readcpu.h" -#include "newcpu.h" -#define FPU_IMPLEMENTATION -#include "fpu/fpu.h" -#include "fpu/fpu_x86.h" -#include "fpu/fpu_x86_asm.h" - -/* Global FPU context */ -fpu_t fpu; - -/* -------------------------------------------------------------------------- */ -/* --- Native Support --- */ -/* -------------------------------------------------------------------------- */ - -#include "fpu/flags.h" -#include "fpu/exceptions.h" -#include "fpu/rounding.h" -#include "fpu/impl.h" - -#include "fpu/flags.cpp" -#include "fpu/exceptions.cpp" -#include "fpu/rounding.cpp" - -/* -------------------------------------------------------------------------- */ -/* --- Scopes Definition --- */ -/* -------------------------------------------------------------------------- */ - -#undef PUBLIC -#define PUBLIC /**/ - -#undef PRIVATE -#define PRIVATE static - -#undef FFPU -#define FFPU /**/ - -#undef FPU -#define FPU fpu. - -/* ---------------------------- Compatibility ---------------------------- */ - -#define BYTE uint8 -#define WORD uint16 -#define DWORD uint32 -#define min(a, b) (((a) < (b)) ? (a) : (b)) - -/* ---------------------------- Configuration ---------------------------- */ - -/* -If USE_3_BIT_QUOTIENT is set to 1, FREM and FMOD use a faster version -with only 3 quotient bits (those provided by the x86 FPU). If set to 0, -they calculate the same 7 bits that m68k does. It seems (as for now) that -3 bits suffice for all Mac programs I have tried. - -If you decide that you need all 7 bits (USE_3_BIT_QUOTIENT is 0), -consider checking the host exception flags after FISTP (search for -"TODO:Quotient". The result may be too large to fit into a dword. -*/ -/* -gb-- I only tested the following configurations: - USE_3_BIT_QUOTIENT 1 -- still changes to apply if no 3-bit quotient - FPU_DEBUG 1 or 0 - USE_CONSISTENCY_CHECKING 0 - I3_ON_ILLEGAL_FPU_OP 0 -- and this won't change - I3_ON_FTRAPCC 0 -- and this won't change -*/ -#define USE_3_BIT_QUOTIENT 1 - -//#define FPU_DEBUG 0 -- now defined in "fpu/fpu.h" -#define USE_CONSISTENCY_CHECKING 0 - -#define I3_ON_ILLEGAL_FPU_OP 0 -#define I3_ON_FTRAPCC 0 - -/* ---------------------------- Debugging ---------------------------- */ - -PUBLIC void FFPU fpu_dump_registers(void) -{ - for (int i = 0; i < 8; i++){ - printf ("FP%d: %g ", i, fpu_get_register(i)); - if ((i & 3) == 3) - printf ("\n"); - } -} - -PUBLIC void FFPU fpu_dump_flags(void) -{ - printf ("N=%d Z=%d I=%d NAN=%d\n", - (get_fpsr() & FPSR_CCB_NEGATIVE) != 0, - (get_fpsr() & FPSR_CCB_ZERO)!= 0, - (get_fpsr() & FPSR_CCB_INFINITY) != 0, - (get_fpsr() & FPSR_CCB_NAN) != 0); -} - -#include "debug.h" - -#if FPU_DEBUG -#undef __inline__ -#define __inline__ - -PRIVATE void FFPU dump_first_bytes_buf(char *b, uae_u8* buf, uae_s32 actual) -{ - char bb[10]; - int32 i, bytes = min(actual,100); - - *b = 0; - for (i=0; i= 10) _ix = 0; - - sprintf( _s[_ix], "%.04f", (float)f ); - return( _s[_ix] ); -} - -PUBLIC void FFPU dump_registers(const char *s) -{ - char b[512]; - - sprintf( - b, - "%s: %s, %s, %s, %s, %s, %s, %s, %s\r\n", - s, - etos(FPU registers[0]), - etos(FPU registers[1]), - etos(FPU registers[2]), - etos(FPU registers[3]), - etos(FPU registers[4]), - etos(FPU registers[5]), - etos(FPU registers[6]), - etos(FPU registers[7]) - ); - D(bug((char*)b)); -} - -#else - -PUBLIC void FFPU dump_registers(const char *) -{ -} - -PUBLIC void FFPU dump_first_bytes(uae_u8 *, uae_s32) -{ -} - -#endif - - -/* ---------------------------- FPU consistency ---------------------------- */ - -#if USE_CONSISTENCY_CHECKING -PRIVATE void FFPU FPU_CONSISTENCY_CHECK_START(void) -{ -/* _asm { - FNSTSW checked_sw_atstart - } */ - __asm__ __volatile__("fnstsw %0" : "=m" (checked_sw_atstart)); -} - -PRIVATE void FFPU FPU_CONSISTENCY_CHECK_STOP(const char *name) -{ - uae_u16 checked_sw_atend; -// _asm FNSTSW checked_sw_atend - __asm__ __volatile__("fnstsw %0" : "=m" (checked_sw_attend)); - char msg[256]; - - // Check for FPU stack overflows/underflows. - if( (checked_sw_atend & 0x3800) != (checked_sw_atstart & 0x3800) ) { - wsprintf( - msg, - "FPU stack leak at %s, %X, %X\r\n", - name, - (int)(checked_sw_atstart & 0x3800) >> 11, - (int)(checked_sw_atend & 0x3800) >> 11 - ); - OutputDebugString(msg); - } - - // Observe status mapping. - /* - if(checked_sw_atstart != 0x400 || checked_sw_atend != 0x400) { - wsprintf( - msg, "Op %s, x86_status_word before=%X, x86_status_word after=%X\r\n", - name, (int)checked_sw_atstart, (int)checked_sw_atend - ); - OutputDebugString(msg); - } - */ -} -#else -PRIVATE void FFPU FPU_CONSISTENCY_CHECK_START(void) -{ -} - -PRIVATE void FFPU FPU_CONSISTENCY_CHECK_STOP(const char *) -{ -} -#endif - - -/* ---------------------------- Status byte ---------------------------- */ - -// Map x86 FXAM codes -> m68k fpu status byte -#define SW_Z_I_NAN_MASK (SW_C0|SW_C2|SW_C3) -#define SW_Z (SW_C3) -#define SW_I (SW_C0|SW_C2) -#define SW_NAN (SW_C0) -#define SW_FINITE (SW_C2) -#define SW_EMPTY_REGISTER (SW_C0|SW_C3) -#define SW_DENORMAL (SW_C2|SW_C3) -#define SW_UNSUPPORTED (0) -#define SW_N (SW_C1) - -// Initial state after boot, reset and frestore(null frame) -#define SW_INITIAL SW_FINITE - - -/* ---------------------------- Status functions ---------------------------- */ - -PRIVATE void __inline__ FFPU SET_BSUN_ON_NAN () -{ - if( (x86_status_word & (SW_Z_I_NAN_MASK)) == SW_NAN ) { - x86_status_word |= SW_FAKE_BSUN; - x86_status_word_accrued |= SW_IE; - } -} - -PRIVATE void __inline__ FFPU build_ex_status () -{ - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word_accrued |= x86_status_word; - } -} - -// TODO_BIGENDIAN; all of these. -/* ---------------------------- Type functions ---------------------------- */ - -/* -When the FPU creates a NAN, the NAN always contains the same bit pattern -in the mantissa. All bits of the mantissa are ones for any precision. -When the user creates a NAN, any nonzero bit pattern can be stored in the mantissa. -*/ -PRIVATE __inline__ void FFPU MAKE_NAN (fpu_register & f) -{ - // Make it non-signaling. - uae_u8 * p = (uae_u8 *) &f; - memset( p, 0xFF, sizeof(fpu_register) - 1 ); - p[9] = 0x7F; -} - -/* -For single- and double-precision infinities the fraction is a zero. -For extended-precision infinities, the mantissa’s MSB, the explicit -integer bit, can be either one or zero. -*/ -PRIVATE __inline__ uae_u32 FFPU IS_INFINITY (fpu_register const & f) -{ - uae_u8 * p = (uae_u8 *) &f; - if( ((p[9] & 0x7F) == 0x7F) && p[8] == 0xFF ) { - if ((*((uae_u32 *)&p[0]) == 0) && - ((*((uae_u32 *)&p[4]) & 0x7FFFFFFF) == 0)) - return(1); - } - return(0); -} - -PRIVATE __inline__ uae_u32 FFPU IS_NAN (fpu_register const & f) -{ - uae_u8 * p = (uae_u8 *) &f; - if( ((p[9] & 0x7F) == 0x7F) && p[8] == 0xFF ) { - if ((*((uae_u32 *)&p[0]) == 0) && - ((*((uae_u32 *)&p[4]) & 0x7FFFFFFF) != 0)) - return(1); - } - return(0); -} - -PRIVATE __inline__ uae_u32 FFPU IS_ZERO (fpu_register const & f) -{ - uae_u8 * p = (uae_u8 *) &f; - return *((uae_u32 *)p) == 0 && - *((uae_u32 *)&p[4]) == 0 && - ( *((uae_u16 *)&p[8]) & 0x7FFF ) == 0; -} - -PRIVATE __inline__ void FFPU MAKE_INF_POSITIVE (fpu_register & f) -{ - uae_u8 * p = (uae_u8 *) &f; - memset( p, 0, sizeof(fpu_register)-2 ); - *((uae_u16 *)&p[8]) = 0x7FFF; -} - -PRIVATE __inline__ void FFPU MAKE_INF_NEGATIVE (fpu_register & f) -{ - uae_u8 * p = (uae_u8 *) &f; - memset( p, 0, sizeof(fpu_register)-2 ); - *((uae_u16 *)&p[8]) = 0xFFFF; -} - -PRIVATE __inline__ void FFPU MAKE_ZERO_POSITIVE (fpu_register & f) -{ - uae_u32 * const p = (uae_u32 *) &f; - memset( p, 0, sizeof(fpu_register) ); -} - -PRIVATE __inline__ void FFPU MAKE_ZERO_NEGATIVE (fpu_register & f) -{ - uae_u32 * const p = (uae_u32 *) &f; - memset( p, 0, sizeof(fpu_register) ); - *((uae_u32 *)&p[4]) = 0x80000000; -} - -PRIVATE __inline__ uae_u32 FFPU IS_NEGATIVE (fpu_register const & f) -{ - uae_u8 * p = (uae_u8 *) &f; - return( (p[9] & 0x80) != 0 ); -} - - -/* ---------------------------- Conversions ---------------------------- */ - -PRIVATE void FFPU signed_to_extended ( uae_s32 x, fpu_register & f ) -{ - FPU_CONSISTENCY_CHECK_START(); - -/* _asm { - MOV ESI, [f] - FILD DWORD PTR [x] - FSTP TBYTE PTR [ESI] - } */ - - __asm__ __volatile__("fildl %1\n\tfstpt %0" : "=m" (f) : "m" (x)); - D(bug("signed_to_extended (%X) = %s\r\n",(int)x,etos(f))); - FPU_CONSISTENCY_CHECK_STOP("signed_to_extended"); -} - -PRIVATE uae_s32 FFPU extended_to_signed_32 ( fpu_register const & f ) -{ - FPU_CONSISTENCY_CHECK_START(); - volatile uae_s32 tmp; - volatile WORD sw_temp; - -/* _asm { - MOV EDI, [f] - FLD TBYTE PTR [EDI] - FISTP DWORD PTR tmp - FNSTSW sw_temp - } */ - - __asm__ __volatile__( - "fldt %2\n" - "fistpl %0\n" - "fnstsw %1\n" - : "=m" (tmp), "=m" (sw_temp) - : "m" (f) - ); - - if(sw_temp & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR. - x86_status_word |= SW_IE; - x86_status_word_accrued |= SW_IE; - // Setting the value to zero might not be the right way to go, - // but I'll leave it like this for now. - tmp = 0; - } - if(sw_temp & SW_PE) { - x86_status_word |= SW_PE; - x86_status_word_accrued |= SW_PE; - } - } - - D(bug("extended_to_signed_32 (%s) = %X\r\n",etos(f),(int)tmp)); - FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_32"); - return tmp; -} - -PRIVATE uae_s16 FFPU extended_to_signed_16 ( fpu_register const & f ) -{ - FPU_CONSISTENCY_CHECK_START(); - volatile uae_s16 tmp; - volatile WORD sw_temp; - -/* _asm { - MOV EDI, [f] - FLD TBYTE PTR [EDI] - FISTP WORD PTR tmp - FNSTSW sw_temp - } */ - - __asm__ __volatile__( - "fldt %2\n" - "fistp %0\n" - "fnstsw %1\n" - : "=m" (tmp), "=m" (sw_temp) - : "m" (f) - ); - - if(sw_temp & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR. - x86_status_word |= SW_IE; - x86_status_word_accrued |= SW_IE; - tmp = 0; - } - if(sw_temp & SW_PE) { - x86_status_word |= SW_PE; - x86_status_word_accrued |= SW_PE; - } - } - - D(bug("extended_to_signed_16 (%s) = %X\r\n",etos(f),(int)tmp)); - FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_16"); - return tmp; -} - -PRIVATE uae_s8 FFPU extended_to_signed_8 ( fpu_register const & f ) -{ - FPU_CONSISTENCY_CHECK_START(); - volatile uae_s16 tmp; - volatile WORD sw_temp; - -/* _asm { - MOV EDI, [f] - FLD TBYTE PTR [EDI] - FISTP WORD PTR tmp - FNSTSW sw_temp - } */ - - __asm__ __volatile__( - "fldt %2\n" - "fistp %0\n" - "fnstsw %1\n" - : "=m" (tmp), "=m" (sw_temp) - : "m" (f) - ); - - if(sw_temp & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR. - x86_status_word |= SW_IE; - x86_status_word_accrued |= SW_IE; - tmp = 0; - } - if(sw_temp & SW_PE) { - x86_status_word |= SW_PE; - x86_status_word_accrued |= SW_PE; - } - } - - if(tmp > 127 || tmp < -128) { // OPERR - x86_status_word |= SW_IE; - x86_status_word_accrued |= SW_IE; - } - - D(bug("extended_to_signed_8 (%s) = %X\r\n",etos(f),(int)tmp)); - FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_8"); - return (uae_s8)tmp; -} - -PRIVATE void FFPU double_to_extended ( double x, fpu_register & f ) -{ - FPU_CONSISTENCY_CHECK_START(); - -/* _asm { - MOV EDI, [f] - FLD QWORD PTR [x] - FSTP TBYTE PTR [EDI] - } */ - - __asm__ __volatile__( - "fldl %1\n" - "fstpt %0\n" - : "=m" (f) - : "m" (x) - ); - - FPU_CONSISTENCY_CHECK_STOP("double_to_extended"); -} - -PRIVATE fpu_double FFPU extended_to_double( fpu_register const & f ) -{ - FPU_CONSISTENCY_CHECK_START(); - double result; - -/* _asm { - MOV ESI, [f] - FLD TBYTE PTR [ESI] - FSTP QWORD PTR result - } */ - - __asm__ __volatile__( - "fldt %1\n" - "fstpl %0\n" - : "=m" (result) - : "m" (f) - ); - - FPU_CONSISTENCY_CHECK_STOP("extended_to_double"); - return result; -} - -PRIVATE void FFPU to_single ( uae_u32 src, fpu_register & f ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [f] - FLD DWORD PTR src - FSTP TBYTE PTR [ESI] - } */ - - __asm__ __volatile__( - "flds %1\n" - "fstpt %0\n" - : "=m" (f) - : "m" (src) - ); - - D(bug("to_single (%X) = %s\r\n",src,etos(f))); - FPU_CONSISTENCY_CHECK_STOP("to_single"); -} - -// TODO_BIGENDIAN -PRIVATE void FFPU to_exten_no_normalize ( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & f ) -{ - FPU_CONSISTENCY_CHECK_START(); - uae_u32 *p = (uae_u32 *)&f; - - uae_u32 sign = (wrd1 & 0x80000000) >> 16; - uae_u32 exp = (wrd1 >> 16) & 0x7fff; - p[0] = wrd3; - p[1] = wrd2; - *((uae_u16 *)&p[2]) = (uae_u16)(sign | exp); - - D(bug("to_exten_no_normalize (%X,%X,%X) = %s\r\n",wrd1,wrd2,wrd3,etos(f))); - FPU_CONSISTENCY_CHECK_STOP("to_exten_no_normalize"); -} - -PRIVATE void FFPU to_exten ( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & f ) -{ - FPU_CONSISTENCY_CHECK_START(); - uae_u32 *p = (uae_u32 *)&f; - - uae_u32 sign = (wrd1 & 0x80000000) >> 16; - uae_u32 exp = (wrd1 >> 16) & 0x7fff; - - // The explicit integer bit is not set, must normalize. - // Don't do it for zeroes, infinities or nans. - if( (wrd2 & 0x80000000) == 0 && exp != 0 && exp != 0x7FFF ) { - D(bug("to_exten denormalized mantissa (%X,%X,%X)\r\n",wrd1,wrd2,wrd3)); - if( wrd2 | wrd3 ) { - // mantissa, not fraction. - uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3; - while( exp > 0 && (man & UVAL64(0x8000000000000000)) == 0 ) { - man <<= 1; - exp--; - } - wrd2 = (uae_u32)( man >> 32 ); - wrd3 = (uae_u32)( man & 0xFFFFFFFF ); - if( exp == 0 || (wrd2 & 0x80000000) == 0 ) { - // underflow - wrd2 = wrd3 = exp = 0; - sign = 0; - } - } else { - if(exp != 0x7FFF && exp != 0) { - // Make a non-signaling nan. - exp = 0x7FFF; - sign = 0; - wrd2 = 0x80000000; - } - } - } - - p[0] = wrd3; - p[1] = wrd2; - *((uae_u16 *)&p[2]) = (uae_u16)(sign | exp); - - D(bug("to_exten (%X,%X,%X) = %s\r\n",wrd1,wrd2,wrd3,etos(f))); - FPU_CONSISTENCY_CHECK_STOP("to_exten"); -} - -PRIVATE void FFPU to_double ( uae_u32 wrd1, uae_u32 wrd2, fpu_register & f ) -{ - FPU_CONSISTENCY_CHECK_START(); - - // gb-- make GCC happy - union { - uae_u64 q; - uae_u32 l[2]; - } src; - - // Should renormalize if needed. I'm not sure that x86 and m68k FPU's - // do it the sama way. This should be extremely rare however. - // to_exten() is often called with denormalized values. - - src.l[0] = wrd2; - src.l[1] = wrd1; - -/* _asm { - FLD QWORD PTR src - MOV EDI, [f] - FSTP TBYTE PTR [EDI] - } */ - - __asm__ __volatile__( - "fldl %1\n" - "fstpt %0\n" - : "=m" (f) - : "m" (src.q) - ); - - D(bug("to_double (%X,%X) = %s\r\n",wrd1,wrd2,etos(f))); - FPU_CONSISTENCY_CHECK_STOP("to_double"); -} - -PRIVATE uae_u32 FFPU from_single ( fpu_register const & f ) -{ - FPU_CONSISTENCY_CHECK_START(); - volatile uae_u32 dest; - volatile WORD sw_temp; - -/* _asm { - MOV EDI, [f] - FLD TBYTE PTR [EDI] - FSTP DWORD PTR dest - FNSTSW sw_temp - } */ - - __asm__ __volatile__( - "fldt %2\n" - "fstps %0\n" - "fnstsw %1\n" - : "=m" (dest), "=m" (sw_temp) - : "m" (f) - ); - - sw_temp &= SW_EXCEPTION_MASK; - if(sw_temp) { -// _asm FNCLEX - asm("fnclex"); - x86_status_word = (x86_status_word & ~SW_EXCEPTION_MASK) | sw_temp; - x86_status_word_accrued |= sw_temp; - } - - D(bug("from_single (%s) = %X\r\n",etos(f),dest)); - FPU_CONSISTENCY_CHECK_STOP("from_single"); - return dest; -} - -// TODO_BIGENDIAN -PRIVATE void FFPU from_exten ( fpu_register const & f, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3 ) -{ - FPU_CONSISTENCY_CHECK_START(); - uae_u32 *p = (uae_u32 *)&f; - *wrd3 = p[0]; - *wrd2 = p[1]; - *wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16; - - D(bug("from_exten (%s) = %X,%X,%X\r\n",etos(f),*wrd1,*wrd2,*wrd3)); - FPU_CONSISTENCY_CHECK_STOP("from_exten"); -} - -PRIVATE void FFPU from_double ( fpu_register const & f, uae_u32 *wrd1, uae_u32 *wrd2 ) -{ - FPU_CONSISTENCY_CHECK_START(); - volatile uae_u32 dest[2]; - volatile WORD sw_temp; - -/* _asm { - MOV EDI, [f] - FLD TBYTE PTR [EDI] - FSTP QWORD PTR dest - FNSTSW sw_temp - } */ - - __asm__ __volatile__( - "fldt %2\n" - "fstpl %0\n" - "fnstsw %1\n" - : "=m" (dest), "=m" (sw_temp) - : "m" (f) - ); - - sw_temp &= SW_EXCEPTION_MASK; - if(sw_temp) { -// _asm FNCLEX - asm("fnclex"); - x86_status_word = (x86_status_word & ~SW_EXCEPTION_MASK) | sw_temp; - x86_status_word_accrued |= sw_temp; - } - - // TODO: There is a partial memory stall, nothing happens until FSTP retires. - // On PIII, could use MMX move w/o any penalty. - *wrd2 = dest[0]; - *wrd1 = dest[1]; - - D(bug("from_double (%s) = %X,%X\r\n",etos(f),dest[1],dest[0])); - FPU_CONSISTENCY_CHECK_STOP("from_double"); -} - -PRIVATE void FFPU do_fmove ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - } */ - - __asm__ __volatile__( - "fldt %2\n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - : "m" (src) - ); - FPU_CONSISTENCY_CHECK_STOP("do_fmove"); -} - -/* -PRIVATE void FFPU do_fmove_no_status ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FSTP TBYTE PTR [EDI] - } - FPU_CONSISTENCY_CHECK_STOP("do_fmove_no_status"); -} -*/ - - -/* ---------------------------- Operations ---------------------------- */ - -PRIVATE void FFPU do_fint ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FRNDINT - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldt %2\n" - "frndint\n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_PE); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fint"); -} - -PRIVATE void FFPU do_fintrz ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - WORD cw_temp; - -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FSTCW cw_temp - and cw_temp, ~X86_ROUNDING_MODE - or cw_temp, CW_RC_ZERO - FLDCW cw_temp - FLD TBYTE PTR [ESI] - FRNDINT - FXAM - FNSTSW x86_status_word - FLDCW x86_control_word - FSTP TBYTE PTR [EDI] - } */ - - __asm__ __volatile__( - "fstcw %0\n" - "andl $(~X86_ROUNDING_MODE), %0\n" - "orl $CW_RC_ZERO, %0\n" - "fldcw %0\n" - "fldt %3\n" - "frndint\n" - "fxam \n" - "fnstsw %1\n" - "fldcw %4\n" - "fstpt %2\n" - : "+m" (cw_temp), "=m" (x86_status_word), "=m" (dest) - : "m" (src), "m" (x86_control_word) - ); - - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_PE); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fintrz"); -} - -PRIVATE void FFPU do_fsqrt ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FSQRT - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - } */ - - __asm__ __volatile__( - "fldt %2\n" - "fsqrt \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - : "m" (src) - ); - - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fsqrt"); -} - -PRIVATE void FFPU do_ftst ( fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - FLD TBYTE PTR [ESI] - FXAM - FNSTSW x86_status_word - FSTP ST(0) - } */ - - __asm__ __volatile__( - "fldt %1\n" - "fxam \n" - "fnstsw %0\n" - "fstp %%st(0)\n" - : "=m" (x86_status_word) - : "m" (src) - ); - - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~SW_EXCEPTION_MASK; - } - FPU_CONSISTENCY_CHECK_STOP("do_ftst"); -} - -// These functions are calculated in 53 bits accuracy only. -// Exception checking is not complete. -PRIVATE void FFPU do_fsinh ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = sinh(x); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_fsinh"); -} - -PRIVATE void FFPU do_flognp1 ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = log (x + 1.0); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_flognp1"); -} - -PRIVATE void FFPU do_fetoxm1 ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = exp (x) - 1.0; - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_fetoxm1"); -} - -PRIVATE void FFPU do_ftanh ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = tanh (x); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_ftanh"); -} - -PRIVATE void FFPU do_fatan ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = atan (x); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_fatan"); -} - -PRIVATE void FFPU do_fasin ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = asin (x); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_fasin"); -} - -PRIVATE void FFPU do_fatanh ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = log ((1 + x) / (1 - x)) / 2; - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_fatanh"); -} - -PRIVATE void FFPU do_fetox ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = exp (x); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_fetox"); -} - -PRIVATE void FFPU do_ftwotox ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = pow(2.0, x); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_ftwotox"); -} - -PRIVATE void FFPU do_ftentox ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = pow(10.0, x); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_ftentox"); -} - -PRIVATE void FFPU do_flogn ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = log (x); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_flogn"); -} - -PRIVATE void FFPU do_flog10 ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = log10 (x); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_flog10"); -} - -PRIVATE void FFPU do_flog2 ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = log (x) / log (2.0); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_flog2"); -} - -PRIVATE void FFPU do_facos ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = acos(x); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_facos"); -} - -PRIVATE void FFPU do_fcosh ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - double x, y; - x = extended_to_double( src ); - y = cosh(x); - double_to_extended( y, dest ); - do_ftst( dest ); - FPU_CONSISTENCY_CHECK_STOP("do_fcosh"); -} - -PRIVATE void FFPU do_fsin ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FSIN - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldt %2\n" - "fsin \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fsin"); -} - -// TODO: Should check for out-of-range condition (partial tangent) -PRIVATE void FFPU do_ftan ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FPTAN - FSTP ST(0) ; pop 1.0 (the 8087/287 compatibility thing) - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldt %2\n" - "fptan \n" - "fstp %%st(0)\n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE - SW_UE); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_ftan"); -} - -PRIVATE void FFPU do_fabs ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FABS - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldt %2\n" - "fabs \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - : "m" (src) - ); - // x86 fabs should not rise any exceptions (except stack underflow) - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~SW_EXCEPTION_MASK; - } - FPU_CONSISTENCY_CHECK_STOP("do_fabs"); -} - -PRIVATE void FFPU do_fneg ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FCHS - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldt %2\n" - "fchs \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - : "m" (src) - ); - // x86 fchs should not rise any exceptions (except stack underflow) - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~SW_EXCEPTION_MASK; - } - FPU_CONSISTENCY_CHECK_STOP("do_fneg"); -} - -PRIVATE void FFPU do_fcos ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FCOS - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldt %2\n" - "fcos \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fcos"); -} - -PRIVATE void FFPU do_fgetexp ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FXTRACT - FSTP ST(0) ; pop mantissa - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldt %2\n" - "fxtract\n" - "fstp %%st(0)\n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~SW_EXCEPTION_MASK; - } - FPU_CONSISTENCY_CHECK_STOP("do_fgetexp"); -} - -PRIVATE void FFPU do_fgetman ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FXTRACT - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - FSTP ST(0) ; pop exponent - } */ - __asm__ __volatile__( - "fldt %2\n" - "fxtract\n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - "fstp %%st(0)\n" - : "=m" (x86_status_word), "=m" (dest) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~SW_EXCEPTION_MASK; - } - FPU_CONSISTENCY_CHECK_STOP("do_fgetman"); -} - -PRIVATE void FFPU do_fdiv ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FDIV ST(0),ST(1) - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - FSTP ST(0) - } */ - __asm__ __volatile__( - "fldt %2\n" - "fldt %1\n" - "fdiv %%st(1), %%st(0)\n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - "fstp %%st(0)\n" - : "=m" (x86_status_word), "+m" (dest) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fdiv"); -} - -// The sign of the quotient is the exclusive-OR of the sign bits -// of the source and destination operands. -// Quotient Byte is loaded with the sign and least significant -// seven bits of the quotient. - -PRIVATE void FFPU do_fmod ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - - volatile uint16 status; - uae_u32 quot; -#if !USE_3_BIT_QUOTIENT - WORD cw_temp; -#endif - - uae_u8 * dest_p = (uae_u8 *)&dest; - uae_u8 * src_p = (uae_u8 *)&src; - uae_u32 sign = (dest_p[9] ^ src_p[9]) & 0x80; - -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - -#if !USE_3_BIT_QUOTIENT - MOV CX, x86_control_word - AND CX, ~X86_ROUNDING_MODE - OR CX, CW_RC_ZERO - MOV cw_temp, CX - FLDCW cw_temp - - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FDIV ST(0),ST(1) - FABS - FISTP DWORD PTR quot - FSTP ST(0) - FLDCW x86_control_word - // TODO:Quotient - // Should clear any possible exceptions here -#endif - - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - -// loop until the remainder is not partial any more. -partial_loop: - FPREM - FNSTSW status - TEST status, SW_C2 - JNE partial_loop - - - FXAM - FNSTSW x86_status_word - - FSTP TBYTE PTR [EDI] - FSTP ST(0) - } */ - -#if !USE_3_BIT_QUOTIENT - - __asm__ __volatile__( - "movl %6, %%ecx\n" // %6: x86_control_word (read) - "andl $(~X86_ROUNDING_MODE), %%ecx\n" - "orl $CW_RC_ZERO, %%ecx\n" - "movl %%ecx, %0\n" // %0: cw_temp (read/write) - "fldcw %0\n" - "fldt %5\n" - "fldt %4\n" - "fdiv %%st(1), %%st(0)\n" - "fabs \n" - "fistpl %1\n" // %1: quot (read/write) - "fstp %%st(0)\n" - "fldcw %6\n" - "fldt %5\n" - "fldt %4\n" - "0:\n" // partial_loop - "fprem \n" - "fnstsw %2\n" // %2: status (read/write) - "testl $SW_C2, %2\n" - "jne 0b\n" - "fxam \n" - "fnstsw %3\n" // %3: x86_status_word (write) - "fstpt %4\n" - "fstp %%st(0)\n" - : "+m" (cw_temp), "+m" (quot), "+m" (status), "=m" (x86_status_word), "+m" (dest) - : "m" (src), "m" (x86_control_word) - : "ecx" - ); - -#else - - __asm__ __volatile__( - "fldt %3\n" - "fldt %2\n" - "0:\n" // partial_loop - "fprem \n" - "fnstsw %0\n" // %0: status (read/write) - "testl $SW_C2, %0\n" - "jne 0b\n" - "fxam \n" - "fnstsw %1\n" // %1: x86_status_word (write) - "fstpt %2\n" - "fstp %%st(0)\n" - : "+m" (status), "=m" (x86_status_word), "+m" (dest) - : "m" (src) - ); - -#endif - - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE); - x86_status_word_accrued |= x86_status_word; - } - -#if USE_3_BIT_QUOTIENT - // SW_C1 Set to least significant bit of quotient (Q0). - // SW_C3 Set to bit 1 (Q1) of the quotient. - // SW_C0 Set to bit 2 (Q2) of the quotient. - quot = ((status & SW_C0) >> 6) | ((status & SW_C3) >> 13) | ((status & SW_C1) >> 9); - FPU fpsr.quotient = (sign | quot) << 16; -#else - FPU fpsr.quotient = (sign | (quot&0x7F)) << 16; -#endif - - FPU_CONSISTENCY_CHECK_STOP("do_fmod"); -} - -PRIVATE void FFPU do_frem ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - - volatile uint16 status; - uae_u32 quot; -#if !USE_3_BIT_QUOTIENT - WORD cw_temp; -#endif - - uae_u8 * dest_p = (uae_u8 *)&dest; - uae_u8 * src_p = (uae_u8 *)&src; - uae_u32 sign = (dest_p[9] ^ src_p[9]) & 0x80; - -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - -#if !USE_3_BIT_QUOTIENT - MOV CX, x86_control_word - AND CX, ~X86_ROUNDING_MODE - OR CX, CW_RC_NEAR - MOV cw_temp, CX - FLDCW cw_temp - - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FDIV ST(0),ST(1) - FABS - FISTP DWORD PTR quot - FSTP ST(0) - FLDCW x86_control_word - // TODO:Quotient - // Should clear any possible exceptions here -#endif - - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - -// loop until the remainder is not partial any more. -partial_loop: - FPREM1 - FNSTSW status - TEST status, SW_C2 - JNE partial_loop - - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - FSTP ST(0) - } */ - -#if !USE_3_BIT_QUOTIENT - - __asm__ __volatile__( - "movl %6, %%ecx\n" // %6: x86_control_word (read) - "andl $(~X86_ROUNDING_MODE), %%ecx\n" - "orl $CW_RC_NEAR, %%ecx\n" - "movl %%ecx, %0\n" // %0: cw_temp (read/write) - "fldcw %0\n" - "fldt %5\n" - "fldt %4\n" - "fdiv %%st(1), %%st(0)\n" - "fabs \n" - "fistpl %1\n" // %1: quot (read/write) - "fstp %%st(0)\n" - "fldcw %6\n" - "fldt %5\n" - "fldt %4\n" - "0:\n" // partial_loop - "fprem1 \n" - "fnstsw %2\n" // %2: status (read/write) - "testl $SW_C2, %2\n" - "jne 0b\n" - "fxam \n" - "fnstsw %3\n" // %3: x86_status_word (write) - "fstpt %4\n" - "fstp %%st(0)\n" - : "+m" (cw_temp), "+m" (quot), "+m" (status), "=m" (x86_status_word), "+m" (dest) - : "m" (src), "m" (x86_control_word) - : "ecx" - ); - -#else - - __asm__ __volatile__( - "fldt %3\n" - "fldt %2\n" - "0:\n" // partial_loop - "fprem1 \n" - "fnstsw %0\n" // %0: status (read/write) - "testl $SW_C2, %0\n" - "jne 0b\n" - "fxam \n" - "fnstsw %1\n" // %1: x86_status_word (write) - "fstpt %2\n" - "fstp %%st(0)\n" - : "+m" (status), "=m" (x86_status_word), "+m" (dest) - : "m" (src) - ); - -#endif - - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE); - x86_status_word_accrued |= x86_status_word; - } - -#if USE_3_BIT_QUOTIENT - // SW_C1 Set to least significant bit of quotient (Q0). - // SW_C3 Set to bit 1 (Q1) of the quotient. - // SW_C0 Set to bit 2 (Q2) of the quotient. - quot = ((status & SW_C0) >> 6) | ((status & SW_C3) >> 13) | ((status & SW_C1) >> 9); - FPU fpsr.quotient = (sign | quot) << 16; -#else - FPU fpsr.quotient = (sign | (quot&0x7F)) << 16; -#endif - - FPU_CONSISTENCY_CHECK_STOP("do_frem"); -} - -// Faster versions. The current rounding mode is already correct. -#if !USE_3_BIT_QUOTIENT -PRIVATE void FFPU do_fmod_dont_set_cw ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - - volatile uint16 status; - uae_u32 quot; - - uae_u8 * dest_p = (uae_u8 *)&dest; - uae_u8 * src_p = (uae_u8 *)&src; - uae_u32 sign = (dest_p[9] ^ src_p[9]) & 0x80; - - _asm { - MOV ESI, [src] - MOV EDI, [dest] - - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FDIV ST(0),ST(1) - FABS - FISTP DWORD PTR quot - FSTP ST(0) - // TODO:Quotient - // Should clear any possible exceptions here - - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - -// loop until the remainder is not partial any more. -partial_loop: - FPREM - FNSTSW status - TEST status, SW_C2 - JNE partial_loop - - FXAM - FNSTSW x86_status_word - - FSTP TBYTE PTR [EDI] - FSTP ST(0) - } - if(x86_status_word & SW_EXCEPTION_MASK) { - _asm FNCLEX - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE); - x86_status_word_accrued |= x86_status_word; - } - FPU fpsr.quotient = (sign | (quot&0x7F)) << 16; - FPU_CONSISTENCY_CHECK_STOP("do_fmod_dont_set_cw"); -} - -PRIVATE void FFPU do_frem_dont_set_cw ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - - volatile uint16 status; - uae_u32 quot; - - uae_u8 * dest_p = (uae_u8 *)&dest; - uae_u8 * src_p = (uae_u8 *)&src; - uae_u32 sign = (dest_p[9] ^ src_p[9]) & 0x80; - - _asm { - MOV ESI, [src] - MOV EDI, [dest] - - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FDIV ST(0),ST(1) - FABS - FISTP DWORD PTR quot - FSTP ST(0) - // TODO:Quotient - // Should clear any possible exceptions here - - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - -// loop until the remainder is not partial any more. -partial_loop: - FPREM1 - FNSTSW status - TEST status, SW_C2 - JNE partial_loop - - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - FSTP ST(0) - } - if(x86_status_word & SW_EXCEPTION_MASK) { - _asm FNCLEX - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE); - x86_status_word_accrued |= x86_status_word; - } - FPU fpsr.quotient = (sign | (quot&0x7F)) << 16; - FPU_CONSISTENCY_CHECK_STOP("do_frem_dont_set_cw"); -} -#endif //USE_3_BIT_QUOTIENT - -PRIVATE void FFPU do_fadd ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FADD - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldt %2\n" - "fldt %1\n" - "fadd \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "+m" (dest) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fadd"); -} - -PRIVATE void FFPU do_fmul ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FMUL - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldt %2\n" - "fldt %1\n" - "fmul \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "+m" (dest) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fmul"); -} - -PRIVATE void FFPU do_fsgldiv ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - WORD cw_temp; -/* _asm { - FSTCW cw_temp - and cw_temp, ~X86_ROUNDING_PRECISION - or cw_temp, PRECISION_CONTROL_SINGLE - FLDCW cw_temp - - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FDIV ST(0),ST(1) - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - FSTP ST(0) - FLDCW x86_control_word - } */ - __asm__ __volatile__( - "fstcw %0\n" - "andl $(~X86_ROUNDING_PRECISION), %0\n" - "orl $PRECISION_CONTROL_SINGLE, %0\n" - "fldcw %0\n" - "fldt %3\n" - "fldt %2\n" - "fdiv %%st(1), %%st(0)\n" - "fxam \n" - "fnstsw %1\n" - "fstpt %2\n" - "fstp %%st(0)\n" - "fldcw %4\n" - : "+m" (cw_temp), "=m" (x86_status_word), "+m" (dest) - : "m" (src), "m" (x86_control_word) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fsgldiv"); -} - -PRIVATE void FFPU do_fscale ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FSCALE - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - FSTP ST(0) - } */ - __asm__ __volatile__( - "fldt %2\n" - "fldt %1\n" - "fscale \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - "fstp %%st(0)\n" - : "=m" (x86_status_word), "+m" (dest) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_UE - SW_OE); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fscale"); -} - -PRIVATE void FFPU do_fsglmul ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); - WORD cw_temp; - -/* _asm { - FSTCW cw_temp - and cw_temp, ~X86_ROUNDING_PRECISION - or cw_temp, PRECISION_CONTROL_SINGLE - FLDCW cw_temp - - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FMUL - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - - FLDCW x86_control_word - } */ - __asm__ __volatile__( - "fstcw %0\n" - "andl $(~X86_ROUNDING_PRECISION), %0\n" - "orl $PRECISION_CONTROL_SINGLE, %0\n" - "fldcw %0\n" - "fldt %3\n" - "fldt %2\n" - "fmul \n" - "fxam \n" - "fnstsw %1\n" - "fstpt %2\n" - "fldcw %4\n" - : "+m" (cw_temp), "=m" (x86_status_word), "+m" (dest) - : "m" (src), "m" (x86_status_word) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fsglmul"); -} - -PRIVATE void FFPU do_fsub ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FSUB ST(0),ST(1) - FXAM - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - FSTP ST(0) - } */ - __asm__ __volatile__( - "fldt %2\n" - "fldt %1\n" - "fsub %%st(1), %%st(0)\n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - "fstp %%st(0)\n" - : "=m" (x86_status_word), "+m" (dest) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fsub"); -} - -PRIVATE void FFPU do_fsincos ( fpu_register & dest_sin, fpu_register & dest_cos, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest_cos] - FLD TBYTE PTR [ESI] - FSINCOS - FSTP TBYTE PTR [EDI] - FXAM - MOV EDI, [dest_sin] - FNSTSW x86_status_word - FSTP TBYTE PTR [EDI] - FSTP ST(0) - } */ - __asm__ __volatile__( - "fldt %3\n" - "fsincos\n" - "fstpt %1\n" - "fxam \n" - "fnstsw %0\n" - "fstpt %2\n" - "fstp %%st(0)\n" - : "=m" (x86_status_word), "=m" (dest_cos), "=m" (dest_sin) - : "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_PE); - x86_status_word_accrued |= x86_status_word; - } - FPU_CONSISTENCY_CHECK_STOP("do_fsincos"); -} - -PRIVATE void FFPU do_fcmp ( fpu_register & dest, fpu_register const & src ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - MOV ESI, [src] - MOV EDI, [dest] - FLD TBYTE PTR [ESI] - FLD TBYTE PTR [EDI] - FSUB ST(0),ST(1) - FXAM - FNSTSW x86_status_word - FSTP ST(0) - FSTP ST(0) - } */ - __asm__ __volatile__( - "fldt %2\n" - "fldt %1\n" - "fsub %%st(1), %%st(0)\n" - "fxam \n" - "fnstsw %0\n" - "fstp %%st(0)\n" - "fstp %%st(0)\n" - : "=m" (x86_status_word) - : "m" (dest), "m" (src) - ); - if(x86_status_word & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - x86_status_word &= ~SW_EXCEPTION_MASK; - } - FPU_CONSISTENCY_CHECK_STOP("do_fcmp"); -} - -// More or less original. Should be reviewed. -PRIVATE fpu_double FFPU to_pack(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) -{ - FPU_CONSISTENCY_CHECK_START(); - - double d; - char *cp; - char str[100]; - - cp = str; - if (wrd1 & 0x80000000) - *cp++ = '-'; - *cp++ = (char)((wrd1 & 0xf) + '0'); - *cp++ = '.'; - *cp++ = (char)(((wrd2 >> 28) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 24) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 20) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 16) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 12) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 8) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 4) & 0xf) + '0'); - *cp++ = (char)(((wrd2 >> 0) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 28) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 24) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 20) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 16) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 12) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 8) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 4) & 0xf) + '0'); - *cp++ = (char)(((wrd3 >> 0) & 0xf) + '0'); - *cp++ = 'E'; - if (wrd1 & 0x40000000) - *cp++ = '-'; - *cp++ = (char)(((wrd1 >> 24) & 0xf) + '0'); - *cp++ = (char)(((wrd1 >> 20) & 0xf) + '0'); - *cp++ = (char)(((wrd1 >> 16) & 0xf) + '0'); - *cp = 0; - sscanf(str, "%le", &d); - - D(bug("to_pack str = %s\r\n",str)); - - D(bug("to_pack(%X,%X,%X) = %.04f\r\n",wrd1,wrd2,wrd3,(float)d)); - - FPU_CONSISTENCY_CHECK_STOP("to_pack"); - - return d; -} - -// More or less original. Should be reviewed. -PRIVATE void FFPU from_pack (fpu_double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) -{ - FPU_CONSISTENCY_CHECK_START(); - - int i; - int t; - char *cp; - char str[100]; - int exponent_digit_count = 0; - - sprintf(str, "%.16e", src); - - D(bug("from_pack(%.04f,%s)\r\n",(float)src,str)); - - cp = str; - *wrd1 = *wrd2 = *wrd3 = 0; - if (*cp == '-') { - cp++; - *wrd1 = 0x80000000; - } - if (*cp == '+') - cp++; - *wrd1 |= (*cp++ - '0'); - if (*cp == '.') - cp++; - for (i = 0; i < 8; i++) { - *wrd2 <<= 4; - if (*cp >= '0' && *cp <= '9') - *wrd2 |= *cp++ - '0'; - } - for (i = 0; i < 8; i++) { - *wrd3 <<= 4; - if (*cp >= '0' && *cp <= '9') - *wrd3 |= *cp++ - '0'; - } - if (*cp == 'e' || *cp == 'E') { - cp++; - if (*cp == '-') { - cp++; - *wrd1 |= 0x40000000; - } - if (*cp == '+') - cp++; - t = 0; - for (i = 0; i < 3; i++) { - if (*cp >= '0' && *cp <= '9') { - t = (t << 4) | (*cp++ - '0'); - exponent_digit_count++; - } - } - *wrd1 |= t << 16; - } - - D(bug("from_pack(%.04f) = %X,%X,%X\r\n",(float)src,*wrd1,*wrd2,*wrd3)); - - WORD sw_temp; -// _asm FNSTSW sw_temp - __asm__ __volatile__("fnstsw %0" : "=m" (sw_temp)); - if(sw_temp & SW_EXCEPTION_MASK) { -// _asm FNCLEX - __asm__ __volatile__("fnclex"); - if(sw_temp & SW_PE) { - x86_status_word |= SW_PE; - x86_status_word_accrued |= SW_PE; - } - } - - /* - OPERR is set if the k-factor > + 17 or the magnitude of - the decimal exponent exceeds three digits; - cleared otherwise. - */ - if(exponent_digit_count > 3) { - x86_status_word |= SW_IE; - x86_status_word_accrued |= SW_IE; - } - - FPU_CONSISTENCY_CHECK_STOP("from_pack"); -} - -PRIVATE int FFPU get_fp_value (uae_u32 opcode, uae_u32 extra, fpu_register & src) -{ - static const int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; - static const int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; - - // D(bug("get_fp_value(%X,%X)\r\n",(int)opcode,(int)extra)); - // dump_first_bytes( regs.pc_p-4, 16 ); - - if ((extra & 0x4000) == 0) { - memcpy( &src, &FPU registers[(extra >> 10) & 7], sizeof(fpu_register) ); -// do_fmove_no_status( src, FPU registers[(extra >> 10) & 7] ); - return 1; - } - - int mode = (opcode >> 3) & 7; - int reg = opcode & 7; - int size = (extra >> 10) & 7; - uae_u32 ad = 0; - - // D(bug("get_fp_value mode=%d, reg=%d, size=%d\r\n",(int)mode,(int)reg,(int)size)); - - switch ((uae_u8)mode) { - case 0: - switch ((uae_u8)size) { - case 6: - signed_to_extended( (uae_s32)(uae_s8) m68k_dreg (regs, reg), src ); - break; - case 4: - signed_to_extended( (uae_s32)(uae_s16) m68k_dreg (regs, reg), src ); - break; - case 0: - signed_to_extended( (uae_s32) m68k_dreg (regs, reg), src ); - break; - case 1: - to_single( m68k_dreg (regs, reg), src ); - break; - default: - return 0; - } - return 1; - case 1: - return 0; - case 2: - ad = m68k_areg (regs, reg); - break; - case 3: - ad = m68k_areg (regs, reg); - m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; - break; - case 4: - m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; - ad = m68k_areg (regs, reg); - break; - case 5: - ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); - break; - case 6: - ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); - break; - case 7: - switch ((uae_u8)reg) { - case 0: - ad = (uae_s32) (uae_s16) next_iword(); - break; - case 1: - ad = next_ilong(); - break; - case 2: - ad = m68k_getpc (); - ad += (uae_s32) (uae_s16) next_iword(); - break; - case 3: { - uaecptr tmppc = m68k_getpc (); - uae_u16 tmp = (uae_u16)next_iword(); - ad = get_disp_ea_020 (tmppc, tmp); - } - break; - case 4: - ad = m68k_getpc (); - m68k_setpc (ad + sz2[size]); - - /* - +0000 000004 FSCALE.B #$01,FP2 | F23C 5926 0001 - F23C 1111001000111100 - 5926 0101100100100110 - 0001 0000000000000001 - mode = 7 - reg = 4 - size = 6 - */ - // Immediate addressing mode && Operation Length == Byte -> - // Use the low-order byte of the extension word. - - if(size == 6) ad++; - - // May be faster on a PII(I), sz2[size] is already in register - // ad += sz2[size] - sz1[size]; - - break; - default: - return 0; - } - } - - switch ((uae_u8)size) { - case 0: - signed_to_extended( (uae_s32) get_long (ad), src ); - break; - case 1: - to_single( get_long (ad), src ); - break; - - case 2:{ - uae_u32 wrd1, wrd2, wrd3; - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - ad += 4; - wrd3 = get_long (ad); - to_exten( wrd1, wrd2, wrd3, src ); - } - break; - case 3:{ - uae_u32 wrd1, wrd2, wrd3; - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - ad += 4; - wrd3 = get_long (ad); - double_to_extended( to_pack(wrd1, wrd2, wrd3), src ); - } - break; - case 4: - signed_to_extended( (uae_s32)(uae_s16) get_word(ad), src ); - break; - case 5:{ - uae_u32 wrd1, wrd2; - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - to_double(wrd1, wrd2, src); - } - break; - case 6: - signed_to_extended( (uae_s32)(uae_s8) get_byte(ad), src ); - break; - default: - return 0; - } - - // D(bug("get_fp_value result = %.04f\r\n",(float)src)); - - return 1; -} - -PRIVATE int FFPU put_fp_value (fpu_register const & value, uae_u32 opcode, uae_u32 extra) -{ - static const int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; - static const int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; - - // D(bug("put_fp_value(%.04f,%X,%X)\r\n",(float)value,(int)opcode,(int)extra)); - - if ((extra & 0x4000) == 0) { - int dest_reg = (extra >> 10) & 7; - do_fmove( FPU registers[dest_reg], value ); - build_ex_status(); - return 1; - } - - int mode = (opcode >> 3) & 7; - int reg = opcode & 7; - int size = (extra >> 10) & 7; - uae_u32 ad = 0xffffffff; - - // Clear exception status - x86_status_word &= ~SW_EXCEPTION_MASK; - - switch ((uae_u8)mode) { - case 0: - switch ((uae_u8)size) { - case 6: - *((uae_u8 *)&m68k_dreg(regs, reg)) = extended_to_signed_8(value); - break; - case 4: - // TODO_BIGENDIAN - *((uae_u16 *)&m68k_dreg(regs, reg)) = extended_to_signed_16(value); - break; - case 0: - m68k_dreg (regs, reg) = extended_to_signed_32(value); - break; - case 1: - m68k_dreg (regs, reg) = from_single(value); - break; - default: - return 0; - } - return 1; - case 1: - return 0; - case 2: - ad = m68k_areg (regs, reg); - break; - case 3: - ad = m68k_areg (regs, reg); - m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; - break; - case 4: - m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; - ad = m68k_areg (regs, reg); - break; - case 5: - ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); - break; - case 6: - ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); - break; - case 7: - switch ((uae_u8)reg) { - case 0: - ad = (uae_s32) (uae_s16) next_iword(); - break; - case 1: - ad = next_ilong(); - break; - case 2: - ad = m68k_getpc (); - ad += (uae_s32) (uae_s16) next_iword(); - break; - case 3: { - uaecptr tmppc = m68k_getpc (); - uae_u16 tmp = (uae_u16)next_iword(); - ad = get_disp_ea_020 (tmppc, tmp); - } - break; - case 4: - ad = m68k_getpc (); - m68k_setpc (ad + sz2[size]); - break; - default: - return 0; - } - } - switch ((uae_u8)size) { - case 0: - put_long (ad, (uae_s32) extended_to_signed_32(value)); - break; - case 1: - put_long (ad, from_single(value)); - break; - case 2: { - uae_u32 wrd1, wrd2, wrd3; - from_exten(value, &wrd1, &wrd2, &wrd3); - - x86_status_word &= ~SW_EXCEPTION_MASK; - if(wrd3) { // TODO: not correct! Just a "smart" guess. - x86_status_word |= SW_PE; - x86_status_word_accrued |= SW_PE; - } - - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - ad += 4; - put_long (ad, wrd3); - } - break; - case 3: { - uae_u32 wrd1, wrd2, wrd3; - from_pack(extended_to_double(value), &wrd1, &wrd2, &wrd3); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - ad += 4; - put_long (ad, wrd3); - } - break; - case 4: - put_word(ad, extended_to_signed_16(value)); - break; - case 5:{ - uae_u32 wrd1, wrd2; - from_double(value, &wrd1, &wrd2); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - } - break; - case 6: - put_byte(ad, extended_to_signed_8(value)); - - break; - default: - return 0; - } - return 1; -} - -PRIVATE int FFPU get_fp_ad(uae_u32 opcode, uae_u32 * ad) -{ - int mode = (opcode >> 3) & 7; - int reg = opcode & 7; - switch ( (uae_u8)mode ) { - case 0: - case 1: - if( (opcode & 0xFF00) == 0xF300 ) { - // fsave, frestore - m68k_setpc (m68k_getpc () - 2); - } else { - m68k_setpc (m68k_getpc () - 4); - } - op_illg (opcode); - dump_registers( "END "); - return 0; - case 2: - *ad = m68k_areg (regs, reg); - break; - case 3: - *ad = m68k_areg (regs, reg); - break; - case 4: - *ad = m68k_areg (regs, reg); - break; - case 5: - *ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); - break; - case 6: - *ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); - break; - case 7: - switch ( (uae_u8)reg ) { - case 0: - *ad = (uae_s32) (uae_s16) next_iword(); - break; - case 1: - *ad = next_ilong(); - break; - case 2: - *ad = m68k_getpc (); - *ad += (uae_s32) (uae_s16) next_iword(); - break; - case 3: { - uaecptr tmppc = m68k_getpc (); - uae_u16 tmp = (uae_u16)next_iword(); - *ad = get_disp_ea_020 (tmppc, tmp); - } - break; - default: - if( (opcode & 0xFF00) == 0xF300 ) { - // fsave, frestore - m68k_setpc (m68k_getpc () - 2); - } else { - m68k_setpc (m68k_getpc () - 4); - } - op_illg (opcode); - dump_registers( "END "); - return 0; - } - } - return 1; -} - -#if FPU_DEBUG -#define CONDRET(s,x) D(bug("fpp_cond %s = %d\r\n",s,(uint32)(x))); return (x) -#else -#define CONDRET(s,x) return (x) -#endif - -PRIVATE int FFPU fpp_cond(uae_u32 opcode, int condition) -{ - -#define N (x86_status_word & SW_N) -#define Z ((x86_status_word & (SW_Z_I_NAN_MASK)) == SW_Z) -#define I ((x86_status_word & (SW_Z_I_NAN_MASK)) == (SW_I)) -#define NotANumber ((x86_status_word & (SW_Z_I_NAN_MASK)) == SW_NAN) - - switch (condition) { - // Common Tests, no BSUN - case 0x01: - CONDRET("Equal",Z); - case 0x0e: - CONDRET("Not Equal",!Z); - - // IEEE Nonaware Tests, BSUN - case 0x12: - SET_BSUN_ON_NAN(); - CONDRET("Greater Than",!(NotANumber || Z || N)); - case 0x1d: - SET_BSUN_ON_NAN(); - CONDRET("Not Greater Than",NotANumber || Z || N); - case 0x13: - SET_BSUN_ON_NAN(); - CONDRET("Greater Than or Equal",Z || !(NotANumber || N)); - case 0x1c: - SET_BSUN_ON_NAN(); - CONDRET("Not Greater Than or Equal",!Z && (NotANumber || N)); - case 0x14: - SET_BSUN_ON_NAN(); - CONDRET("Less Than",N && !(NotANumber || Z)); - case 0x1b: - SET_BSUN_ON_NAN(); - CONDRET("Not Less Than",NotANumber || Z || !N); - case 0x15: - SET_BSUN_ON_NAN(); - CONDRET("Less Than or Equal",Z || (N && !NotANumber)); - case 0x1a: - SET_BSUN_ON_NAN(); - CONDRET("Not Less Than or Equal",NotANumber || !(N || Z)); - case 0x16: - SET_BSUN_ON_NAN(); - CONDRET("Greater or Less Than",!(NotANumber || Z)); - case 0x19: - SET_BSUN_ON_NAN(); - CONDRET("Not Greater or Less Than",NotANumber || Z); - case 0x17: - CONDRET("Greater, Less or Equal",!NotANumber); - case 0x18: - SET_BSUN_ON_NAN(); - CONDRET("Not Greater, Less or Equal",NotANumber); - - // IEEE Aware Tests, no BSUN - case 0x02: - CONDRET("Ordered Greater Than",!(NotANumber || Z || N)); - case 0x0d: - CONDRET("Unordered or Less or Equal",NotANumber || Z || N); - case 0x03: - CONDRET("Ordered Greater Than or Equal",Z || !(NotANumber || N)); - case 0x0c: - CONDRET("Unordered or Less Than",NotANumber || (N && !Z)); - case 0x04: - CONDRET("Ordered Less Than",N && !(NotANumber || Z)); - case 0x0b: - CONDRET("Unordered or Greater or Equal",NotANumber || Z || !N); - case 0x05: - CONDRET("Ordered Less Than or Equal",Z || (N && !NotANumber)); - case 0x0a: - CONDRET("Unordered or Greater Than",NotANumber || !(N || Z)); - case 0x06: - CONDRET("Ordered Greater or Less Than",!(NotANumber || Z)); - case 0x09: - CONDRET("Unordered or Equal",NotANumber || Z); - case 0x07: - CONDRET("Ordered",!NotANumber); - case 0x08: - CONDRET("Unordered",NotANumber); - - // Miscellaneous Tests, no BSUN - case 0x00: - CONDRET("False",0); - case 0x0f: - CONDRET("True",1); - - // Miscellaneous Tests, BSUN - case 0x10: - SET_BSUN_ON_NAN(); - CONDRET("Signaling False",0); - case 0x1f: - SET_BSUN_ON_NAN(); - CONDRET("Signaling True",1); - case 0x11: - SET_BSUN_ON_NAN(); - CONDRET("Signaling Equal",Z); - case 0x1e: - SET_BSUN_ON_NAN(); - CONDRET("Signaling Not Equal",!Z); - } - CONDRET("",-1); - -#undef N -#undef Z -#undef I -#undef NotANumber - -} - -PUBLIC void REGPARAM2 FFPU fpuop_dbcc(uae_u32 opcode, uae_u32 extra) -{ - uaecptr pc = (uae_u32) m68k_getpc (); - uae_s32 disp = (uae_s32) (uae_s16) next_iword(); - int cc; - - D(bug("fdbcc_opp %X, %X at %08lx\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); - - cc = fpp_cond(opcode, extra & 0x3f); - if (cc < 0) { - m68k_setpc (pc - 4); - op_illg (opcode); - } else if (!cc) { - int reg = opcode & 0x7; - - // TODO_BIGENDIAN - uae_u16 newv = (uae_u16)(m68k_dreg (regs, reg) & 0xffff) - 1; - *((uae_u16 *)&m68k_dreg(regs, reg)) = newv; - - if (newv != 0xffff) - m68k_setpc (pc + disp); - } -} - -PUBLIC void REGPARAM2 FFPU fpuop_scc(uae_u32 opcode, uae_u32 extra) -{ - uae_u32 ad; - int cc; - - D(bug("fscc_opp %X, %X at %08lx\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); - - cc = fpp_cond(opcode, extra & 0x3f); - if (cc < 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - } else if ((opcode & 0x38) == 0) { - // TODO_BIGENDIAN - m68k_dreg (regs, opcode & 7) = (m68k_dreg (regs, opcode & 7) & ~0xff) | - (cc ? 0xff : 0x00); - } else { - if (get_fp_ad(opcode, &ad)) { - put_byte(ad, cc ? 0xff : 0x00); - } - } -} - -PUBLIC void REGPARAM2 FFPU fpuop_trapcc(uae_u32 opcode, uaecptr oldpc) -{ - int cc; - - D(bug("ftrapcc_opp %X at %08lx\r\n", (uae_u32)opcode, m68k_getpc ())); - -#if I3_ON_FTRAPCC -#error "FIXME: _asm int 3" - _asm int 3 -#endif - - // This must be broken. - cc = fpp_cond(opcode, opcode & 0x3f); - - if (cc < 0) { - m68k_setpc (oldpc); - op_illg (opcode); - } else if (cc) - Exception(7, oldpc - 2); -} - -// NOTE that we get here also when there is a FNOP (nontrapping false, displ 0) -PUBLIC void REGPARAM2 FFPU fpuop_bcc(uae_u32 opcode, uaecptr pc, uae_u32 extra) -{ - int cc; - - D(bug("fbcc_opp %X, %X at %08lx, jumpto=%X\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc (), extra )); - - cc = fpp_cond(opcode, opcode & 0x3f); - if (cc < 0) { - m68k_setpc (pc); - op_illg (opcode); - } else if (cc) { - if ((opcode & 0x40) == 0) - extra = (uae_s32) (uae_s16) extra; - m68k_setpc (pc + extra); - } -} - -// FSAVE has no post-increment -// 0x1f180000 == IDLE state frame, coprocessor version number 1F -PUBLIC void REGPARAM2 FFPU fpuop_save(uae_u32 opcode) -{ - uae_u32 ad; - int incr = (opcode & 0x38) == 0x20 ? -1 : 1; - int i; - - D(bug("fsave_opp at %08lx\r\n", m68k_getpc ())); - - if (get_fp_ad(opcode, &ad)) { - if (FPU is_integral) { - // Put 4 byte 68040 IDLE frame. - if (incr < 0) { - ad -= 4; - put_long (ad, 0x41000000); - } else { - put_long (ad, 0x41000000); - ad += 4; - } - } else { - // Put 28 byte 68881 IDLE frame. - if (incr < 0) { - D(bug("fsave_opp pre-decrement\r\n")); - ad -= 4; - // What's this? Some BIU flags, or (incorrectly placed) command/condition? - put_long (ad, 0x70000000); - for (i = 0; i < 5; i++) { - ad -= 4; - put_long (ad, 0x00000000); - } - ad -= 4; - put_long (ad, 0x1f180000); // IDLE, vers 1f - } else { - put_long (ad, 0x1f180000); // IDLE, vers 1f - ad += 4; - for (i = 0; i < 5; i++) { - put_long (ad, 0x00000000); - ad += 4; - } - // What's this? Some BIU flags, or (incorrectly placed) command/condition? - put_long (ad, 0x70000000); - ad += 4; - } - } - if ((opcode & 0x38) == 0x18) { - m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881 - D(bug("PROBLEM: fsave_opp post-increment\r\n")); - } - if ((opcode & 0x38) == 0x20) { - m68k_areg (regs, opcode & 7) = ad; - D(bug("fsave_opp pre-decrement %X -> A%d\r\n",ad,opcode & 7)); - } - } -} - -PRIVATE void FFPU do_null_frestore () -{ - // A null-restore operation sets FP7-FP0 positive, nonsignaling NANs. - for( int i=0; i<8; i++ ) { - MAKE_NAN( FPU registers[i] ); - } - - FPU instruction_address = 0; - set_fpcr(0); - set_fpsr(0); - - x86_status_word = SW_INITIAL; - x86_status_word_accrued = 0; - FPU fpsr.quotient = 0; - - x86_control_word = CW_INITIAL; -/* _asm FLDCW x86_control_word - _asm FNCLEX */ - __asm__ __volatile__("fldcw %0\n\tfnclex" : : "m" (x86_control_word)); -} - -// FSAVE has no pre-decrement -PUBLIC void REGPARAM2 FFPU fpuop_restore(uae_u32 opcode) -{ - uae_u32 ad; - uae_u32 d; - int incr = (opcode & 0x38) == 0x20 ? -1 : 1; - - D(bug("frestore_opp at %08lx\r\n", m68k_getpc ())); - - if (get_fp_ad(opcode, &ad)) { - if (FPU is_integral) { - // 68040 - if (incr < 0) { - D(bug("PROBLEM: frestore_opp incr < 0\r\n")); - // this may be wrong, but it's never called. - ad -= 4; - d = get_long (ad); - if ((d & 0xff000000) == 0) { // NULL - D(bug("frestore_opp found NULL frame at %X\r\n",ad-4)); - do_null_frestore(); - } else if ((d & 0x00ff0000) == 0) { // IDLE - D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4)); - } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP - D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4)); - ad -= 44; - } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY - D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4)); - ad -= 92; - } else { - D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d)); - } - } else { - d = get_long (ad); - D(bug("frestore_opp frame at %X = %X\r\n",ad,d)); - ad += 4; - if ((d & 0xff000000) == 0) { // NULL - D(bug("frestore_opp found NULL frame at %X\r\n",ad-4)); - do_null_frestore(); - } else if ((d & 0x00ff0000) == 0) { // IDLE - D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4)); - } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP - D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4)); - ad += 44; - } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY - D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4)); - ad += 92; - } else { - D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d)); - } - } - } else { - // 68881 - if (incr < 0) { - D(bug("PROBLEM: frestore_opp incr < 0\r\n")); - // this may be wrong, but it's never called. - ad -= 4; - d = get_long (ad); - if ((d & 0xff000000) == 0) { // NULL - do_null_frestore(); - } else if ((d & 0x00ff0000) == 0x00180000) { - ad -= 6 * 4; - } else if ((d & 0x00ff0000) == 0x00380000) { - ad -= 14 * 4; - } else if ((d & 0x00ff0000) == 0x00b40000) { - ad -= 45 * 4; - } - } else { - d = get_long (ad); - D(bug("frestore_opp frame at %X = %X\r\n",ad,d)); - ad += 4; - if ((d & 0xff000000) == 0) { // NULL - D(bug("frestore_opp found NULL frame at %X\r\n",ad-4)); - do_null_frestore(); - } else if ((d & 0x00ff0000) == 0x00180000) { // IDLE - D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4)); - ad += 6 * 4; - } else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C? - ad += 14 * 4; - D(bug("PROBLEM: frestore_opp found UNIMP? frame at %X\r\n",ad-4)); - } else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY - D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4)); - ad += 45 * 4; - } else { - D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d)); - } - } - } - - if ((opcode & 0x38) == 0x18) { - m68k_areg (regs, opcode & 7) = ad; - D(bug("frestore_opp post-increment %X -> A%d\r\n",ad,opcode & 7)); - } - if ((opcode & 0x38) == 0x20) { - m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881 - D(bug("PROBLEM: frestore_opp pre-decrement\r\n")); - } - } -} - - -/* ---------------------------- Old-style interface ---------------------------- */ - -// #ifndef OPTIMIZED_8BIT_MEMORY_ACCESS -PUBLIC void REGPARAM2 FFPU fpuop_arithmetic(uae_u32 opcode, uae_u32 extra) -{ - uae_u32 mask = (extra & 0xFC7F) | ((opcode & 0x0038) << 4); - (*fpufunctbl[mask])(opcode,extra); -} -// #endif - - -/* ---------------------------- Illegal ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_illg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("ILLEGAL F OP 2 %X\r\n",opcode)); - -#if I3_ON_ILLEGAL_FPU_OP -#error "FIXME: asm int 3" - _asm int 3 -#endif - - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); -} - - -/* ---------------------------- FPP -> ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmove_2_ea( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVE -> \r\n")); - - if (put_fp_value (FPU registers[(extra >> 7) & 7], opcode, extra) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - } - - /* - Needed (among other things) by some Pack5/Elems68k transcendental - functions, they require the ACCR_INEX flag after a "MOVE.D, Dreg". - However, now put_fp_value() is responsible of clearing the exceptions - and merging statuses. - */ - - /* - WORD sw_temp; - _asm FNSTSW sw_temp - if(sw_temp & SW_PE) { - _asm FNCLEX - x86_status_word |= SW_PE; - x86_status_word_accrued |= SW_PE; - } - */ - - dump_registers( "END "); -} - - -/* ---------------------------- CONTROL REGS -> Dreg ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Dreg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM control(none) -> D%d\r\n", opcode & 7)); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM FPU instruction_address (%X) -> D%d\r\n", FPU instruction_address, opcode & 7)); - m68k_dreg (regs, opcode & 7) = FPU instruction_address; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Dreg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpsr (%X) -> D%d\r\n", get_fpsr(), opcode & 7)); - m68k_dreg (regs, opcode & 7) = get_fpsr(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Dreg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpcr (%X) -> D%d\r\n", get_fpcr(), opcode & 7)); - m68k_dreg (regs, opcode & 7) = get_fpcr(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpsr (%X) -> D%d\r\n", get_fpsr(), opcode & 7)); - m68k_dreg (regs, opcode & 7) = get_fpsr(); - D(bug("FMOVEM FPU instruction_address (%X) -> D%d\r\n", FPU instruction_address, opcode & 7)); - m68k_dreg (regs, opcode & 7) = FPU instruction_address; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpcr (%X) -> D%d\r\n", get_fpcr(), opcode & 7)); - m68k_dreg (regs, opcode & 7) = get_fpcr(); - D(bug("FMOVEM FPU instruction_address (%X) -> D%d\r\n", FPU instruction_address, opcode & 7)); - m68k_dreg (regs, opcode & 7) = FPU instruction_address; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Dreg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpcr (%X) -> D%d\r\n", get_fpcr(), opcode & 7)); - m68k_dreg (regs, opcode & 7) = get_fpcr(); - D(bug("FMOVEM regs.FPU fpsr (%X) -> D%d\r\n", get_fpsr(), opcode & 7)); - m68k_dreg (regs, opcode & 7) = get_fpsr(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpcr (%X) -> D%d\r\n", get_fpcr(), opcode & 7)); - m68k_dreg (regs, opcode & 7) = get_fpcr(); - D(bug("FMOVEM regs.FPU fpsr (%X) -> D%d\r\n", get_fpsr(), opcode & 7)); - m68k_dreg (regs, opcode & 7) = get_fpsr(); - D(bug("FMOVEM FPU instruction_address (%X) -> D%d\r\n", FPU instruction_address, opcode & 7)); - m68k_dreg (regs, opcode & 7) = FPU instruction_address; - dump_registers( "END "); -} - - -/* ---------------------------- Dreg -> CONTROL REGS ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_none( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM D%d -> control(none)\r\n", opcode & 7)); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpiar( uae_u32 opcode, uae_u32 extra ) -{ - FPU instruction_address = m68k_dreg (regs, opcode & 7); - D(bug("FMOVEM D%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpsr( uae_u32 opcode, uae_u32 extra ) -{ - set_fpsr( m68k_dreg (regs, opcode & 7) ); - D(bug("FMOVEM D%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ) -{ - set_fpsr( m68k_dreg (regs, opcode & 7) ); - D(bug("FMOVEM D%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); - FPU instruction_address = m68k_dreg (regs, opcode & 7); - D(bug("FMOVEM D%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr( uae_u32 opcode, uae_u32 extra ) -{ - set_fpcr( m68k_dreg (regs, opcode & 7) ); - D(bug("FMOVEM D%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpiar( uae_u32 opcode, uae_u32 extra ) -{ - set_fpcr( m68k_dreg (regs, opcode & 7) ); - D(bug("FMOVEM D%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); - FPU instruction_address = m68k_dreg (regs, opcode & 7); - D(bug("FMOVEM D%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr( uae_u32 opcode, uae_u32 extra ) -{ - set_fpcr( m68k_dreg (regs, opcode & 7) ); - D(bug("FMOVEM D%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); - set_fpsr( m68k_dreg (regs, opcode & 7) ); - D(bug("FMOVEM D%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ) -{ - set_fpcr( m68k_dreg (regs, opcode & 7) ); - D(bug("FMOVEM D%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); - set_fpsr( m68k_dreg (regs, opcode & 7) ); - D(bug("FMOVEM D%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); - FPU instruction_address = m68k_dreg (regs, opcode & 7); - D(bug("FMOVEM D%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); - dump_registers( "END "); -} - - -/* ---------------------------- CONTROL REGS -> Areg ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Areg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM control(none) -> A%d\r\n", opcode & 7)); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM FPU instruction_address (%X) -> A%d\r\n", FPU instruction_address, opcode & 7)); - m68k_areg (regs, opcode & 7) = FPU instruction_address; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Areg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpsr (%X) -> A%d\r\n", get_fpsr(), opcode & 7)); - m68k_areg (regs, opcode & 7) = get_fpsr(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Areg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpcr (%X) -> A%d\r\n", get_fpcr(), opcode & 7)); - m68k_areg (regs, opcode & 7) = get_fpcr(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpsr (%X) -> A%d\r\n", get_fpsr(), opcode & 7)); - m68k_areg (regs, opcode & 7) = get_fpsr(); - D(bug("FMOVEM FPU instruction_address (%X) -> A%d\r\n", FPU instruction_address, opcode & 7)); - m68k_areg (regs, opcode & 7) = FPU instruction_address; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpcr (%X) -> A%d\r\n", get_fpcr(), opcode & 7)); - m68k_areg (regs, opcode & 7) = get_fpcr(); - D(bug("FMOVEM FPU instruction_address (%X) -> A%d\r\n", FPU instruction_address, opcode & 7)); - m68k_areg (regs, opcode & 7) = FPU instruction_address; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Areg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpcr (%X) -> A%d\r\n", get_fpcr(), opcode & 7)); - m68k_areg (regs, opcode & 7) = get_fpcr(); - D(bug("FMOVEM regs.FPU fpsr (%X) -> A%d\r\n", get_fpsr(), opcode & 7)); - m68k_areg (regs, opcode & 7) = get_fpsr(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM regs.FPU fpcr (%X) -> A%d\r\n", get_fpcr(), opcode & 7)); - m68k_areg (regs, opcode & 7) = get_fpcr(); - D(bug("FMOVEM regs.FPU fpsr (%X) -> A%d\r\n", get_fpsr(), opcode & 7)); - m68k_areg (regs, opcode & 7) = get_fpsr(); - D(bug("FMOVEM FPU instruction_address (%X) -> A%d\r\n", FPU instruction_address, opcode & 7)); - m68k_areg (regs, opcode & 7) = FPU instruction_address; - dump_registers( "END "); -} - - -/* ---------------------------- Areg -> CONTROL REGS ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_none( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM A%d -> control(none)\r\n", opcode & 7)); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpiar( uae_u32 opcode, uae_u32 extra ) -{ - FPU instruction_address = m68k_areg (regs, opcode & 7); - D(bug("FMOVEM A%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpsr( uae_u32 opcode, uae_u32 extra ) -{ - set_fpsr( m68k_areg (regs, opcode & 7) ); - D(bug("FMOVEM A%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ) -{ - set_fpsr( m68k_areg (regs, opcode & 7) ); - D(bug("FMOVEM A%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); - FPU instruction_address = m68k_areg (regs, opcode & 7); - D(bug("FMOVEM A%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr( uae_u32 opcode, uae_u32 extra ) -{ - set_fpcr( m68k_areg (regs, opcode & 7) ); - D(bug("FMOVEM A%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpiar( uae_u32 opcode, uae_u32 extra ) -{ - set_fpcr( m68k_areg (regs, opcode & 7) ); - D(bug("FMOVEM A%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); - FPU instruction_address = m68k_areg (regs, opcode & 7); - D(bug("FMOVEM A%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpsr( uae_u32 opcode, uae_u32 extra ) -{ - set_fpcr( m68k_areg (regs, opcode & 7) ); - D(bug("FMOVEM A%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); - set_fpsr( m68k_areg (regs, opcode & 7) ); - D(bug("FMOVEM A%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ) -{ - set_fpcr( m68k_areg (regs, opcode & 7) ); - D(bug("FMOVEM A%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); - set_fpsr( m68k_areg (regs, opcode & 7) ); - D(bug("FMOVEM A%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); - FPU instruction_address = m68k_areg (regs, opcode & 7); - D(bug("FMOVEM A%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); - dump_registers( "END "); -} - - -/* ---------------------------- CONTROL REGS -> --MEMORY---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM Control regs (none) -> mem\r\n" )); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 4; - put_long (ad, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 4; - put_long (ad, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 8; - put_long (ad, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); - put_long (ad+4, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 4; - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 8; - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - put_long (ad+4, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 8; - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - put_long (ad+4, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 12; - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - put_long (ad+4, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); - put_long (ad+8, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+8 )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - - -/* ---------------------------- CONTROL REGS -> MEMORY++ ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM Control regs (none) -> mem\r\n" )); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad )); - m68k_areg (regs, opcode & 7) = ad+4; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); - m68k_areg (regs, opcode & 7) = ad+4; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); - put_long (ad+4, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); - m68k_areg (regs, opcode & 7) = ad+8; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - m68k_areg (regs, opcode & 7) = ad+4; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - put_long (ad+4, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); - m68k_areg (regs, opcode & 7) = ad+8; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - dump_registers( "END "); - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - put_long (ad+4, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); - m68k_areg (regs, opcode & 7) = ad+8; - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - put_long (ad+4, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); - put_long (ad+8, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+8 )); - m68k_areg (regs, opcode & 7) = ad+12; - dump_registers( "END "); - } -} - - -/* ---------------------------- CONTROL REGS -> MEMORY ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM Control regs (none) -> mem\r\n" )); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad )); - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); - put_long (ad+4, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - put_long (ad+4, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - put_long (ad+4, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - put_long (ad, get_fpcr()); - D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); - put_long (ad+4, get_fpsr()); - D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); - put_long (ad+8, FPU instruction_address); - D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+8 )); - dump_registers( "END "); - } -} - - -/* ---------------------------- --MEMORY -> CONTROL REGS ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM --Mem -> control(none)\r\n")); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 4; - FPU instruction_address = get_long (ad); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad, FPU instruction_address )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 4; - set_fpsr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 8; - set_fpsr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); - FPU instruction_address = get_long (ad+4); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 4; - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 8; - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - FPU instruction_address = get_long (ad+4); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 8; - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - set_fpsr( get_long (ad+4) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - ad -= 12; - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - set_fpsr( get_long (ad+4) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); - FPU instruction_address = get_long (ad+8); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+8, FPU instruction_address )); - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - - -/* ---------------------------- CONTROL REGS -> MEMORY++ ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM Mem++ -> control(none)\r\n")); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - FPU instruction_address = get_long (ad); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad, FPU instruction_address )); - m68k_areg (regs, opcode & 7) = ad+4; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpsr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); - m68k_areg (regs, opcode & 7) = ad+4; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpsr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); - FPU instruction_address = get_long (ad+4); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); - m68k_areg (regs, opcode & 7) = ad+8; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - m68k_areg (regs, opcode & 7) = ad+4; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - FPU instruction_address = get_long (ad+4); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); - m68k_areg (regs, opcode & 7) = ad+8; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - set_fpsr( get_long (ad+4) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); - m68k_areg (regs, opcode & 7) = ad+8; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - set_fpsr( get_long (ad+4) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); - FPU instruction_address = get_long (ad+8); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+8, FPU instruction_address )); - m68k_areg (regs, opcode & 7) = ad+12; - dump_registers( "END "); - } -} - - -/* ---------------------------- MEMORY -> CONTROL REGS ---------------------------- */ -/* ---------------------------- and ---------------------------- */ -/* ---------------------------- IMMEDIATE -> CONTROL REGS ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVEM Mem -> control(none)\r\n")); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - if ((opcode & 0x3f) == 0x3c) { - FPU instruction_address = next_ilong(); - D(bug("FMOVEM #<%X> -> FPU instruction_address\r\n", FPU instruction_address)); - } else { - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - FPU instruction_address = get_long (ad); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad, FPU instruction_address )); - } - } - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - if ((opcode & 0x3f) == 0x3c) { - set_fpsr( next_ilong() ); - D(bug("FMOVEM #<%X> -> regs.FPU fpsr\r\n", get_fpsr())); - } else { - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpsr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); - } - } - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - if ((opcode & 0x3f) == 0x3c) { - set_fpsr( next_ilong() ); - D(bug("FMOVEM #<%X> -> regs.FPU fpsr\r\n", get_fpsr())); - FPU instruction_address = next_ilong(); - D(bug("FMOVEM #<%X> -> FPU instruction_address\r\n", FPU instruction_address)); - } else { - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpsr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); - FPU instruction_address = get_long (ad+4); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); - } - } - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - if ((opcode & 0x3f) == 0x3c) { - set_fpcr( next_ilong() ); - D(bug("FMOVEM #<%X> -> regs.FPU fpcr\r\n", get_fpcr())); - } else { - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - } - } - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - if ((opcode & 0x3f) == 0x3c) { - set_fpcr( next_ilong() ); - D(bug("FMOVEM #<%X> -> regs.FPU fpcr\r\n", get_fpcr())); - FPU instruction_address = next_ilong(); - D(bug("FMOVEM #<%X> -> FPU instruction_address\r\n", FPU instruction_address)); - } else { - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - FPU instruction_address = get_long (ad+4); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); - } - } - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - if ((opcode & 0x3f) == 0x3c) { - set_fpcr( next_ilong() ); - D(bug("FMOVEM #<%X> -> regs.FPU fpcr\r\n", get_fpcr())); - set_fpsr( next_ilong() ); - D(bug("FMOVEM #<%X> -> regs.FPU fpsr\r\n", get_fpsr())); - } else { - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - set_fpsr( get_long (ad+4) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); - } - } - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) -{ - if ((opcode & 0x3f) == 0x3c) { - set_fpcr( next_ilong() ); - D(bug("FMOVEM #<%X> -> regs.FPU fpcr\r\n", get_fpcr())); - set_fpsr( next_ilong() ); - D(bug("FMOVEM #<%X> -> regs.FPU fpsr\r\n", get_fpsr())); - FPU instruction_address = next_ilong(); - D(bug("FMOVEM #<%X> -> FPU instruction_address\r\n", FPU instruction_address)); - } else { - uae_u32 ad; - if (get_fp_ad(opcode, &ad)) { - set_fpcr( get_long (ad) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); - set_fpsr( get_long (ad+4) ); - D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); - FPU instruction_address = get_long (ad+8); - D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+8, FPU instruction_address )); - } - } - dump_registers( "END "); -} - - -/* ---------------------------- FMOVEM MEMORY -> FPP ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - ad -= 4; - wrd3 = get_long (ad); - ad -= 4; - wrd2 = get_long (ad); - ad -= 4; - wrd1 = get_long (ad); - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - ad -= 4; - wrd3 = get_long (ad); - ad -= 4; - wrd2 = get_long (ad); - ad -= 4; - wrd1 = get_long (ad); - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - ad -= 4; - wrd3 = get_long (ad); - ad -= 4; - wrd2 = get_long (ad); - ad -= 4; - wrd1 = get_long (ad); - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - ad -= 4; - wrd3 = get_long (ad); - ad -= 4; - wrd2 = get_long (ad); - ad -= 4; - wrd1 = get_long (ad); - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - ad -= 4; - wrd3 = get_long (ad); - ad -= 4; - wrd2 = get_long (ad); - ad -= 4; - wrd1 = get_long (ad); - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - ad -= 4; - wrd3 = get_long (ad); - ad -= 4; - wrd2 = get_long (ad); - ad -= 4; - wrd1 = get_long (ad); - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - ad += 4; - wrd3 = get_long (ad); - ad += 4; - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - ad += 4; - wrd3 = get_long (ad); - ad += 4; - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - ad += 4; - wrd3 = get_long (ad); - ad += 4; - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - ad += 4; - wrd3 = get_long (ad); - ad += 4; - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - ad += 4; - wrd3 = get_long (ad); - ad += 4; - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM memory->FPP\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - wrd1 = get_long (ad); - ad += 4; - wrd2 = get_long (ad); - ad += 4; - wrd3 = get_long (ad); - ad += 4; - to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); - } - list <<= 1; - } - dump_registers( "END "); - } -} - - -/* ---------------------------- FPP -> FMOVEM MEMORY ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - ad -= 4; - put_long (ad, wrd3); - ad -= 4; - put_long (ad, wrd2); - ad -= 4; - put_long (ad, wrd1); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - ad -= 4; - put_long (ad, wrd3); - ad -= 4; - put_long (ad, wrd2); - ad -= 4; - put_long (ad, wrd1); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - ad -= 4; - put_long (ad, wrd3); - ad -= 4; - put_long (ad, wrd2); - ad -= 4; - put_long (ad, wrd1); - } - list <<= 1; - } - dump_registers( "END "); - } -} -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - ad -= 4; - put_long (ad, wrd3); - ad -= 4; - put_long (ad, wrd2); - ad -= 4; - put_long (ad, wrd1); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - ad -= 4; - put_long (ad, wrd3); - ad -= 4; - put_long (ad, wrd2); - ad -= 4; - put_long (ad, wrd1); - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=7; reg>=0; reg-- ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - ad -= 4; - put_long (ad, wrd3); - ad -= 4; - put_long (ad, wrd2); - ad -= 4; - put_long (ad, wrd1); - } - list <<= 1; - } - dump_registers( "END "); - } -} -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - ad += 4; - put_long (ad, wrd3); - ad += 4; - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - ad += 4; - put_long (ad, wrd3); - ad += 4; - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = extra & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - ad += 4; - put_long (ad, wrd3); - ad += 4; - } - list <<= 1; - } - dump_registers( "END "); - } -} -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_postincrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - ad += 4; - put_long (ad, wrd3); - ad += 4; - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_predecrement( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - ad += 4; - put_long (ad, wrd3); - ad += 4; - } - list <<= 1; - } - m68k_areg (regs, opcode & 7) = ad; - dump_registers( "END "); - } -} -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc( uae_u32 opcode, uae_u32 extra ) -{ - uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; - D(bug("FMOVEM FPP->memory\r\n")); - if (get_fp_ad(opcode, &ad)) { - for( int reg=0; reg<8; reg++ ) { - uae_u32 wrd1, wrd2, wrd3; - if( list & 0x80 ) { - from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); - put_long (ad, wrd1); - ad += 4; - put_long (ad, wrd2); - ad += 4; - put_long (ad, wrd3); - ad += 4; - } - list <<= 1; - } - dump_registers( "END "); - } -} - - -/* ---------------------------- FMOVEM CONSTANT ROM -> FPP ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_do_fldpi( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: Pi\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_pi, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fldlg2( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: Log 10 (2)\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_lg2, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_e( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: e\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_e, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fldl2e( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: Log 2 (e)\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_l2e, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_log_10_e( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: Log 10 (e)\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_log_10_e, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fldz( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: zero\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_z, sizeof(fpu_register) ); - x86_status_word = SW_Z; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fldln2( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: ln(2)\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_ln2, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_ln_10( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: ln(10)\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_ln_10, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fld1( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e0\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1, sizeof(fpu_register) ); - x86_status_word = SW_FINITE; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e1( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e1\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e1, sizeof(fpu_register) ); - x86_status_word = SW_FINITE; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e2( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e2\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e2, sizeof(fpu_register) ); - x86_status_word = SW_FINITE; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e4( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e4\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e4, sizeof(fpu_register) ); - x86_status_word = SW_FINITE; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e8( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e8\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e8, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; // Is it really FPSR_EXCEPTION_INEX2? - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e16( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e16\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e16, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e32( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e32\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e32, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e64( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e64\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e64, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e128( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e128\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e128, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e256( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e256\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e256, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e512( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e512\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e512, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e1024( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e1024\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e1024, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e2048( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e2048\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e2048, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e4096( uae_u32 opcode, uae_u32 extra ) -{ - D(bug("FMOVECR memory->FPP FP const: 1.0e4096\r\n")); - memcpy( &FPU registers[(extra>>7) & 7], &const_1e4096, sizeof(fpu_register) ); - x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; - dump_registers( "END "); -} - - -/* ---------------------------- ALU ---------------------------- */ - -PRIVATE void REGPARAM2 FFPU fpuop_do_fmove( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FMOVE %s\r\n",etos(src))); - do_fmove( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fint( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FINT %s, opcode=%X, extra=%X, ta %X\r\n",etos(src),opcode,extra,m68k_getpc())); - do_fint( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fsinh( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FSINH %s\r\n",etos(src))); - do_fsinh( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fintrz( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FINTRZ %s\r\n",etos(src))); - do_fintrz( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fsqrt( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FSQRT %s\r\n",etos(src))); - do_fsqrt( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_flognp1( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FLOGNP1 %s\r\n",etos(src))); - do_flognp1( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fetoxm1( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FETOXM1 %s\r\n",etos(src))); - do_fetoxm1( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_ftanh( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FTANH %s\r\n",etos(src))); - do_ftanh( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fatan( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FATAN %s\r\n",etos(src))); - do_fatan( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fasin( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FASIN %s\r\n",etos(src))); - do_fasin( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fatanh( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FATANH %s\r\n",etos(src))); - do_fatanh( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fsin( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FSIN %s\r\n",etos(src))); - do_fsin( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_ftan( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FTAN %s\r\n",etos(src))); - do_ftan( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fetox( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FETOX %s\r\n",etos(src))); - do_fetox( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_ftwotox( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FTWOTOX %s\r\n",etos(src))); - do_ftwotox( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_ftentox( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FTENTOX %s\r\n",etos(src))); - do_ftentox( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_flogn( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FLOGN %s\r\n",etos(src))); - do_flogn( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_flog10( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FLOG10 %s\r\n",etos(src))); - do_flog10( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_flog2( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FLOG2 %s\r\n",etos(src))); - do_flog2( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fabs( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FABS %s\r\n",etos(src))); - do_fabs( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fcosh( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FCOSH %s\r\n",etos(src))); - do_fcosh( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fneg( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FNEG %s\r\n",etos(src))); - do_fneg( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_facos( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FACOS %s\r\n",etos(src))); - do_facos( FPU registers[reg], src ); - build_ex_status(); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fcos( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FCOS %s\r\n",etos(src))); - do_fcos( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fgetexp( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FGETEXP %s\r\n",etos(src))); - - if( IS_INFINITY(src) ) { - MAKE_NAN( FPU registers[reg] ); - do_ftst( FPU registers[reg] ); - x86_status_word |= SW_IE; - } else { - do_fgetexp( FPU registers[reg], src ); - } - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fgetman( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FGETMAN %s\r\n",etos(src))); - if( IS_INFINITY(src) ) { - MAKE_NAN( FPU registers[reg] ); - do_ftst( FPU registers[reg] ); - x86_status_word |= SW_IE; - } else { - do_fgetman( FPU registers[reg], src ); - } - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fdiv( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FDIV %s\r\n",etos(src))); - do_fdiv( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fmod( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FMOD %s\r\n",etos(src))); - -#if USE_3_BIT_QUOTIENT - do_fmod( FPU registers[reg], src ); -#else - if( (x86_control_word & X86_ROUNDING_MODE) == CW_RC_ZERO ) { - do_fmod_dont_set_cw( FPU registers[reg], src ); - } else { - do_fmod( FPU registers[reg], src ); - } -#endif - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_frem( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FREM %s\r\n",etos(src))); -#if USE_3_BIT_QUOTIENT - do_frem( FPU registers[reg], src ); -#else - if( (x86_control_word & X86_ROUNDING_MODE) == CW_RC_NEAR ) { - do_frem_dont_set_cw( FPU registers[reg], src ); - } else { - do_frem( FPU registers[reg], src ); - } -#endif - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fadd( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FADD %s\r\n",etos(src))); - do_fadd( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fmul( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FMUL %s\r\n",etos(src))); - do_fmul( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fsgldiv( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FSGLDIV %s\r\n",etos(src))); - do_fsgldiv( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fscale( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FSCALE %s, opcode=%X, extra=%X, ta %X\r\n",etos(src),opcode,extra,m68k_getpc())); - if( IS_INFINITY(FPU registers[reg]) ) { - MAKE_NAN( FPU registers[reg] ); - do_ftst( FPU registers[reg] ); - x86_status_word |= SW_IE; - } else { - // When the absolute value of the source operand is >= 2^14, - // an overflow or underflow always results. - do_fscale( FPU registers[reg], src ); - } - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fsglmul( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FSGLMUL %s\r\n",etos(src))); - do_fsglmul( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fsub( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FSUB %s\r\n",etos(src))); - do_fsub( FPU registers[reg], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fsincos( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FSINCOS %s\r\n",etos(src))); - do_fsincos( FPU registers[reg], FPU registers[extra & 7], src ); - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_fcmp( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FCMP %s\r\n",etos(src))); - - if( IS_INFINITY(src) ) { - if( IS_NEGATIVE(src) ) { - if( IS_INFINITY(FPU registers[reg]) && IS_NEGATIVE(FPU registers[reg]) ) { - x86_status_word = SW_Z | SW_N; - D(bug("-INF FCMP -INF -> NZ\r\n")); - } else { - x86_status_word = SW_FINITE; - D(bug("X FCMP -INF -> None\r\n")); - } - } else { - if( IS_INFINITY(FPU registers[reg]) && !IS_NEGATIVE(FPU registers[reg]) ) { - x86_status_word = SW_Z; - D(bug("+INF FCMP +INF -> Z\r\n")); - } else { - x86_status_word = SW_N; - D(bug("X FCMP +INF -> N\r\n")); - } - } - } else if( IS_INFINITY(FPU registers[reg]) ) { - if( IS_NEGATIVE(FPU registers[reg]) ) { - x86_status_word = SW_N; - D(bug("-INF FCMP X -> Negative\r\n")); - } else { - x86_status_word = SW_FINITE; - D(bug("+INF FCMP X -> None\r\n")); - } - } else { - do_fcmp( FPU registers[reg], src ); - } - - dump_registers( "END "); -} - -PRIVATE void REGPARAM2 FFPU fpuop_do_ftst( uae_u32 opcode, uae_u32 extra ) -{ - int reg = (extra >> 7) & 7; - fpu_register src; - if (get_fp_value (opcode, extra, src) == 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); - dump_registers( "END "); - return; - } - D(bug("FTST %s\r\n",etos(src))); - do_ftst( src ); - build_ex_status(); - dump_registers( "END "); -} - - - -/* ---------------------------- SETUP TABLES ---------------------------- */ - -PRIVATE void FFPU build_fpp_opp_lookup_table () -{ - for( uae_u32 opcode=0; opcode<=0x38; opcode+=8 ) { - for( uae_u32 extra=0; extra<65536; extra++ ) { - uae_u32 mask = (extra & 0xFC7F) | ((opcode & 0x0038) << 4); - fpufunctbl[mask] = & FFPU fpuop_illg; - - switch ((extra >> 13) & 0x7) { - case 3: - fpufunctbl[mask] = & FFPU fpuop_fmove_2_ea; - break; - case 4: - case 5: - if ((opcode & 0x38) == 0) { - if (extra & 0x2000) { // dr bit - switch( extra & 0x1C00 ) { - case 0x0000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_none_2_Dreg; - break; - case 0x0400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpiar_2_Dreg; - break; - case 0x0800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_2_Dreg; - break; - case 0x0C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_fpiar_2_Dreg; - break; - case 0x1000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_2_Dreg; - break; - case 0x1400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpiar_2_Dreg; - break; - case 0x1800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_2_Dreg; - break; - case 0x1C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Dreg; - break; - } - } else { - switch( extra & 0x1C00 ) { - case 0x0000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_none; - break; - case 0x0400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpiar; - break; - case 0x0800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpsr; - break; - case 0x0C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpsr_fpiar; - break; - case 0x1000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpcr; - break; - case 0x1400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpcr_fpiar; - break; - case 0x1800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr; - break; - case 0x1C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr_fpiar; - break; - } - } - } else if ((opcode & 0x38) == 8) { - if (extra & 0x2000) { // dr bit - switch( extra & 0x1C00 ) { - case 0x0000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_none_2_Areg; - break; - case 0x0400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpiar_2_Areg; - break; - case 0x0800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_2_Areg; - break; - case 0x0C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_fpiar_2_Areg; - break; - case 0x1000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_2_Areg; - break; - case 0x1400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpiar_2_Areg; - break; - case 0x1800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_2_Areg; - break; - case 0x1C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Areg; - break; - } - } else { - switch( extra & 0x1C00 ) { - case 0x0000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_none; - break; - case 0x0400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpiar; - break; - case 0x0800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpsr; - break; - case 0x0C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpsr_fpiar; - break; - case 0x1000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpcr; - break; - case 0x1400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpcr_fpiar; - break; - case 0x1800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpcr_fpsr; - break; - case 0x1C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpcr_fpsr_fpiar; - break; - } - } - } else if (extra & 0x2000) { - if ((opcode & 0x38) == 0x20) { - switch( extra & 0x1C00 ) { - case 0x0000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_none_2_Mem_predecrement; - break; - case 0x0400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpiar_2_Mem_predecrement; - break; - case 0x0800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_2_Mem_predecrement; - break; - case 0x0C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_predecrement; - break; - case 0x1000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_2_Mem_predecrement; - break; - case 0x1400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_predecrement; - break; - case 0x1800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_predecrement; - break; - case 0x1C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_predecrement; - break; - } - } else if ((opcode & 0x38) == 0x18) { - switch( extra & 0x1C00 ) { - case 0x0000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_none_2_Mem_postincrement; - break; - case 0x0400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpiar_2_Mem_postincrement; - break; - case 0x0800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_2_Mem_postincrement; - break; - case 0x0C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_postincrement; - break; - case 0x1000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_2_Mem_postincrement; - break; - case 0x1400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_postincrement; - break; - case 0x1800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_postincrement; - break; - case 0x1C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_postincrement; - break; - } - } else { - switch( extra & 0x1C00 ) { - case 0x0000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_none_2_Mem; - break; - case 0x0400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpiar_2_Mem; - break; - case 0x0800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_2_Mem; - break; - case 0x0C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_fpiar_2_Mem; - break; - case 0x1000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_2_Mem; - break; - case 0x1400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpiar_2_Mem; - break; - case 0x1800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_2_Mem; - break; - case 0x1C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem; - break; - } - } - } else { - if ((opcode & 0x38) == 0x20) { - switch( extra & 0x1C00 ) { - case 0x0000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_none_predecrement; - break; - case 0x0400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpiar_predecrement; - break; - case 0x0800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_predecrement; - break; - case 0x0C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_predecrement; - break; - case 0x1000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_predecrement; - break; - case 0x1400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_predecrement; - break; - case 0x1800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_predecrement; - break; - case 0x1C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_predecrement; - break; - } - } else if ((opcode & 0x38) == 0x18) { - switch( extra & 0x1C00 ) { - case 0x0000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_none_postincrement; - break; - case 0x0400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpiar_postincrement; - break; - case 0x0800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_postincrement; - break; - case 0x0C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_postincrement; - break; - case 0x1000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_postincrement; - break; - case 0x1400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_postincrement; - break; - case 0x1800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_postincrement; - break; - case 0x1C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_postincrement; - break; - } - } else { - switch( extra & 0x1C00 ) { - case 0x0000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_none_2_Mem; - break; - case 0x0400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpiar_2_Mem; - break; - case 0x0800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_2_Mem; - break; - case 0x0C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_2_Mem; - break; - case 0x1000: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_2_Mem; - break; - case 0x1400: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_2_Mem; - break; - case 0x1800: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_2_Mem; - break; - case 0x1C00: - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_2_Mem; - break; - } - } - break; - case 6: - switch ((extra >> 11) & 3) { - case 0: /* static pred */ - if ((opcode & 0x38) == 0x18) // post-increment? - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_pred_postincrement; - else if ((opcode & 0x38) == 0x20) // pre-decrement? - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_pred_predecrement; - else - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_pred; - break; - case 1: /* dynamic pred */ - if ((opcode & 0x38) == 0x18) // post-increment? - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_postincrement; - else if ((opcode & 0x38) == 0x20) // pre-decrement? - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_predecrement; - else - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred; - break; - case 2: /* static postinc */ - if ((opcode & 0x38) == 0x18) // post-increment? - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_postincrement; - else if ((opcode & 0x38) == 0x20) // pre-decrement? - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_predecrement; - else - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_postinc; - break; - case 3: /* dynamic postinc */ - if ((opcode & 0x38) == 0x18) // post-increment? - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_postincrement; - else if ((opcode & 0x38) == 0x20) // pre-decrement? - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_predecrement; - else - fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc; - break; - } - break; - case 7: - switch ((extra >> 11) & 3) { - case 0: /* static pred */ - if ((opcode & 0x38) == 0x18) // post-increment? - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_pred_postincrement; - else if ((opcode & 0x38) == 0x20) // pre-decrement? - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_pred_predecrement; - else - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_pred; - break; - case 1: /* dynamic pred */ - if ((opcode & 0x38) == 0x18) // post-increment? - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_postincrement; - else if ((opcode & 0x38) == 0x20) // pre-decrement? - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_predecrement; - else - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred; - break; - case 2: /* static postinc */ - if ((opcode & 0x38) == 0x18) // post-increment? - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_postincrement; - else if ((opcode & 0x38) == 0x20) // pre-decrement? - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_predecrement; - else - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_postinc; - break; - case 3: /* dynamic postinc */ - if ((opcode & 0x38) == 0x18) // post-increment? - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_postincrement; - else if ((opcode & 0x38) == 0x20) // pre-decrement? - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_predecrement; - else - fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc; - break; - } - break; - case 0: - case 2: - if ((extra & 0xfc00) == 0x5c00) { - switch (extra & 0x7f) { - case 0x00: - fpufunctbl[mask] = & FFPU fpuop_do_fldpi; - break; - case 0x0b: - fpufunctbl[mask] = & FFPU fpuop_do_fldlg2; - break; - case 0x0c: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_e; - break; - case 0x0d: - fpufunctbl[mask] = & FFPU fpuop_do_fldl2e; - break; - case 0x0e: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_log_10_e; - break; - case 0x0f: - fpufunctbl[mask] = & FFPU fpuop_do_fldz; - break; - case 0x30: - fpufunctbl[mask] = & FFPU fpuop_do_fldln2; - break; - case 0x31: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_ln_10; - break; - case 0x32: - fpufunctbl[mask] = & FFPU fpuop_do_fld1; - break; - case 0x33: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e1; - break; - case 0x34: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e2; - break; - case 0x35: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e4; - break; - case 0x36: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e8; - break; - case 0x37: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e16; - break; - case 0x38: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e32; - break; - case 0x39: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e64; - break; - case 0x3a: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e128; - break; - case 0x3b: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e256; - break; - case 0x3c: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e512; - break; - case 0x3d: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e1024; - break; - case 0x3e: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e2048; - break; - case 0x3f: - fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e4096; - break; - } - break; - } - - switch (extra & 0x7f) { - case 0x00: - fpufunctbl[mask] = & FFPU fpuop_do_fmove; - break; - case 0x01: - fpufunctbl[mask] = & FFPU fpuop_do_fint; - break; - case 0x02: - fpufunctbl[mask] = & FFPU fpuop_do_fsinh; - break; - case 0x03: - fpufunctbl[mask] = & FFPU fpuop_do_fintrz; - break; - case 0x04: - fpufunctbl[mask] = & FFPU fpuop_do_fsqrt; - break; - case 0x06: - fpufunctbl[mask] = & FFPU fpuop_do_flognp1; - break; - case 0x08: - fpufunctbl[mask] = & FFPU fpuop_do_fetoxm1; - break; - case 0x09: - fpufunctbl[mask] = & FFPU fpuop_do_ftanh; - break; - case 0x0a: - fpufunctbl[mask] = & FFPU fpuop_do_fatan; - break; - case 0x0c: - fpufunctbl[mask] = & FFPU fpuop_do_fasin; - break; - case 0x0d: - fpufunctbl[mask] = & FFPU fpuop_do_fatanh; - break; - case 0x0e: - fpufunctbl[mask] = & FFPU fpuop_do_fsin; - break; - case 0x0f: - fpufunctbl[mask] = & FFPU fpuop_do_ftan; - break; - case 0x10: - fpufunctbl[mask] = & FFPU fpuop_do_fetox; - break; - case 0x11: - fpufunctbl[mask] = & FFPU fpuop_do_ftwotox; - break; - case 0x12: - fpufunctbl[mask] = & FFPU fpuop_do_ftentox; - break; - case 0x14: - fpufunctbl[mask] = & FFPU fpuop_do_flogn; - break; - case 0x15: - fpufunctbl[mask] = & FFPU fpuop_do_flog10; - break; - case 0x16: - fpufunctbl[mask] = & FFPU fpuop_do_flog2; - break; - case 0x18: - fpufunctbl[mask] = & FFPU fpuop_do_fabs; - break; - case 0x19: - fpufunctbl[mask] = & FFPU fpuop_do_fcosh; - break; - case 0x1a: - fpufunctbl[mask] = & FFPU fpuop_do_fneg; - break; - case 0x1c: - fpufunctbl[mask] = & FFPU fpuop_do_facos; - break; - case 0x1d: - fpufunctbl[mask] = & FFPU fpuop_do_fcos; - break; - case 0x1e: - fpufunctbl[mask] = & FFPU fpuop_do_fgetexp; - break; - case 0x1f: - fpufunctbl[mask] = & FFPU fpuop_do_fgetman; - break; - case 0x20: - fpufunctbl[mask] = & FFPU fpuop_do_fdiv; - break; - case 0x21: - fpufunctbl[mask] = & FFPU fpuop_do_fmod; - break; - case 0x22: - fpufunctbl[mask] = & FFPU fpuop_do_fadd; - break; - case 0x23: - fpufunctbl[mask] = & FFPU fpuop_do_fmul; - break; - case 0x24: - fpufunctbl[mask] = & FFPU fpuop_do_fsgldiv; - break; - case 0x25: - fpufunctbl[mask] = & FFPU fpuop_do_frem; - break; - case 0x26: - fpufunctbl[mask] = & FFPU fpuop_do_fscale; - break; - case 0x27: - fpufunctbl[mask] = & FFPU fpuop_do_fsglmul; - break; - case 0x28: - fpufunctbl[mask] = & FFPU fpuop_do_fsub; - break; - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - fpufunctbl[mask] = & FFPU fpuop_do_fsincos; - break; - case 0x38: - fpufunctbl[mask] = & FFPU fpuop_do_fcmp; - break; - case 0x3a: - fpufunctbl[mask] = & FFPU fpuop_do_ftst; - break; - } - } - } - } - } -} - -/* ---------------------------- CONSTANTS ---------------------------- */ - -PRIVATE void FFPU set_constant ( fpu_register & f, char *name, double value, uae_s32 mult ) -{ - FPU_CONSISTENCY_CHECK_START(); - if(mult == 1) { -/* _asm { - MOV ESI, [f] - FLD QWORD PTR [value] - FSTP TBYTE PTR [ESI] - } */ - __asm__ __volatile__( - "fldl %1\n" - "fstpt %0\n" - : "=m" (f) - : "m" (value) - ); - } else { -/* _asm { - MOV ESI, [f] - FILD DWORD PTR [mult] - FLD QWORD PTR [value] - FMUL - FSTP TBYTE PTR [ESI] - } */ - __asm__ __volatile__( - "fildl %2\n" - "fldl %1\n" - "fmul \n" - "fstpt %0\n" - : "=m" (f) - : "m" (value), "m" (mult) - ); - } - D(bug("set_constant (%s,%.04f) = %s\r\n",name,(float)value,etos(f))); - FPU_CONSISTENCY_CHECK_STOP( mult==1 ? "set_constant(mult==1)" : "set_constant(mult>1)" ); -} - -PRIVATE void FFPU do_fldpi ( fpu_register & dest ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - FLDPI - FXAM - FNSTSW x86_status_word - MOV EDI, [dest] - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldpi \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - ); - FPU_CONSISTENCY_CHECK_STOP("do_fldpi"); -} - -PRIVATE void FFPU do_fldlg2 ( fpu_register & dest ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - FLDLG2 - FXAM - FNSTSW x86_status_word - MOV EDI, [dest] - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldlg2 \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - ); - FPU_CONSISTENCY_CHECK_STOP("do_fldlg2"); -} - -PRIVATE void FFPU do_fldl2e ( fpu_register & dest ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - FLDL2E - FXAM - FNSTSW x86_status_word - MOV EDI, [dest] - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldl2e \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - ); - FPU_CONSISTENCY_CHECK_STOP("do_fldl2e"); -} - -PRIVATE void FFPU do_fldz ( fpu_register & dest ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - FLDZ - FXAM - FNSTSW x86_status_word - MOV EDI, [dest] - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldz \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - ); - FPU_CONSISTENCY_CHECK_STOP("do_fldz"); -} - -PRIVATE void FFPU do_fldln2 ( fpu_register & dest ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - FLDLN2 - FXAM - FNSTSW x86_status_word - MOV EDI, [dest] - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fldln2 \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - ); - FPU_CONSISTENCY_CHECK_STOP("do_fldln2"); -} - -PRIVATE void FFPU do_fld1 ( fpu_register & dest ) -{ - FPU_CONSISTENCY_CHECK_START(); -/* _asm { - FLD1 - FXAM - FNSTSW x86_status_word - MOV EDI, [dest] - FSTP TBYTE PTR [EDI] - } */ - __asm__ __volatile__( - "fld1 \n" - "fxam \n" - "fnstsw %0\n" - "fstpt %1\n" - : "=m" (x86_status_word), "=m" (dest) - ); - FPU_CONSISTENCY_CHECK_STOP("do_fld1"); -} - - -/* ---------------------------- MAIN INIT ---------------------------- */ - -#ifdef HAVE_SIGACTION -// Mega hackaround-that-happens-to-work: the following way to handle -// SIGFPE just happens to make the "fsave" below in fpu_init() *NOT* -// to abort with a floating point exception. However, we never -// actually reach sigfpe_handler(). -static void sigfpe_handler(int code, siginfo_t *sip, void *) -{ - if (code == SIGFPE && sip->si_code == FPE_FLTINV) { - fprintf(stderr, "Invalid floating point operation\n"); - abort(); - } -} -#endif - -PUBLIC void FFPU fpu_init( bool integral_68040 ) -{ - static bool done_first_time_initialization = false; - if (!done_first_time_initialization) { - fpu_init_native_fflags(); - fpu_init_native_exceptions(); - fpu_init_native_accrued_exceptions(); -#ifdef HAVE_SIGACTION - struct sigaction fpe_sa; - sigemptyset(&fpe_sa.sa_mask); - fpe_sa.sa_sigaction = sigfpe_handler; - fpe_sa.sa_flags = SA_SIGINFO; - sigaction(SIGFPE, &fpe_sa, 0); -#endif - done_first_time_initialization = true; - } - - __asm__ __volatile__("fsave %0" : "=m" (m_fpu_state_original)); - - FPU is_integral = integral_68040; - FPU instruction_address = 0; - set_fpcr(0); - set_fpsr(0); - - x86_control_word = CW_INITIAL; - x86_status_word = SW_INITIAL; - x86_status_word_accrued = 0; - FPU fpsr.quotient = 0; - - for( int i=0; i<8; i++ ) { - MAKE_NAN( FPU registers[i] ); - } - - build_fpp_opp_lookup_table(); - - __asm__ __volatile__("fninit\nfldcw %0" : : "m" (x86_control_word)); - - do_fldpi( const_pi ); - do_fldlg2( const_lg2 ); - do_fldl2e( const_l2e ); - do_fldz( const_z ); - do_fldln2( const_ln2 ); - do_fld1( const_1 ); - - set_constant( const_e, "e", exp (1.0), 1 ); - set_constant( const_log_10_e, "Log 10 (e)", log (exp (1.0)) / log (10.0), 1 ); - set_constant( const_ln_10, "ln(10)", log (10.0), 1 ); - set_constant( const_1e1, "1.0e1", 1.0e1, 1 ); - set_constant( const_1e2, "1.0e2", 1.0e2, 1 ); - set_constant( const_1e4, "1.0e4", 1.0e4, 1 ); - set_constant( const_1e8, "1.0e8", 1.0e8, 1 ); - set_constant( const_1e16, "1.0e16", 1.0e16, 1 ); - set_constant( const_1e32, "1.0e32", 1.0e32, 1 ); - set_constant( const_1e64, "1.0e64", 1.0e64, 1 ) ; - set_constant( const_1e128, "1.0e128", 1.0e128, 1 ); - set_constant( const_1e256, "1.0e256", 1.0e256, 1 ); - set_constant( const_1e512, "1.0e512", 1.0e256, 10 ); - set_constant( const_1e1024, "1.0e1024", 1.0e256, 100 ); - set_constant( const_1e2048, "1.0e2048", 1.0e256, 1000 ); - set_constant( const_1e4096, "1.0e4096", 1.0e256, 10000 ); - - // Just in case. - __asm__ __volatile__("fninit\nfldcw %0" : : "m" (x86_control_word)); -} - -PUBLIC void FFPU fpu_exit( void ) -{ - __asm__ __volatile__("frstor %0" : : "m" (m_fpu_state_original)); -} - -PUBLIC void FFPU fpu_reset( void ) -{ - fpu_exit(); - fpu_init(FPU is_integral); -} diff --git a/BasiliskII/src/uae_cpu/fpu/fpu_x86.h b/BasiliskII/src/uae_cpu/fpu/fpu_x86.h deleted file mode 100644 index 96f1d959..00000000 --- a/BasiliskII/src/uae_cpu/fpu/fpu_x86.h +++ /dev/null @@ -1,361 +0,0 @@ -/* - * fpu/fpu_x86.h - Extra Definitions for the X86 assembly FPU core - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * MC68881/68040 fpu emulation - * - * Original UAE FPU, copyright 1996 Herman ten Brugge - * Rewrite for x86, copyright 1999-2000 Lauri Pesonen - * New framework, copyright 2000 Gwenole Beauchesne - * Adapted for JIT compilation (c) Bernd Meyer, 2000 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef FPU_X86_H -#define FPU_X86_H - -/* NOTE: this file shall be included from fpu/fpu_x86.cpp */ -#undef PUBLIC -#define PUBLIC extern - -#undef PRIVATE -#define PRIVATE static - -#undef FFPU -#define FFPU /**/ - -#undef FPU -#define FPU fpu. - -// Status word -PRIVATE uae_u32 x86_status_word; -PRIVATE uae_u32 x86_status_word_accrued; - -// FPU jump table -typedef void REGPARAM2 ( *fpuop_func )( uae_u32, uae_u32 ); -PRIVATE fpuop_func fpufunctbl[65536]; - -// FPU consistency -PRIVATE uae_u32 checked_sw_atstart; - -// FMOVECR constants supported byt x86 FPU -PRIVATE fpu_register const_pi; -PRIVATE fpu_register const_lg2; -PRIVATE fpu_register const_l2e; -PRIVATE fpu_register const_z; -PRIVATE fpu_register const_ln2; -PRIVATE fpu_register const_1; - -// FMOVECR constants not not suported by x86 FPU -PRIVATE fpu_register const_e; -PRIVATE fpu_register const_log_10_e; -PRIVATE fpu_register const_ln_10; -PRIVATE fpu_register const_1e1; -PRIVATE fpu_register const_1e2; -PRIVATE fpu_register const_1e4; -PRIVATE fpu_register const_1e8; -PRIVATE fpu_register const_1e16; -PRIVATE fpu_register const_1e32; -PRIVATE fpu_register const_1e64; -PRIVATE fpu_register const_1e128; -PRIVATE fpu_register const_1e256; -PRIVATE fpu_register const_1e512; -PRIVATE fpu_register const_1e1024; -PRIVATE fpu_register const_1e2048; -PRIVATE fpu_register const_1e4096; - -// Saved host FPU state -PRIVATE uae_u8 m_fpu_state_original[108]; // 90/94/108 - -/* -------------------------------------------------------------------------- */ -/* --- Methods --- */ -/* -------------------------------------------------------------------------- */ - -// Debug support functions -PRIVATE void FFPU dump_first_bytes_buf(char *b, uae_u8* buf, uae_s32 actual); -PRIVATE char * FFPU etos(fpu_register const & e) REGPARAM; - -// FPU consistency -PRIVATE void FFPU FPU_CONSISTENCY_CHECK_START(void); -PRIVATE void FFPU FPU_CONSISTENCY_CHECK_STOP(const char *name); - -// Get special floating-point value class -PRIVATE __inline__ uae_u32 FFPU IS_INFINITY (fpu_register const & f); -PRIVATE __inline__ uae_u32 FFPU IS_NAN (fpu_register const & f); -PRIVATE __inline__ uae_u32 FFPU IS_ZERO (fpu_register const & f); -PRIVATE __inline__ uae_u32 FFPU IS_NEGATIVE (fpu_register const & f); - -// Make a special floating-point value -PRIVATE __inline__ void FFPU MAKE_NAN (fpu_register & f); -PRIVATE __inline__ void FFPU MAKE_INF_POSITIVE (fpu_register & f); -PRIVATE __inline__ void FFPU MAKE_INF_NEGATIVE (fpu_register & f); -PRIVATE __inline__ void FFPU MAKE_ZERO_POSITIVE (fpu_register & f); -PRIVATE __inline__ void FFPU MAKE_ZERO_NEGATIVE (fpu_register & f); - -// Conversion from extended floating-point values -PRIVATE uae_s32 FFPU extended_to_signed_32 ( fpu_register const & f ) REGPARAM; -PRIVATE uae_s16 FFPU extended_to_signed_16 ( fpu_register const & f ) REGPARAM; -PRIVATE uae_s8 FFPU extended_to_signed_8 ( fpu_register const & f ) REGPARAM; -PRIVATE fpu_double FFPU extended_to_double( fpu_register const & f ) REGPARAM; -PRIVATE uae_u32 FFPU from_single ( fpu_register const & f ) REGPARAM; -PRIVATE void FFPU from_exten ( fpu_register const & f, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3 ) REGPARAM; -PRIVATE void FFPU from_double ( fpu_register const & f, uae_u32 *wrd1, uae_u32 *wrd2 ) REGPARAM; -PRIVATE void FFPU from_pack (fpu_double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) REGPARAM; - -// Conversion to extended floating-point values -PRIVATE void FFPU signed_to_extended ( uae_s32 x, fpu_register & f ) REGPARAM; -PRIVATE void FFPU double_to_extended ( double x, fpu_register & f ) REGPARAM; -PRIVATE void FFPU to_single ( uae_u32 src, fpu_register & f ) REGPARAM; -PRIVATE void FFPU to_exten_no_normalize ( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & f ) REGPARAM; -PRIVATE void FFPU to_exten ( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & f ) REGPARAM; -PRIVATE void FFPU to_double ( uae_u32 wrd1, uae_u32 wrd2, fpu_register & f ) REGPARAM; -PRIVATE fpu_double FFPU to_pack(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) REGPARAM; - -// Atomic floating-point arithmetic operations -PRIVATE void FFPU do_fmove ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fmove_no_status ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fint ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fintrz ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fsqrt ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_ftst ( fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fsinh ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_flognp1 ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fetoxm1 ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_ftanh ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fatan ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fasin ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fatanh ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fetox ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_ftwotox ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_ftentox ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_flogn ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_flog10 ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_flog2 ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_facos ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fcosh ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fsin ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_ftan ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fabs ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fneg ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fcos ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fgetexp ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fgetman ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fdiv ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fmod ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_frem ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fmod_dont_set_cw ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_frem_dont_set_cw ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fadd ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fmul ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fsgldiv ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fscale ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fsglmul ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fsub ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fsincos ( fpu_register & dest_sin, fpu_register & dest_cos, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fcmp ( fpu_register & dest, fpu_register const & src ) REGPARAM; -PRIVATE void FFPU do_fldpi ( fpu_register & dest ) REGPARAM; -PRIVATE void FFPU do_fldlg2 ( fpu_register & dest ) REGPARAM; -PRIVATE void FFPU do_fldl2e ( fpu_register & dest ) REGPARAM; -PRIVATE void FFPU do_fldz ( fpu_register & dest ) REGPARAM; -PRIVATE void FFPU do_fldln2 ( fpu_register & dest ) REGPARAM; -PRIVATE void FFPU do_fld1 ( fpu_register & dest ) REGPARAM; - -// Instructions handlers -PRIVATE void REGPARAM2 FFPU fpuop_illg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmove_2_ea( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Dreg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Dreg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Dreg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Dreg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_none( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpiar( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpsr( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpiar( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Areg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Areg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Areg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Areg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_none( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpiar( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpsr( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpiar( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpsr( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_postincrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_predecrement( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fldpi( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fldlg2( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_e( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fldl2e( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_log_10_e( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fldz( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fldln2( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_ln_10( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fld1( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e1( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e2( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e4( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e8( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e16( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e32( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e64( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e128( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e256( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e512( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e1024( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e2048( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e4096( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fmove( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fint( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fsinh( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fintrz( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fsqrt( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_flognp1( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fetoxm1( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_ftanh( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fatan( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fasin( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fatanh( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fsin( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_ftan( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fetox( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_ftwotox( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_ftentox( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_flogn( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_flog10( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_flog2( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fabs( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fcosh( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fneg( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_facos( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fcos( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fgetexp( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fgetman( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fdiv( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fmod( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_frem( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fadd( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fmul( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fsgldiv( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fscale( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fsglmul( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fsub( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fsincos( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_fcmp( uae_u32 opcode, uae_u32 extra ); -PRIVATE void REGPARAM2 FFPU fpuop_do_ftst( uae_u32 opcode, uae_u32 extra ); - -// Get & Put floating-point values -PRIVATE int FFPU get_fp_value (uae_u32 opcode, uae_u32 extra, fpu_register & src) REGPARAM; -PRIVATE int FFPU put_fp_value (fpu_register const & value, uae_u32 opcode, uae_u32 extra) REGPARAM; -PRIVATE int FFPU get_fp_ad(uae_u32 opcode, uae_u32 * ad) REGPARAM; - -// Floating-point condition-based instruction handlers -PRIVATE int FFPU fpp_cond(uae_u32 opcode, int condition) REGPARAM; - -// Misc functions -PRIVATE void __inline__ FFPU set_host_fpu_control_word (); -PRIVATE void __inline__ FFPU SET_BSUN_ON_NAN (); -PRIVATE void __inline__ FFPU build_ex_status (); -PRIVATE void FFPU do_null_frestore (); -PRIVATE void FFPU build_fpp_opp_lookup_table (); -PRIVATE void FFPU set_constant ( fpu_register & f, char *name, double value, uae_s32 mult ); - -#endif /* FPU_X86_H */ diff --git a/BasiliskII/src/uae_cpu/fpu/fpu_x86_asm.h b/BasiliskII/src/uae_cpu/fpu/fpu_x86_asm.h deleted file mode 100644 index ecdecfbc..00000000 --- a/BasiliskII/src/uae_cpu/fpu/fpu_x86_asm.h +++ /dev/null @@ -1,72 +0,0 @@ -#define DEFINE_X86_MACRO(name, value) \ - asm(".local " #name "\n\t" #name " = " #value) - -DEFINE_X86_MACRO(BSUN, 0x00008000); -DEFINE_X86_MACRO(SNAN, 0x00004000); -DEFINE_X86_MACRO(OPERR, 0x00002000); -DEFINE_X86_MACRO(OVFL, 0x00001000); -DEFINE_X86_MACRO(UNFL, 0x00000800); -DEFINE_X86_MACRO(DZ, 0x00000400); -DEFINE_X86_MACRO(INEX2, 0x00000200); -DEFINE_X86_MACRO(INEX1, 0x00000100); -DEFINE_X86_MACRO(ACCR_IOP, 0x80); -DEFINE_X86_MACRO(ACCR_OVFL, 0x40); -DEFINE_X86_MACRO(ACCR_UNFL, 0x20); -DEFINE_X86_MACRO(ACCR_DZ, 0x10); -DEFINE_X86_MACRO(ACCR_INEX, 0x08); -DEFINE_X86_MACRO(ROUND_CONTROL_MASK, 0x30); -DEFINE_X86_MACRO(ROUND_TO_NEAREST, 0); -DEFINE_X86_MACRO(ROUND_TO_ZERO, 0x10); -DEFINE_X86_MACRO(ROUND_TO_NEGATIVE_INFINITY, 0x20); -DEFINE_X86_MACRO(ROUND_TO_POSITIVE_INFINITY, 0x30); -DEFINE_X86_MACRO(PRECISION_CONTROL_MASK, 0xC0); -DEFINE_X86_MACRO(PRECISION_CONTROL_EXTENDED, 0); -DEFINE_X86_MACRO(PRECISION_CONTROL_DOUBLE, 0x80); -DEFINE_X86_MACRO(PRECISION_CONTROL_SINGLE, 0x40); -DEFINE_X86_MACRO(PRECISION_CONTROL_UNDEFINED, 0xC0); -DEFINE_X86_MACRO(CW_RESET, 0x0040); -DEFINE_X86_MACRO(CW_FINIT, 0x037F); -DEFINE_X86_MACRO(SW_RESET, 0x0000); -DEFINE_X86_MACRO(SW_FINIT, 0x0000); -DEFINE_X86_MACRO(TW_RESET, 0x5555); -DEFINE_X86_MACRO(TW_FINIT, 0x0FFF); -DEFINE_X86_MACRO(CW_X, 0x1000); -DEFINE_X86_MACRO(CW_RC_ZERO, 0x0C00); -DEFINE_X86_MACRO(CW_RC_UP, 0x0800); -DEFINE_X86_MACRO(CW_RC_DOWN, 0x0400); -DEFINE_X86_MACRO(CW_RC_NEAR, 0x0000); -DEFINE_X86_MACRO(CW_PC_EXTENDED, 0x0300); -DEFINE_X86_MACRO(CW_PC_DOUBLE, 0x0200); -DEFINE_X86_MACRO(CW_PC_RESERVED, 0x0100); -DEFINE_X86_MACRO(CW_PC_SINGLE, 0x0000); -DEFINE_X86_MACRO(CW_PM, 0x0020); -DEFINE_X86_MACRO(CW_UM, 0x0010); -DEFINE_X86_MACRO(CW_OM, 0x0008); -DEFINE_X86_MACRO(CW_ZM, 0x0004); -DEFINE_X86_MACRO(CW_DM, 0x0002); -DEFINE_X86_MACRO(CW_IM, 0x0001); -DEFINE_X86_MACRO(SW_B, 0x8000); -DEFINE_X86_MACRO(SW_C3, 0x4000); -DEFINE_X86_MACRO(SW_TOP_7, 0x3800); -DEFINE_X86_MACRO(SW_TOP_6, 0x3000); -DEFINE_X86_MACRO(SW_TOP_5, 0x2800); -DEFINE_X86_MACRO(SW_TOP_4, 0x2000); -DEFINE_X86_MACRO(SW_TOP_3, 0x1800); -DEFINE_X86_MACRO(SW_TOP_2, 0x1000); -DEFINE_X86_MACRO(SW_TOP_1, 0x0800); -DEFINE_X86_MACRO(SW_TOP_0, 0x0000); -DEFINE_X86_MACRO(SW_C2, 0x0400); -DEFINE_X86_MACRO(SW_C1, 0x0200); -DEFINE_X86_MACRO(SW_C0, 0x0100); -DEFINE_X86_MACRO(SW_ES, 0x0080); -DEFINE_X86_MACRO(SW_SF, 0x0040); -DEFINE_X86_MACRO(SW_PE, 0x0020); -DEFINE_X86_MACRO(SW_UE, 0x0010); -DEFINE_X86_MACRO(SW_OE, 0x0008); -DEFINE_X86_MACRO(SW_ZE, 0x0004); -DEFINE_X86_MACRO(SW_DE, 0x0002); -DEFINE_X86_MACRO(SW_IE, 0x0001); -DEFINE_X86_MACRO(X86_ROUNDING_MODE, 0x0C00); -DEFINE_X86_MACRO(X86_ROUNDING_PRECISION, 0x0300); - -#undef DEFINE_X86_MACRO diff --git a/BasiliskII/src/uae_cpu/fpu/mathlib.h b/BasiliskII/src/uae_cpu/fpu/mathlib.h index 2363af56..755c43d9 100644 --- a/BasiliskII/src/uae_cpu/fpu/mathlib.h +++ b/BasiliskII/src/uae_cpu/fpu/mathlib.h @@ -49,12 +49,6 @@ // Use ISO C99 extended-precision math functions (glibc 2.1+) #define FPU_USE_ISO_C99 1 -// NOTE: this is irrelevant on Win32 platforms since the MS libraries -// don't support extended-precision floating-point computations -#if defined(WIN32) && USE_LONG_DOUBLE -#undef FPU_USE_ISO_C99 -#endif - // Use faster implementation of math functions, but this could cause // some incorrect results (?) #ifdef _MSC_VER diff --git a/BasiliskII/src/uae_cpu/gencpu.c b/BasiliskII/src/uae_cpu/gencpu.c index 1653adab..3030258f 100644 --- a/BasiliskII/src/uae_cpu/gencpu.c +++ b/BasiliskII/src/uae_cpu/gencpu.c @@ -2188,15 +2188,13 @@ static void gen_opcode (unsigned long int opcode) case i_CINVP: case i_CINVA: /* gb-- srcreg now contains the cache field */ - printf ("\tif (srcreg&0x2)\n"); - printf ("\t\tflush_icache(%d);\n", 30 + ((opcode >> 3) & 3)); + break; case i_CPUSHL: case i_CPUSHP: case i_CPUSHA: /* gb-- srcreg now contains the cache field */ - printf ("\tif (srcreg&0x2)\n"); - printf ("\t\tflush_icache(%d);\n", 40 + ((opcode >> 3) & 3)); + break; case i_MOVE16: if ((opcode & 0xfff8) == 0xf620) { @@ -2262,7 +2260,6 @@ static void generate_includes (FILE * f) fprintf (f, "#include \"memory.h\"\n"); fprintf (f, "#include \"readcpu.h\"\n"); fprintf (f, "#include \"newcpu.h\"\n"); - fprintf (f, "#include \"compiler/compemu.h\"\n"); fprintf (f, "#include \"fpu/fpu.h\"\n"); fprintf (f, "#include \"cputbl.h\"\n"); @@ -2541,18 +2538,5 @@ int main (int argc, char **argv) fclose (stblfile); fflush (out); - /* For build systems (IDEs mainly) that don't make it easy to compile the - * same file twice with different settings. */ - stblfile = fopen ("cpustbl_nf.cpp", "w"); - out = freopen ("cpuemu_nf.cpp", "w", stdout); - - fprintf (stblfile, "#define NOFLAGS\n"); - fprintf (stblfile, "#include \"cpustbl.cpp\"\n"); - fclose (stblfile); - - printf ("#define NOFLAGS\n"); - printf ("#include \"cpuemu.cpp\"\n"); - fflush (out); - return 0; } diff --git a/BasiliskII/src/uae_cpu/memory.cpp b/BasiliskII/src/uae_cpu/memory.cpp deleted file mode 100644 index 676a2436..00000000 --- a/BasiliskII/src/uae_cpu/memory.cpp +++ /dev/null @@ -1,585 +0,0 @@ -/* - * UAE - The Un*x Amiga Emulator - * - * Memory management - * - * (c) 1995 Bernd Schmidt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include "sysdeps.h" - -#include "cpu_emulation.h" -#include "main.h" -#include "video.h" - -#include "m68k.h" -#include "memory.h" -#include "readcpu.h" -#include "newcpu.h" - -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING - -static bool illegal_mem = false; - -#ifdef SAVE_MEMORY_BANKS -addrbank *mem_banks[65536]; -#else -addrbank mem_banks[65536]; -#endif - -#ifdef WORDS_BIGENDIAN -# define swap_words(X) (X) -#else -# define swap_words(X) (((X) >> 16) | ((X) << 16)) -#endif - -#ifdef NO_INLINE_MEMORY_ACCESS -uae_u32 longget (uaecptr addr) -{ - return call_mem_get_func (get_mem_bank (addr).lget, addr); -} -uae_u32 wordget (uaecptr addr) -{ - return call_mem_get_func (get_mem_bank (addr).wget, addr); -} -uae_u32 byteget (uaecptr addr) -{ - return call_mem_get_func (get_mem_bank (addr).bget, addr); -} -void longput (uaecptr addr, uae_u32 l) -{ - call_mem_put_func (get_mem_bank (addr).lput, addr, l); -} -void wordput (uaecptr addr, uae_u32 w) -{ - call_mem_put_func (get_mem_bank (addr).wput, addr, w); -} -void byteput (uaecptr addr, uae_u32 b) -{ - call_mem_put_func (get_mem_bank (addr).bput, addr, b); -} -#endif - -/* A dummy bank that only contains zeros */ - -static uae_u32 REGPARAM2 dummy_lget (uaecptr) REGPARAM; -static uae_u32 REGPARAM2 dummy_wget (uaecptr) REGPARAM; -static uae_u32 REGPARAM2 dummy_bget (uaecptr) REGPARAM; -static void REGPARAM2 dummy_lput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 dummy_wput (uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 dummy_bput (uaecptr, uae_u32) REGPARAM; - -uae_u32 REGPARAM2 dummy_lget (uaecptr addr) -{ - if (illegal_mem) - write_log ("Illegal lget at %08lx\n", addr); - - return 0; -} - -uae_u32 REGPARAM2 dummy_wget (uaecptr addr) -{ - if (illegal_mem) - write_log ("Illegal wget at %08lx\n", addr); - - return 0; -} - -uae_u32 REGPARAM2 dummy_bget (uaecptr addr) -{ - if (illegal_mem) - write_log ("Illegal bget at %08lx\n", addr); - - return 0; -} - -void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l) -{ - if (illegal_mem) - write_log ("Illegal lput at %08lx\n", addr); -} -void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w) -{ - if (illegal_mem) - write_log ("Illegal wput at %08lx\n", addr); -} -void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b) -{ - if (illegal_mem) - write_log ("Illegal bput at %08lx\n", addr); -} - -/* Mac RAM (32 bit addressing) */ - -static uae_u32 REGPARAM2 ram_lget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 ram_wget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 ram_bget(uaecptr) REGPARAM; -static void REGPARAM2 ram_lput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 ram_wput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 ram_bput(uaecptr, uae_u32) REGPARAM; -static uae_u8 *REGPARAM2 ram_xlate(uaecptr addr) REGPARAM; - -static uintptr RAMBaseDiff; // RAMBaseHost - RAMBaseMac - -uae_u32 REGPARAM2 ram_lget(uaecptr addr) -{ - uae_u32 *m; - m = (uae_u32 *)(RAMBaseDiff + addr); - return do_get_mem_long(m); -} - -uae_u32 REGPARAM2 ram_wget(uaecptr addr) -{ - uae_u16 *m; - m = (uae_u16 *)(RAMBaseDiff + addr); - return do_get_mem_word(m); -} - -uae_u32 REGPARAM2 ram_bget(uaecptr addr) -{ - return (uae_u32)*(uae_u8 *)(RAMBaseDiff + addr); -} - -void REGPARAM2 ram_lput(uaecptr addr, uae_u32 l) -{ - uae_u32 *m; - m = (uae_u32 *)(RAMBaseDiff + addr); - do_put_mem_long(m, l); -} - -void REGPARAM2 ram_wput(uaecptr addr, uae_u32 w) -{ - uae_u16 *m; - m = (uae_u16 *)(RAMBaseDiff + addr); - do_put_mem_word(m, w); -} - -void REGPARAM2 ram_bput(uaecptr addr, uae_u32 b) -{ - *(uae_u8 *)(RAMBaseDiff + addr) = b; -} - -uae_u8 *REGPARAM2 ram_xlate(uaecptr addr) -{ - return (uae_u8 *)(RAMBaseDiff + addr); -} - -/* Mac RAM (24 bit addressing) */ - -static uae_u32 REGPARAM2 ram24_lget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 ram24_wget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 ram24_bget(uaecptr) REGPARAM; -static void REGPARAM2 ram24_lput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 ram24_wput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 ram24_bput(uaecptr, uae_u32) REGPARAM; -static uae_u8 *REGPARAM2 ram24_xlate(uaecptr addr) REGPARAM; - -uae_u32 REGPARAM2 ram24_lget(uaecptr addr) -{ - uae_u32 *m; - m = (uae_u32 *)(RAMBaseDiff + (addr & 0xffffff)); - return do_get_mem_long(m); -} - -uae_u32 REGPARAM2 ram24_wget(uaecptr addr) -{ - uae_u16 *m; - m = (uae_u16 *)(RAMBaseDiff + (addr & 0xffffff)); - return do_get_mem_word(m); -} - -uae_u32 REGPARAM2 ram24_bget(uaecptr addr) -{ - return (uae_u32)*(uae_u8 *)(RAMBaseDiff + (addr & 0xffffff)); -} - -void REGPARAM2 ram24_lput(uaecptr addr, uae_u32 l) -{ - uae_u32 *m; - m = (uae_u32 *)(RAMBaseDiff + (addr & 0xffffff)); - do_put_mem_long(m, l); -} - -void REGPARAM2 ram24_wput(uaecptr addr, uae_u32 w) -{ - uae_u16 *m; - m = (uae_u16 *)(RAMBaseDiff + (addr & 0xffffff)); - do_put_mem_word(m, w); -} - -void REGPARAM2 ram24_bput(uaecptr addr, uae_u32 b) -{ - *(uae_u8 *)(RAMBaseDiff + (addr & 0xffffff)) = b; -} - -uae_u8 *REGPARAM2 ram24_xlate(uaecptr addr) -{ - return (uae_u8 *)(RAMBaseDiff + (addr & 0xffffff)); -} - -/* Mac ROM (32 bit addressing) */ - -static uae_u32 REGPARAM2 rom_lget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 rom_wget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 rom_bget(uaecptr) REGPARAM; -static void REGPARAM2 rom_lput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 rom_wput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 rom_bput(uaecptr, uae_u32) REGPARAM; -static uae_u8 *REGPARAM2 rom_xlate(uaecptr addr) REGPARAM; - -static uintptr ROMBaseDiff; // ROMBaseHost - ROMBaseMac - -uae_u32 REGPARAM2 rom_lget(uaecptr addr) -{ - uae_u32 *m; - m = (uae_u32 *)(ROMBaseDiff + addr); - return do_get_mem_long(m); -} - -uae_u32 REGPARAM2 rom_wget(uaecptr addr) -{ - uae_u16 *m; - m = (uae_u16 *)(ROMBaseDiff + addr); - return do_get_mem_word(m); -} - -uae_u32 REGPARAM2 rom_bget(uaecptr addr) -{ - return (uae_u32)*(uae_u8 *)(ROMBaseDiff + addr); -} - -void REGPARAM2 rom_lput(uaecptr addr, uae_u32 b) -{ - if (illegal_mem) - write_log ("Illegal ROM lput at %08lx\n", addr); -} - -void REGPARAM2 rom_wput(uaecptr addr, uae_u32 b) -{ - if (illegal_mem) - write_log ("Illegal ROM wput at %08lx\n", addr); -} - -void REGPARAM2 rom_bput(uaecptr addr, uae_u32 b) -{ - if (illegal_mem) - write_log ("Illegal ROM bput at %08lx\n", addr); -} - -uae_u8 *REGPARAM2 rom_xlate(uaecptr addr) -{ - return (uae_u8 *)(ROMBaseDiff + addr); -} - -/* Mac ROM (24 bit addressing) */ - -static uae_u32 REGPARAM2 rom24_lget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 rom24_wget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 rom24_bget(uaecptr) REGPARAM; -static uae_u8 *REGPARAM2 rom24_xlate(uaecptr addr) REGPARAM; - -uae_u32 REGPARAM2 rom24_lget(uaecptr addr) -{ - uae_u32 *m; - m = (uae_u32 *)(ROMBaseDiff + (addr & 0xffffff)); - return do_get_mem_long(m); -} - -uae_u32 REGPARAM2 rom24_wget(uaecptr addr) -{ - uae_u16 *m; - m = (uae_u16 *)(ROMBaseDiff + (addr & 0xffffff)); - return do_get_mem_word(m); -} - -uae_u32 REGPARAM2 rom24_bget(uaecptr addr) -{ - return (uae_u32)*(uae_u8 *)(ROMBaseDiff + (addr & 0xffffff)); -} - -uae_u8 *REGPARAM2 rom24_xlate(uaecptr addr) -{ - return (uae_u8 *)(ROMBaseDiff + (addr & 0xffffff)); -} - -/* Frame buffer */ - -static uae_u32 REGPARAM2 frame_direct_lget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 frame_direct_wget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 frame_direct_bget(uaecptr) REGPARAM; -static void REGPARAM2 frame_direct_lput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 frame_direct_wput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 frame_direct_bput(uaecptr, uae_u32) REGPARAM; - -static uae_u32 REGPARAM2 frame_host_555_lget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 frame_host_555_wget(uaecptr) REGPARAM; -static void REGPARAM2 frame_host_555_lput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 frame_host_555_wput(uaecptr, uae_u32) REGPARAM; - -static uae_u32 REGPARAM2 frame_host_565_lget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 frame_host_565_wget(uaecptr) REGPARAM; -static void REGPARAM2 frame_host_565_lput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 frame_host_565_wput(uaecptr, uae_u32) REGPARAM; - -static uae_u32 REGPARAM2 frame_host_888_lget(uaecptr) REGPARAM; -static void REGPARAM2 frame_host_888_lput(uaecptr, uae_u32) REGPARAM; - -static uae_u8 *REGPARAM2 frame_xlate(uaecptr addr) REGPARAM; - -static uintptr FrameBaseDiff; // MacFrameBaseHost - MacFrameBaseMac - -uae_u32 REGPARAM2 frame_direct_lget(uaecptr addr) -{ - uae_u32 *m; - m = (uae_u32 *)(FrameBaseDiff + addr); - return do_get_mem_long(m); -} - -uae_u32 REGPARAM2 frame_direct_wget(uaecptr addr) -{ - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + addr); - return do_get_mem_word(m); -} - -uae_u32 REGPARAM2 frame_direct_bget(uaecptr addr) -{ - return (uae_u32)*(uae_u8 *)(FrameBaseDiff + addr); -} - -void REGPARAM2 frame_direct_lput(uaecptr addr, uae_u32 l) -{ - uae_u32 *m; - m = (uae_u32 *)(FrameBaseDiff + addr); - do_put_mem_long(m, l); -} - -void REGPARAM2 frame_direct_wput(uaecptr addr, uae_u32 w) -{ - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + addr); - do_put_mem_word(m, w); -} - -void REGPARAM2 frame_direct_bput(uaecptr addr, uae_u32 b) -{ - *(uae_u8 *)(FrameBaseDiff + addr) = b; -} - -uae_u32 REGPARAM2 frame_host_555_lget(uaecptr addr) -{ - uae_u32 *m, l; - m = (uae_u32 *)(FrameBaseDiff + addr); - l = *m; - return swap_words(l); -} - -uae_u32 REGPARAM2 frame_host_555_wget(uaecptr addr) -{ - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + addr); - return *m; -} - -void REGPARAM2 frame_host_555_lput(uaecptr addr, uae_u32 l) -{ - uae_u32 *m; - m = (uae_u32 *)(FrameBaseDiff + addr); - *m = swap_words(l); -} - -void REGPARAM2 frame_host_555_wput(uaecptr addr, uae_u32 w) -{ - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + addr); - *m = w; -} - -uae_u32 REGPARAM2 frame_host_565_lget(uaecptr addr) -{ - uae_u32 *m, l; - m = (uae_u32 *)(FrameBaseDiff + addr); - l = *m; - l = (l & 0x001f001f) | ((l >> 1) & 0x7fe07fe0); - return swap_words(l); -} - -uae_u32 REGPARAM2 frame_host_565_wget(uaecptr addr) -{ - uae_u16 *m, w; - m = (uae_u16 *)(FrameBaseDiff + addr); - w = *m; - return (w & 0x1f) | ((w >> 1) & 0x7fe0); -} - -void REGPARAM2 frame_host_565_lput(uaecptr addr, uae_u32 l) -{ - uae_u32 *m; - m = (uae_u32 *)(FrameBaseDiff + addr); - l = (l & 0x001f001f) | ((l << 1) & 0xffc0ffc0); - *m = swap_words(l); -} - -void REGPARAM2 frame_host_565_wput(uaecptr addr, uae_u32 w) -{ - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + addr); - *m = (w & 0x1f) | ((w << 1) & 0xffc0); -} - -uae_u32 REGPARAM2 frame_host_888_lget(uaecptr addr) -{ - uae_u32 *m, l; - m = (uae_u32 *)(FrameBaseDiff + addr); - return *m; -} - -void REGPARAM2 frame_host_888_lput(uaecptr addr, uae_u32 l) -{ - uae_u32 *m; - m = (uae_u32 *)(MacFrameBaseHost + addr - MacFrameBaseMac); - *m = l; -} - -uae_u8 *REGPARAM2 frame_xlate(uaecptr addr) -{ - return (uae_u8 *)(FrameBaseDiff + addr); -} - -/* Default memory access functions */ - -uae_u8 *REGPARAM2 default_xlate (uaecptr a) -{ - write_log("Your Mac program just did something terribly stupid\n"); - return NULL; -} - -/* Address banks */ - -addrbank dummy_bank = { - dummy_lget, dummy_wget, dummy_bget, - dummy_lput, dummy_wput, dummy_bput, - default_xlate -}; - -addrbank ram_bank = { - ram_lget, ram_wget, ram_bget, - ram_lput, ram_wput, ram_bput, - ram_xlate -}; - -addrbank ram24_bank = { - ram24_lget, ram24_wget, ram24_bget, - ram24_lput, ram24_wput, ram24_bput, - ram24_xlate -}; - -addrbank rom_bank = { - rom_lget, rom_wget, rom_bget, - rom_lput, rom_wput, rom_bput, - rom_xlate -}; - -addrbank rom24_bank = { - rom24_lget, rom24_wget, rom24_bget, - rom_lput, rom_wput, rom_bput, - rom24_xlate -}; - -addrbank frame_direct_bank = { - frame_direct_lget, frame_direct_wget, frame_direct_bget, - frame_direct_lput, frame_direct_wput, frame_direct_bput, - frame_xlate -}; - -addrbank frame_host_555_bank = { - frame_host_555_lget, frame_host_555_wget, frame_direct_bget, - frame_host_555_lput, frame_host_555_wput, frame_direct_bput, - frame_xlate -}; - -addrbank frame_host_565_bank = { - frame_host_565_lget, frame_host_565_wget, frame_direct_bget, - frame_host_565_lput, frame_host_565_wput, frame_direct_bput, - frame_xlate -}; - -addrbank frame_host_888_bank = { - frame_host_888_lget, frame_direct_wget, frame_direct_bget, - frame_host_888_lput, frame_direct_wput, frame_direct_bput, - frame_xlate -}; - -void memory_init(void) -{ - for(long i=0; i<65536; i++) - put_mem_bank(i<<16, &dummy_bank); - - // Limit RAM size to not overlap ROM - uint32 ram_size = RAMSize > ROMBaseMac ? ROMBaseMac : RAMSize; - - RAMBaseDiff = (uintptr)RAMBaseHost - (uintptr)RAMBaseMac; - ROMBaseDiff = (uintptr)ROMBaseHost - (uintptr)ROMBaseMac; - FrameBaseDiff = (uintptr)MacFrameBaseHost - (uintptr)MacFrameBaseMac; - - // Map RAM and ROM - if (TwentyFourBitAddressing) { - map_banks(&ram24_bank, RAMBaseMac >> 16, ram_size >> 16); - map_banks(&rom24_bank, ROMBaseMac >> 16, ROMSize >> 16); - } else { - map_banks(&ram_bank, RAMBaseMac >> 16, ram_size >> 16); - map_banks(&rom_bank, ROMBaseMac >> 16, ROMSize >> 16); - } - - // Map frame buffer - switch (MacFrameLayout) { - case FLAYOUT_DIRECT: - map_banks(&frame_direct_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); - break; - case FLAYOUT_HOST_555: - map_banks(&frame_host_555_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); - break; - case FLAYOUT_HOST_565: - map_banks(&frame_host_565_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); - break; - case FLAYOUT_HOST_888: - map_banks(&frame_host_888_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); - break; - } -} - -void map_banks(addrbank *bank, int start, int size) -{ - int bnr; - unsigned long int hioffs = 0, endhioffs = 0x100; - - if (start >= 0x100) { - for (bnr = start; bnr < start + size; bnr++) - put_mem_bank (bnr << 16, bank); - return; - } - if (TwentyFourBitAddressing) endhioffs = 0x10000; - for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) - for (bnr = start; bnr < start+size; bnr++) - put_mem_bank((bnr + hioffs) << 16, bank); -} - -#endif /* !REAL_ADDRESSING && !DIRECT_ADDRESSING */ - diff --git a/BasiliskII/src/uae_cpu/memory.h b/BasiliskII/src/uae_cpu/memory.h index 75a6303b..670c2ee7 100644 --- a/BasiliskII/src/uae_cpu/memory.h +++ b/BasiliskII/src/uae_cpu/memory.h @@ -23,107 +23,11 @@ #ifndef UAE_MEMORY_H #define UAE_MEMORY_H -#if !DIRECT_ADDRESSING && !REAL_ADDRESSING - -/* Enabling this adds one additional native memory reference per 68k memory - * access, but saves one shift (on the x86). Enabling this is probably - * better for the cache. My favourite benchmark (PP2) doesn't show a - * difference, so I leave this enabled. */ - -#if 1 || defined SAVE_MEMORY -#define SAVE_MEMORY_BANKS -#endif - -typedef uae_u32 (REGPARAM2 *mem_get_func)(uaecptr) REGPARAM; -typedef void (REGPARAM2 *mem_put_func)(uaecptr, uae_u32) REGPARAM; -typedef uae_u8 *(REGPARAM2 *xlate_func)(uaecptr) REGPARAM; - -#undef DIRECT_MEMFUNCS_SUCCESSFUL - -#ifndef CAN_MAP_MEMORY -#undef USE_COMPILER -#endif - -#if defined(USE_COMPILER) && !defined(USE_MAPPED_MEMORY) -#define USE_MAPPED_MEMORY -#endif - -typedef struct { - /* These ones should be self-explanatory... */ - mem_get_func lget, wget, bget; - mem_put_func lput, wput, bput; - /* Use xlateaddr to translate an Amiga address to a uae_u8 * that can - * be used to address memory without calling the wget/wput functions. - * This doesn't work for all memory banks, so this function may call - * abort(). */ - xlate_func xlateaddr; -} addrbank; - -extern uae_u8 filesysory[65536]; - -extern addrbank ram_bank; // Mac RAM -extern addrbank rom_bank; // Mac ROM -extern addrbank frame_bank; // Frame buffer - -/* Default memory access functions */ - -extern uae_u8 *REGPARAM2 default_xlate(uaecptr addr) REGPARAM; - -#define bankindex(addr) (((uaecptr)(addr)) >> 16) - -#ifdef SAVE_MEMORY_BANKS -extern addrbank *mem_banks[65536]; -#define get_mem_bank(addr) (*mem_banks[bankindex(addr)]) -#define put_mem_bank(addr, b) (mem_banks[bankindex(addr)] = (b)) -#else -extern addrbank mem_banks[65536]; -#define get_mem_bank(addr) (mem_banks[bankindex(addr)]) -#define put_mem_bank(addr, b) (mem_banks[bankindex(addr)] = *(b)) -#endif - -extern void memory_init(void); -extern void map_banks(addrbank *bank, int first, int count); - -#ifndef NO_INLINE_MEMORY_ACCESS - -#define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr)) -#define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr)) -#define byteget(addr) (call_mem_get_func(get_mem_bank(addr).bget, addr)) -#define longput(addr,l) (call_mem_put_func(get_mem_bank(addr).lput, addr, l)) -#define wordput(addr,w) (call_mem_put_func(get_mem_bank(addr).wput, addr, w)) -#define byteput(addr,b) (call_mem_put_func(get_mem_bank(addr).bput, addr, b)) - -#else - -extern uae_u32 longget(uaecptr addr); -extern uae_u32 wordget(uaecptr addr); -extern uae_u32 byteget(uaecptr addr); -extern void longput(uaecptr addr, uae_u32 l); -extern void wordput(uaecptr addr, uae_u32 w); -extern void byteput(uaecptr addr, uae_u32 b); - -#endif - -#ifndef MD_HAVE_MEM_1_FUNCS - -#define longget_1 longget -#define wordget_1 wordget -#define byteget_1 byteget -#define longput_1 longput -#define wordput_1 wordput -#define byteput_1 byteput - -#endif - -#endif /* !DIRECT_ADDRESSING && !REAL_ADDRESSING */ - -#if REAL_ADDRESSING -const uintptr MEMBaseDiff = 0; -#elif DIRECT_ADDRESSING +#if DIRECT_ADDRESSING extern uintptr MEMBaseDiff; #endif -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING static __inline__ uae_u8 *do_get_real_address(uaecptr addr) { return (uae_u8 *)MEMBaseDiff + addr; @@ -170,38 +74,7 @@ static __inline__ uae_u32 get_virtual_address(uae_u8 *addr) { return do_get_virtual_address(addr); } -#else -static __inline__ uae_u32 get_long(uaecptr addr) -{ - return longget_1(addr); -} -static __inline__ uae_u32 get_word(uaecptr addr) -{ - return wordget_1(addr); -} -static __inline__ uae_u32 get_byte(uaecptr addr) -{ - return byteget_1(addr); -} -static __inline__ void put_long(uaecptr addr, uae_u32 l) -{ - longput_1(addr, l); -} -static __inline__ void put_word(uaecptr addr, uae_u32 w) -{ - wordput_1(addr, w); -} -static __inline__ void put_byte(uaecptr addr, uae_u32 b) -{ - byteput_1(addr, b); -} -static __inline__ uae_u8 *get_real_address(uaecptr addr) -{ - return get_mem_bank(addr).xlateaddr(addr); -} -/* gb-- deliberately not implemented since it shall not be used... */ -extern uae_u32 get_virtual_address(uae_u8 *addr); -#endif /* DIRECT_ADDRESSING || REAL_ADDRESSING */ +#endif /* DIRECT_ADDRESSING */ #endif /* MEMORY_H */ diff --git a/BasiliskII/src/uae_cpu/newcpu.cpp b/BasiliskII/src/uae_cpu/newcpu.cpp index 4e45817b..a88ebf5e 100644 --- a/BasiliskII/src/uae_cpu/newcpu.cpp +++ b/BasiliskII/src/uae_cpu/newcpu.cpp @@ -36,17 +36,12 @@ extern int intlev(void); // From baisilisk_glue.cpp #include "memory.h" #include "readcpu.h" #include "newcpu.h" -#include "compiler/compemu.h" #include "fpu/fpu.h" #if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS) B2_mutex *spcflags_lock = NULL; #endif -#if ENABLE_MON -#include "mon.h" -#include "mon_disass.h" -#endif bool quit_program = false; struct flag_struct regflags; @@ -122,20 +117,12 @@ static void dump_log(void) #else fprintf(f, " | "); #endif -#if ENABLE_MON - disass_68k(f, pc); -#endif + } fclose(f); } #endif -#if ENABLE_MON -static void dump_regs(void) -{ - m68k_dumpstate(NULL); -} -#endif #define COUNT_INSTRS 0 @@ -308,7 +295,7 @@ static int backup_pointer = 0; static long int m68kpc_offset; int lastint_no; -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING #define get_ibyte_1(o) get_byte(get_virtual_address(regs.pc_p) + (o) + 1) #define get_iword_1(o) get_word(get_virtual_address(regs.pc_p) + (o)) #define get_ilong_1(o) get_long(get_virtual_address(regs.pc_p) + (o)) @@ -860,16 +847,7 @@ int m68k_move2c (int regno, uae_u32 *regp) case 1: regs.dfc = *regp & 7; break; case 2: cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000); -#if USE_JIT - if (CPUType < 4) { - set_cache_state(cacr&1); - if (*regp & 0x08) - flush_icache(1); - } - else { - set_cache_state(cacr&0x8000); - } -#endif + break; case 3: tc = *regp & 0xc000; break; case 4: itt0 = *regp & 0xffffe364; break; @@ -1209,17 +1187,6 @@ void m68k_reset (void) memset(log, 0, sizeof(log)); #endif -#if ENABLE_MON - static bool first_time = true; - if (first_time) { - first_time = false; - mon_add_command("regs", dump_regs, "regs Dump m68k emulator registers\n"); -#if FLIGHT_RECORDER - // Install "log" command in mon - mon_add_command("log", dump_log, "log Dump m68k emulation log\n"); -#endif - } -#endif } void m68k_emulop_return(void) @@ -1263,9 +1230,6 @@ void REGPARAM2 op_illg (uae_u32 opcode) } write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); -#if USE_JIT && JIT_DEBUG - compiler_dumpstate(); -#endif Exception (4,0); return; @@ -1323,18 +1287,7 @@ static void do_trace (void) int m68k_do_specialties (void) { -#if USE_JIT - // Block was compiled - SPCFLAGS_CLEAR( SPCFLAG_JIT_END_COMPILE ); - // Retain the request to get out of compiled code until - // we reached the toplevel execution, i.e. the one that - // can compile then run compiled code. This also means - // we processed all (nested) EmulOps - if ((m68k_execute_depth == 0) && SPCFLAGS_TEST( SPCFLAG_JIT_EXEC_RETURN )) - SPCFLAGS_CLEAR( SPCFLAG_JIT_EXEC_RETURN ); -#endif - if (SPCFLAGS_TEST( SPCFLAG_DOTRACE )) { Exception (9,last_trace_ad); } @@ -1389,17 +1342,13 @@ void m68k_do_execute (void) void m68k_execute (void) { -#if USE_JIT - ++m68k_execute_depth; -#endif + for (;;) { if (quit_program) break; m68k_do_execute(); } -#if USE_JIT - --m68k_execute_depth; -#endif + } static void m68k_verify (uaecptr addr, uaecptr *nextpc) diff --git a/BasiliskII/src/uae_cpu/newcpu.h b/BasiliskII/src/uae_cpu/newcpu.h index 1d07c36b..a15d79d8 100644 --- a/BasiliskII/src/uae_cpu/newcpu.h +++ b/BasiliskII/src/uae_cpu/newcpu.h @@ -63,16 +63,6 @@ struct cputbl { extern cpuop_func *cpufunctbl[65536] ASM_SYM("cpufunctbl"); -#if USE_JIT -typedef void compop_func (uae_u32) REGPARAM; - -struct comptbl { - compop_func *handler; - uae_u32 specific; - uae_u32 opcode; -}; -#endif - extern void REGPARAM2 op_illg (uae_u32) REGPARAM; typedef char flagtype; @@ -200,7 +190,7 @@ static __inline__ uae_u32 next_ilong (void) static __inline__ void m68k_setpc (uaecptr newpc) { -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING regs.pc_p = get_real_address(newpc); #else regs.pc_p = regs.pc_oldp = get_real_address(newpc); @@ -210,7 +200,7 @@ static __inline__ void m68k_setpc (uaecptr newpc) static __inline__ uaecptr m68k_getpc (void) { -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING return get_virtual_address(regs.pc_p); #else return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp); @@ -300,9 +290,7 @@ extern void m68k_record_step(uaecptr) REGPARAM; #endif extern void m68k_do_execute(void); extern void m68k_execute(void); -#if USE_JIT -extern void m68k_compile_execute(void); -#endif + #ifdef USE_CPU_EMUL_SERVICES extern int32 emulated_ticks; extern void cpu_do_check_ticks(void); diff --git a/BasiliskII/src/uae_cpu/spcflags.h b/BasiliskII/src/uae_cpu/spcflags.h index 3c3fc032..494f4fcc 100644 --- a/BasiliskII/src/uae_cpu/spcflags.h +++ b/BasiliskII/src/uae_cpu/spcflags.h @@ -32,14 +32,10 @@ enum { SPCFLAG_TRACE = 0x08, SPCFLAG_DOTRACE = 0x10, SPCFLAG_DOINT = 0x20, -#if USE_JIT - SPCFLAG_JIT_END_COMPILE = 0x40, - SPCFLAG_JIT_EXEC_RETURN = 0x80, -#else + SPCFLAG_JIT_END_COMPILE = 0, SPCFLAG_JIT_EXEC_RETURN = 0, -#endif - + SPCFLAG_ALL = SPCFLAG_STOP | SPCFLAG_INT | SPCFLAG_BRK diff --git a/BasiliskII/src/user_strings.cpp b/BasiliskII/src/user_strings.cpp index f4861825..81614a24 100644 --- a/BasiliskII/src/user_strings.cpp +++ b/BasiliskII/src/user_strings.cpp @@ -33,11 +33,7 @@ #include "sysdeps.h" #include "user_strings.h" -#ifdef __BEOS__ -#define ELLIPSIS "\xE2\x80\xA6" -#else #define ELLIPSIS "..." -#endif // Common string definitions