
*
* Constants
TDRE		EQU	$80
RDRF		EQU	$20
IRV		EQU	$10
MDA		EQU	$20
SMOD		EQU	$40
mS10		EQU	4000
uS500		EQU	200
uS30		EQU	12
uS15		EQU	6
DATAIN		EQU	$01
CLOCKIN		EQU	$02
DATAOUT		EQU	$10
CLOCKOUT	EQU	$20
LOOPBACK	EQU	$40
*
*Registers
PORTA		EQU	$00
BAUD		EQU	$2B
SCCR1		EQU	$2C
SCCR2		EQU	$2D
SCSR		EQU	$2E
SCDR		EQU	$2F
PPROG		EQU	$3B
HPRIO		EQU	$3C
CONFIG		EQU	$103F
*
*
* Program
		ORG	$B600
		LDS	#$FF
		LDX	#$1000
		CLR	SCCR1,X
		LDD	#$330C			1200 8 n 1
		STAA	BAUD,X
		STAB	SCCR2,X
*
*	IBM Keyboard startup sequence
*
*		BCLR	$1000,#16		Data high   (Green off)
*		BCLR	$1000,#32		Clock high  (Yellow off)
*
*	SUN keyboard startup sequence
*		
*		LDAB	#01			Reset
*		JSR	WRITEC
*		JSR	WAIT500mS		Wait 1000mS
*		JSR	WAIT500mS
*		LDAB	#03			Bell off
*		JSR	WRITEC
*		LDAB	#11			KeyClick off
*		JSR	WRITEC

*
*	Disable loopback
*
		BSET	PORTA,X #LOOPBACK

*
*	INIT vars
*
RESET		LDD	#36000			Delay  0.5 sekund
		STD	$0			Delay
		CLRB				Char
		STAB	$6
		STAB	$7
RESET1		LDY	#4400			Rate and init Y
		STY	$2			Rate

*
*	Main Loop
*
*	Totalt 28 cpu cykler pa ett varv => 71429 varv = 1 sekund
*
MAIN		DEY
		BEQ	AUTOREPEAT
		BRSET	SCSR,X #RDRF READSUN	Check for data on serial
		BRCLR	PORTA,X #CLOCKIN MAIN	Continue if Clock is high
		BRSET	PORTA,X #DATAIN MAIN	Continue if Data is low 

*
*	Read data from PC
*						(PC wants to send something)
		JSR	FROMIBM			Get byte from PC
		LDAA	$7
		STAB	$7
		CMPA	#$ED
		BEQ	READPC2
		CMPB	#$FF			Check if Reset
		BNE	READPC1
		LDAB	#$FA
		JSR	TOIBM
		LDAB	#$AA
		JSR	TOIBM
		BRA	RESET
READPC2		LDAA	#$0E
		BSR	WRITEC
		TBA
		LSRA
		LSRA
		LSRB
		ROLA
		LSLA
		LSRB
		ROLA
		BSR	WRITEC
READPC1		LDAB	#$FA			Return OK
		JSR	TOIBM
KAKA		BRA	MAIN

*
*	Write A to sunkeyboard
*
WRITEC		BRCLR	SCSR,X #TDRE *
		STAA	SCDR,X
		RTS
*
*	Autorepeat
*
AUTOREPEAT	LDAB	$6			Load Char
		LDY	$2			Load Rate
		BRA	READSUN1		Go for it

*
*	Read data from sunkeyboard
*
READSUN		LDAB	SCDR,X
		CMPB	#$15			Pause (Down)
		BEQ	PAUSE
		STAB	$6			Save Char
		LDY	$0			Load Delay
READSUN1	LSLB				Clear bit7 
		LSRB
		PSHX
		LDX	#TABLE1
		ABX
		CLRA
		LDAB	0,X
		PULX
		LSRB
		BCC	READSUN3
		TBA
		LSRB
		LSRB
		PSHX
		LDX	#TABLE2
		ABX
		LDAB	0,X
		PULX
READSUN3	BEQ	KAKA			If Char == 0 return
		PSHB
		LDAB	$6			Check if Up or Down
		LSLB
		BCS	READSUN4
*						Key Down
		LSRA
		BCC	READSUN5
		LSRA
		BCC	READSUN6
		BSR	E0TOIBM
		LDAB	#$12
		BSR	TOIBM
READSUN6	BSR	E0TOIBM
READSUN5	PULB
		BSR	TOIBM
		BRA	KAKA
*						Key Up
READSUN4	CLRB				Disable autorepeat (Char==0)
		STAB	$6			Save Char
		LSRA
		BCC	READSUN7
READSUN8	BSR	E0TOIBM
READSUN7	LDAB	#$F0
		BSR	TOIBM
		PULB
		BSR	TOIBM
		LSRA
		BCC	KAKA
		LDAB	#$12
		PSHB
		CLRA
		BRA	READSUN8	

*
*	Send Pause or Break
*
*		IN		OUT
*	A	Register not affected	
*	B	-		0
*	Y	-		PAUSESTR + 9
*
PAUSE		LDY	#PAUSESTR
		LDAB	$6
		CMPB	#$4C			if last key == Ctrl then BREAK
		BNE	PAUSE1
		LDY	#BREAKSTR
PAUSE1		LDAB	0,Y
		BEQ	PAUSE2
		BSR	TOIBM
		INY
		BRA	PAUSE1
PAUSE2		STB	$6
		JMP	RESET1			Reinit Y

*
*	Read byte from PC
*
*		IN		OUT
*	A	-		0
*	B	-		Byte from ibm
*	Y	Register not affected	
*
FROMIBM		EQU	*
		LDAA	#8
FROMIBM2	BSR	CFROMIBM
		RORB
		DECA
		BNE	FROMIBM2 
		BSR	CFROMIBM		Parity
		BSR	CFROMIBM		Stop
		BSET	PORTA,X #DATAOUT
		BSR	CFROMIBM		Extra
		BCLR	PORTA,X #DATAOUT
FROMIBM3	BRSET	PORTA,X	#CLOCKIN *	Wait for handshake
		BRCLR	PORTA,X	#CLOCKIN *
		LDAA	#140			Delay 400uS
FROMIBM1	DECA				140*(2+3)/2000000 = 0.0004
		BNE	FROMIBM1
		RTS
*
* Read Carry Bit From IBM
*
*		IN		OUT
*	A	Register not affected
*	B	Register not affected
*	Y	Register not affected	
*
CFROMIBM	EQU	*
		BSET	PORTA,X #CLOCKOUT
		BSR	WAIT30uS
		BCLR	PORTA,X #CLOCKOUT
		BSR	WAIT15uS
		PSHA
		LDAA	PORTA,X
		LSRA
		PULA
		BSR	WAIT15uS
		RTS

*
*	Write E0 to PC
*
E0TOIBM		LDAB	#$E0

*
*	Write byte to PC
*
*		IN		OUT
*	A	Register not affected
*	B	Byte to ibm	0
*	Y	Register not affected	
*
TOIBM		EQU	*			Send The Value in AccB to IBM
		PSHA
TOIBM1		BRSET	PORTA,X	#$03 TOIBM2	Wait for Clock & Data to go high
		BRA	TOIBM1
TOIBM2		CLC				Startbit
		BSR	CTOIBM
		LDAA	#1
		PSHY
		LDY	#8
TOIBM3		LSRB
		BSR	CTOIBM
		DEY
		BNE	TOIBM3
		PULY
		LSRA				Parity
		BSR	CTOIBM
		SEC				Stopbit
		BSR	CTOIBM
		PULA
		BRA	FROMIBM3
*
* Send Carry Bit To IBM
*
*		IN		OUT
*	A	n		n+1
*	B	Register not affected
*	Y	Register not affected	
*
CTOIBM		BCC	CTOIBM1
		BCLR	PORTA,X #DATAOUT	1
		INCA				Inc A (for parity)
		BRA	CTOIBM2
CTOIBM1		BSET	PORTA,X #DATAOUT	0
CTOIBM2		BSET	PORTA,X	#CLOCKOUT
		BSR	WAIT30uS
		BCLR	PORTA,X #CLOCKOUT

*
* Delay 30uS
*
*		IN		OUT
*	A	Register not affected
*	B	Register not affected
*	Y	Register not affected	
*
*
WAIT30uS	BSR	WAIT15uS

*
* Delay 15uS
*
*		IN		OUT
*	A	Register not affected
*	B	Register not affected
*	Y	Register not affected	
*
WAIT15uS	PSHB
		LDAB	#uS15
WAIT15uS1	DECB
		BNE	WAIT15uS1
		PULB
		RTS

*
*	Strings for Pause key
*
BREAKSTR	FCB	$E0, $7E, $E0, $F0, $7E, $00
PAUSESTR	FCB	$E1, $14, $77, $E1, $F0, $14, $F0, $77

*
*	Main table
*
*	Om bit 0 == 0 ar bit 1-7 data som ska skrivas till PC
*
*	Om bit 0 == 1, bit 1 == 0 och bit2 == 0 ar bit 3-7 index till table2
*
*	Om bit 0 == 1, bit 1 == 1 och bit2 == 0 ska $E0 skrivas till PC och
*			bit 3-7 ar index till table2
*
*	Om bit 0 == 1, bit 1 == 1 och bit2 == 1 ska $E0, $12, $E0 skrivas
*			till PC och bit 3-7 ar index till table2
*
TABLE1		FCB	$00		$00)	Must be $00 !!!!
		FCB	$26		$01)	Stop	(L1) // pme OK F13 116
		FCB	$AE		$02)	Volume Down  // pme wrong
		FCB	$32		$03)	Again	(L2) // pme OK F14 124
		FCB	$90		$04)	Volume Up    // pme OK sc 126
		FCB	$0A		$05)	F1
		FCB	$0C		$06)	F2
		FCB	$12		$07)	F10
		FCB	$08		$08)	F3
		FCB	$F0		$09)	F11
		FCB	$18		$0A)	F4
		FCB	$0E		$0B)	F12
		FCB	$06		$0C)	F5
		FCB	$03		$0D)	Alt Graph              (Index 0)
		FCB	$16		$0E)	F6
		FCB	$80		$0F)	No Text      // pme OK sc 115 
		FCB	$79		$10)	F7                    (Index 15)
		FCB	$14		$11)	F8
		FCB	$02		$12)	F9
		FCB	$22		$13)	Alt
		FCB	$0B		$14)	Cursor Up              (Index 1)
		FCB	$0F		$15)	Pause        // pme OK very
		FCB	$17		$16)	Print Screen           (Index 2)
		FCB	$FC		$17)	Scroll Lock
		FCB	$1B		$18)	Cursor Left            (Index 3)
		FCB	$72		$19)	Props	(L3)  // pme OK F15 123
		FCB	$A2		$1A)	Undo	(L4)  // pme OK F16 101
		FCB	$23		$1B)	Cursor Down            (Index 4)
		FCB	$2B		$1C)	Cursor Right           (Index 5)
		FCB	$EC		$1D)	Esc
		FCB	$2C		$1E)	1 !
		FCB	$3C		$1F)	2 
		FCB	$4C		$20)	3 #
		FCB	$4A		$21)	4 $
		FCB	$5C		$22)	5 %
		FCB	$6C		$23)	6 ^
		FCB	$7A		$24)	7 &
		FCB	$7C		$25)	8 *
		FCB	$8C		$26)	9 (
		FCB	$8A		$27)	0 )
		FCB	$9C		$28)	- _
		FCB	$AA		$29)	= +
		FCB	$1C		$2A)	` ~
		FCB	$CC		$2B)	BackSpace
		FCB	$37		$2C)	Insert                 (Index 6)
		FCB	$C0		$2D)	Volume Off
		FCB	$3B		$2E)	/     (Numeric Keypad) (Index 7)
		FCB	$F8		$2F)	*     (Numeric Keypad)
		FCB	$15		$30)	Power Off // pme wrong 
		FCB	$A6		$31)	Front	(L5)  // pme F17 = 117
		FCB	$E2		$32)	. Del	(Numeric Keypad)
		FCB	$B8		$33)	Copy	(L6)   // pme OK F18 122
		FCB	$47		$34)	Home    org=47   (Index 8)
		FCB	$1A		$35)	Tab
		FCB	$2A		$36)	q
		FCB	$3A		$37)	w
		FCB	$48		$38)	e
		FCB	$5A		$39)	r
		FCB	$58		$3A)	t
		FCB	$6A		$3B)	y
		FCB	$78		$3C)	u
		FCB	$86		$3D)	i
		FCB	$88		$3E)	o
		FCB	$9A		$3F)	p
		FCB	$A8		$40)	[ {
		FCB	$B6		$41)	] }
		FCB	$4F		$42)	Delete                 (Index 9)
		FCB	$6B		$43)	Compose // pme wrong org 1E
		FCB	$D8		$44)	7 Home	(Numeric Keypad)
		FCB	$EA		$45)	8 Up	(Numeric Keypad)
		FCB	$FA		$46)	9 PgUp	(Numeric Keypad)
		FCB	$F6		$47)	-	(Numeric Keypad)
		FCB	$BE		$48)	Open	(L7)  //pme OK F19 118
		FCB	$C4		$49)	Paste	(L8)  //pme OK F20 121
		FCB	$57		$4A)	End                   (Index 10)
		FCB	$00		$4B)	
		FCB	$28		$4C)	Control
		FCB	$38		$4D)	a
		FCB	$36		$4E)	s
		FCB	$46		$4F)	d
		FCB	$56		$50)	f
		FCB	$68		$51)	g
		FCB	$66		$52)	h
		FCB	$76		$53)	j
		FCB	$84		$54)	k
		FCB	$96		$55)	l
		FCB	$98		$56)	; :
		FCB	$A4		$57)	' 
		FCB	$BA		$58)	\ |	
		FCB	$B4		$59)	Return
		FCB	$5B		$5A)	Enter (Numeric Keypad)(Index 11)
		FCB	$D6		$5B)	4 Left	(Numeric Keypad)
		FCB	$E6		$5C)	5	(Numeric Keypad)
		FCB	$E8		$5D)	6 Right	(Numeric Keypad)
		FCB	$E0		$5E)	0 Ins	(Numeric Keypad)
		FCB	$C6		$5F)	Find	(L9) // pme OK F21 121
		FCB	$67		$60)	PageUp                (Index 12)
		FCB	$C8		$61)	Cut	(L10) // pme OK F22 120
		FCB	$EE		$62)	NumLock
		FCB	$24		$63)	Left Shift
		FCB	$34		$64)	z
		FCB	$44		$65)	x
		FCB	$42		$66)	c
		FCB	$54		$67)	v
		FCB	$64		$68)	b
		FCB	$62		$69)	n
		FCB	$74		$6A)	m
		FCB	$82		$6B)	, <
		FCB	$92		$6C)	. >
		FCB	$94		$6D)	/ ?
		FCB	$B2		$6E)	Right Shift
		FCB	$29		$6F)	
		FCB	$D2		$70)	1 End	(Numeric Keypad)
		FCB	$E4		$71)	2 Down	(Numeric Keypad)
		FCB	$F4		$72)	3 PgDn	(Numeric Keypad)
		FCB	$2D		$73)	
		FCB	$2E		$74)	
		FCB	$2F		$75)	
		FCB	$CA		$76)	Help
		FCB	$B0		$77)	CapsLock
		FCB	$CE		$78)	Left Meta
		FCB	$52		$79)	S P A C E
		FCB	$5E		$7A)	Right Meta            (Index 13)
		FCB	$77		$7B)	PageDown              (Index 14)
		FCB	$31		$7C)	
		FCB	$F2		$7D)	+	(Numeric Keypad)
		FCB	$32		$7E)	
		FCB	$00		$7F)	All Keys Are Up
		
*
*	Table 2
*
*	Bit 0 is always 0
*
*	Bit 1-7 is data
*

TABLE2		FCB	$11		$0D)	Alt Graph               $E0, $11
		FCB	$75		$14)	Cursor Up               $E0, $75
		FCB	$7C		$16)	Print Screen  $E0, $12, $E0, $7C
		FCB	$6B		$18)	Cursor Left             $E0, $6B
		FCB	$72		$1B)	Cursor Down             $E0, $72
		FCB	$74		$1C)	Cursor Right            $E0, $74
		FCB	$70		$2C)	Insert        $E0, $12, $E0, $70
		FCB	$4A		$2E)	/ (Numeric)             $E0, $4A
		FCB	$6C		$34)	Home          $E0, $12, $E0, $6C
		FCB	$71		$42)	Delete        $E0, $12, $E0, $71
		FCB	$69		$4A)	End           $E0, $12, $E0, $69
		FCB	$5A		$5A)	Enter                   $E0, $5A
		FCB	$7D		$60)	PageUp        $E0, $12, $E0, $7D
		FCB	$14		$7A)	Right Meta              $E0, $14
		FCB	$7A		$7B)	PageDown      $E0, $12, $E0, $7A
		FCB	$83		$10)	F7                           $83
*
		END
