Line 45... |
Line 45... |
; | |
|
; | |
|
; FFFFFFFF +----------------+
|
; FFFFFFFF +----------------+
|
;
|
;
|
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
;
|
;
|
|
HAS_MMU equ 0
|
|
|
CTRLC EQU $03
|
CTRLC EQU $03
|
CTRLH EQU $08
|
CTRLH EQU $08
|
CTRLS EQU $13
|
CTRLS EQU $13
|
CTRLX EQU $18
|
CTRLX EQU $18
|
CTRLZ EQU $1A
|
CTRLZ EQU $1A
|
Line 72... |
Line 74... |
SC_LSHIFT EQU $12
|
SC_LSHIFT EQU $12
|
SC_DEL EQU $71 ; extend
|
SC_DEL EQU $71 ; extend
|
SC_LCTRL EQU $58
|
SC_LCTRL EQU $58
|
SC_TAB EQU $0D
|
SC_TAB EQU $0D
|
|
|
|
if HAS_MMU
|
TEXTREG EQU $1E3FF00 ; virtual addresses
|
TEXTREG EQU $1E3FF00 ; virtual addresses
|
txtscreen EQU $1E00000
|
txtscreen EQU $1E00000
|
semamem EQU $1E50000
|
semamem EQU $1E50000
|
ACIA EQU $1E60000
|
ACIA EQU $1E60000
|
ACIA_RX EQU 0
|
ACIA_RX EQU 0
|
ACIA_TX EQU 0
|
ACIA_TX EQU 0
|
ACIA_STAT EQU 4
|
ACIA_STAT EQU 4
|
ACIA_CMD EQU 8
|
ACIA_CMD EQU 8
|
ACIA_CTRL EQU 12
|
ACIA_CTRL EQU 12
|
|
I2C2 equ $01E69000
|
|
I2C_PREL equ 0
|
|
I2C_PREH equ 1
|
|
I2C_CTRL equ 2
|
|
I2C_RXR equ 3
|
|
I2C_TXR equ 3
|
|
I2C_CMD equ 4
|
|
I2C_STAT equ 4
|
PLIC EQU $1E90000
|
PLIC EQU $1E90000
|
MMU EQU $FDC00000 ; physical address
|
MMU EQU $FDC00000 ; physical address
|
leds EQU $1EFFF00 ; virtual addresses
|
leds EQU $1EFFF00 ; virtual addresses
|
keybd EQU $1EFFE00
|
keybd EQU $1EFFE00
|
KEYBD EQU $1EFFE00
|
KEYBD EQU $1EFFE00
|
Line 93... |
Line 104... |
RAND_STRM EQU $1EFFD04
|
RAND_STRM EQU $1EFFD04
|
RAND_MZ EQU $1EFFD08
|
RAND_MZ EQU $1EFFD08
|
RAND_MW EQU $1EFFD0C
|
RAND_MW EQU $1EFFD0C
|
RST_REG EQU $1EFFC00
|
RST_REG EQU $1EFFC00
|
IO_BITMAP EQU $1F00000
|
IO_BITMAP EQU $1F00000
|
IOFocus EQU $0100000
|
else
|
|
TEXTREG EQU $FD03FF00 ; virtual addresses
|
|
txtscreen EQU $FD000000
|
|
semamem EQU $FD050000
|
|
ACIA EQU $FD060000
|
|
ACIA_RX EQU 0
|
|
ACIA_TX EQU 0
|
|
ACIA_STAT EQU 4
|
|
ACIA_CMD EQU 8
|
|
ACIA_CTRL EQU 12
|
|
I2C2 equ $FD069000
|
|
I2C_PREL equ 0
|
|
I2C_PREH equ 1
|
|
I2C_CTRL equ 2
|
|
I2C_RXR equ 3
|
|
I2C_TXR equ 3
|
|
I2C_CMD equ 4
|
|
I2C_STAT equ 4
|
|
PLIC EQU $FD090000
|
|
MMU EQU $FDC00000 ; physical address
|
|
leds EQU $FD0FFF00 ; virtual addresses
|
|
keybd EQU $FD0FFE00
|
|
KEYBD EQU $FD0FFE00
|
|
RAND EQU $FD0FFD00
|
|
RAND_NUM EQU $FD0FFD00
|
|
RAND_STRM EQU $FD0FFD04
|
|
RAND_MZ EQU $FD0FFD08
|
|
RAND_MW EQU $FD0FFD0C
|
|
RST_REG EQU $FD0FFC00
|
|
IO_BITMAP EQU $FD100000
|
|
endif
|
|
|
SERIAL_SEMA EQU 2
|
SERIAL_SEMA EQU 2
|
KEYBD_SEMA EQU 3
|
KEYBD_SEMA EQU 3
|
RAND_SEMA EQU 4
|
RAND_SEMA EQU 4
|
SCREEN_SEMA EQU 5
|
SCREEN_SEMA EQU 5
|
Line 292... |
Line 333... |
BreakpointWords equ $40280 ; to $402A0
|
BreakpointWords equ $40280 ; to $402A0
|
;RunningTCB equ $40300
|
;RunningTCB equ $40300
|
TimerStack equ $40BFC
|
TimerStack equ $40BFC
|
|
|
; Keyboard buffer is in shared memory
|
; Keyboard buffer is in shared memory
|
|
IOFocus EQU $00100000
|
memend equ $00100004
|
memend equ $00100004
|
KeybdLEDs equ $0010000E
|
KeybdLEDs equ $0010000E
|
_KeyState1 equ $0010000F
|
_KeyState1 equ $0010000F
|
_KeyState2 equ $00100010
|
_KeyState2 equ $00100010
|
_KeybdHead equ $00100011
|
_KeybdHead equ $00100011
|
Line 307... |
Line 349... |
SerTailRcv equ $00100160
|
SerTailRcv equ $00100160
|
SerHeadRcv equ $00100162
|
SerHeadRcv equ $00100162
|
SerRcvXon equ $00100164
|
SerRcvXon equ $00100164
|
SerRcvXoff equ $00100165
|
SerRcvXoff equ $00100165
|
SerRcvBuf equ $00101000
|
SerRcvBuf equ $00101000
|
|
RTCBuf equ $00100200 ; to $0010023F
|
|
|
include "..\Femtiki\source\kernel\Femtiki_vars.x68"
|
include "..\Femtiki\source\kernel\Femtiki_vars.x68"
|
|
|
code
|
code
|
align 2
|
align 2
|
start:
|
start:
|
|
; fadd (a0)+,fp2
|
move.w #$2700,sr ; enable level 6 and higher interrupts
|
move.w #$2700,sr ; enable level 6 and higher interrupts
|
moveq #0,d0 ; set address space zero
|
moveq #0,d0 ; set address space zero
|
movec d0,asid
|
movec d0,asid
|
|
; Setup circuit select signals
|
|
move.l #MMU,d0
|
|
movec d0,mmus
|
|
if HAS_MMU
|
|
move.l #$01F00000,d0 ; set virtual address for iop bitmap
|
|
movec d0,iops
|
|
move.l #$01E00000,d0 ; set virtual address for io block
|
|
movec d0,ios
|
|
else
|
|
move.l #$FD100000,d0 ; set virtual address for iop bitmap
|
|
movec d0,iops
|
|
move.l #$FD000000,d0 ; set virtual address for io block
|
|
movec d0,ios
|
|
endif
|
|
movec coreno,d0 ; set initial value of thread register
|
|
swap d0 ; coreno in high eight bits
|
|
lsl.l #8,d0
|
|
movec d0,tr
|
; Prepare local variable storage
|
; Prepare local variable storage
|
move.w #1023,d0 ; 1024 longs to clear
|
move.w #1023,d0 ; 1024 longs to clear
|
lea $40000,a0 ; non shared local memory address
|
lea $40000,a0 ; non shared local memory address
|
.0111:
|
.0111:
|
clr.l (a0)+ ; clear the memory area
|
clr.l (a0)+ ; clear the memory area
|
Line 327... |
Line 389... |
move.l #$1fffff,fgColor ; set foreground / background color
|
move.l #$1fffff,fgColor ; set foreground / background color
|
move.l #$00003f,bkColor
|
move.l #$00003f,bkColor
|
movec.l coreno,d0 ; get core number (2 to 9)
|
movec.l coreno,d0 ; get core number (2 to 9)
|
subi.b #2,d0 ; adjust (0 to 7)
|
subi.b #2,d0 ; adjust (0 to 7)
|
mulu #16384,d0 ; compute screen location
|
mulu #16384,d0 ; compute screen location
|
|
if HAS_MMU
|
|
addi.l #$01E00000,d0
|
|
else
|
addi.l #$FD000000,d0
|
addi.l #$FD000000,d0
|
|
endif
|
move.l d0,TextScr
|
move.l d0,TextScr
|
move.b #64,TextCols ; set rows and columns
|
move.b #64,TextCols ; set rows and columns
|
move.b #32,TextRows
|
move.b #32,TextRows
|
movec.l coreno,d0 ; get core number
|
movec.l coreno,d0 ; get core number
|
cmpi.b #2,d0
|
cmpi.b #2,d0
|
bne start_other
|
bne start_other
|
move.b d0,IOFocus ; Set the IO focus in global memory
|
move.b d0,IOFocus ; Set the IO focus in global memory
|
|
if HAS_MMU
|
bsr InitMMU ; Can't access anything till this is done
|
bsr InitMMU ; Can't access anything till this is done
|
bsr InitIOBitmap ; not going to get far without this
|
endif
|
|
bsr InitIOPBitmap ; not going to get far without this
|
bsr InitSemaphores
|
bsr InitSemaphores
|
bsr InitRand
|
bsr InitRand
|
bsr Delay3s ; give devices time to reset
|
bsr Delay3s ; give devices time to reset
|
bsr clear_screen
|
bsr clear_screen
|
|
|
bsr _KeybdInit
|
bsr _KeybdInit
|
; bsr InitIRQ
|
; bsr InitIRQ
|
bsr SerialInit
|
bsr SerialInit
|
|
bsr init_i2c
|
|
; bsr rtc_read
|
|
|
; Write startup message to screen
|
; Write startup message to screen
|
|
|
lea msg_start,a1
|
lea msg_start,a1
|
bsr DisplayString
|
bsr DisplayString
|
Line 376... |
Line 446... |
dbra d0,loop1
|
dbra d0,loop1
|
bra loop2
|
bra loop2
|
|
|
start_other:
|
start_other:
|
bsr Delay3s2 ; need time for system setup (io_bitmap etc.)
|
bsr Delay3s2 ; need time for system setup (io_bitmap etc.)
|
|
bsr Delay3s2 ; need time for system setup (io_bitmap etc.)
|
bsr clear_screen
|
bsr clear_screen
|
movec coreno,d1
|
movec coreno,d1
|
bsr DisplayByte
|
bsr DisplayByte
|
lea msg_core_start,a1
|
lea msg_core_start,a1
|
bsr DisplayString
|
bsr DisplayString
|
Line 389... |
Line 460... |
bra do_nothing
|
bra do_nothing
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Initialize the MMU to allow thread #0 access to IO
|
; Initialize the MMU to allow thread #0 access to IO
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
if HAS_MMU
|
align 2
|
align 2
|
mmu_adrtbl: ; virtual address[24:16], physical address[31:16] bytes reversed!
|
mmu_adrtbl: ; virtual address[24:16], physical address[31:16] bytes reversed!
|
dc.l $0010,$10000300 ; global scratch pad
|
dc.l $0010,$10000300 ; global scratch pad
|
dc.l $01E0,$00FD0300
|
dc.l $01E0,$00FD0300
|
dc.l $01E1,$01FD0300
|
dc.l $01E1,$01FD0300
|
Line 401... |
Line 473... |
dc.l $01E5,$05FD0300
|
dc.l $01E5,$05FD0300
|
dc.l $01E6,$06FD0300
|
dc.l $01E6,$06FD0300
|
dc.l $01E9,$09FD0300
|
dc.l $01E9,$09FD0300
|
dc.l $01EF,$0FFD0300
|
dc.l $01EF,$0FFD0300
|
dc.l $01F0,$10FD0300
|
dc.l $01F0,$10FD0300
|
|
dc.l $01FF,$FFFF0300 ; all ones output for IRQ ack needed
|
|
|
even
|
even
|
InitMMU:
|
InitMMU:
|
lea MMU+8,a0 ; first 128kB is local RAM
|
lea MMU+8,a0 ; first 128kB is local RAM
|
move.l #$32000,d2 ; map all pages to DRAM
|
move.l #$32000,d2 ; map all pages to DRAM
|
Line 415... |
Line 488... |
move.l d1,(a0)+
|
move.l d1,(a0)+
|
addi.w #1,d2 ; increment DRAM page number
|
addi.w #1,d2 ; increment DRAM page number
|
dbra d0,.0002
|
dbra d0,.0002
|
lea MMU,a0 ; now program IO access
|
lea MMU,a0 ; now program IO access
|
lea mmu_adrtbl,a1
|
lea mmu_adrtbl,a1
|
moveq #9,d0
|
moveq #10,d0
|
.0001
|
.0001
|
move.l (a1)+,d2
|
move.l (a1)+,d2
|
lsl.l #2,d2
|
lsl.l #2,d2
|
move.l (a1)+,(a0,d2.w)
|
move.l (a1)+,(a0,d2.w)
|
dbra d0,.0001
|
dbra d0,.0001
|
rts
|
rts
|
|
endif
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; The IO bitmap needs to be initialized to allow access to IO.
|
; The IO bitmap needs to be initialized to allow access to IO.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
InitIOBitmap:
|
InitIOPBitmap:
|
; mark all IO inaccessible
|
moveq #0,d3 ; d3 = asid value
|
move.w #8191,d0
|
move.w #63,d0 ; 64 bitmaps to setup
|
lea IO_BITMAP,a0
|
movec iops,a0 ; a0 = IOP bitmap address
|
|
movea.l a0,a1 ; a1 = table address
|
|
.0004
|
|
tst.b d3
|
|
seq d1 ; set entire bitmap for asid 0, otherwise clear entire bitmap
|
|
ext.w d1 ; make into a long value
|
|
ext.l d1
|
|
move.w #127,d4
|
.0001
|
.0001
|
clr.l (a0)+
|
move.l d1,(a1)+ ; set or clear entire table
|
dbra d0,.0001
|
dbra d4,.0001
|
; Give the system asid=0 complete access to the IO area
|
|
move.w #127,d0
|
|
moveq #-1,d1
|
moveq #-1,d1
|
lea IO_BITMAP,a0
|
move.l d1,160(a0) ; all cores have access to semaphores
|
.0002
|
move.l d1,164(a0)
|
move.l d1,(a0)+
|
move.l d1,168(a0)
|
dbra d0,.0002
|
move.l d1,172(a0)
|
; Give all cores access to the screen
|
|
lea IO_BITMAP+128,a0
|
|
moveq #-1,d1
|
|
move.w #62,d0 ; 63 more bitmaps to fill
|
|
.0004
|
|
swap d0
|
swap d0
|
move.w #31,d0 ; 32 bytes for the screen area per bitmap
|
move.w #31,d0 ; 32 long words for the screen area per bitmap
|
.0003
|
.0003
|
move.l d1,(a0)+
|
move.l d1,(a0)+ ; all cores have access to a screen
|
dbra d0,.0003
|
dbra d0,.0003
|
swap d0
|
swap d0
|
lea 96(a0),a0
|
addi.b #1,d3 ; do next address space
|
|
movea.l a1,a0 ; a0 points to area for next address space
|
dbra d0,.0004
|
dbra d0,.0004
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; RandInit
|
; RandInit
|
Line 471... |
Line 546... |
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
InitRand:
|
InitRand:
|
RandInit:
|
RandInit:
|
movem.l d0/d1,-(a7)
|
movem.l d0/d1,-(a7)
|
movec coreno,d0
|
moveq #37,d0 ; lock semaphore
|
swap d0
|
|
moveq #RAND_SEMA,d1
|
moveq #RAND_SEMA,d1
|
bsr LockSemaphore
|
trap #15
|
swap d0
|
movec coreno,d0 ; d0 = core number
|
lsl.l #6,d0 ; allow 64 streams per core
|
lsl.l #6,d0 ; allow 64 streams per core
|
move.l d0,RAND_STRM ; select the stream
|
move.l d0,RAND_STRM ; select the stream
|
move.l #$12345678,RAND_MZ ; initialize to some value
|
move.l #$12345678,RAND_MZ ; initialize to some value
|
move.l #$98765432,RAND_MW
|
move.l #$98765432,RAND_MW
|
move.l #777777777,RAND_NUM ; generate first number
|
move.l #777777777,RAND_NUM ; generate first number
|
movec coreno,d0
|
moveq #38,d0 ; unlock semaphore
|
swap d0
|
|
moveq #RAND_SEMA,d1
|
moveq #RAND_SEMA,d1
|
bsr UnlockSemaphore
|
trap #15
|
movem.l (a7)+,d0/d1
|
movem.l (a7)+,d0/d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
RandGetNum:
|
RandGetNum:
|
movem.l d0/d2,-(a7)
|
movem.l d0/d2,-(a7)
|
movec coreno,d0
|
moveq #37,d0 ; lock semaphore
|
swap d0
|
|
moveq #RAND_SEMA,d1
|
moveq #RAND_SEMA,d1
|
bsr LockSemaphore
|
trap #15
|
|
movec coreno,d0
|
lsl.l #6,d0
|
lsl.l #6,d0
|
move.l d0,RAND_STRM ; select the stream
|
move.l d0,RAND_STRM ; select the stream
|
move.l RAND_NUM,d2
|
move.l RAND_NUM,d2 ; d2 = random number
|
clr.l RAND_NUM ; generate next number
|
clr.l RAND_NUM ; generate next number
|
movec coreno,d0
|
moveq #38,d0 ; unlock semaphore
|
swap d0
|
|
moveq #RAND_SEMA,d1
|
moveq #RAND_SEMA,d1
|
bsr UnlockSemaphore
|
trap #15
|
move.l d2,d1
|
move.l d2,d1
|
movem.l (a7)+,d0/d2
|
movem.l (a7)+,d0/d2
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
Line 598... |
Line 670... |
; d0 = key
|
; d0 = key
|
; d1 = semaphore number
|
; d1 = semaphore number
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
|
|
LockSemaphore:
|
LockSemaphore:
|
|
rts
|
movem.l d1/a0,-(a7) ; save registers
|
movem.l d1/a0,-(a7) ; save registers
|
lea semamem,a0 ; point to semaphore memory lock area
|
lea semamem,a0 ; point to semaphore memory lock area
|
andi.w #255,d1 ; make d1 word value
|
andi.w #255,d1 ; make d1 word value
|
lsl.w #2,d1 ; align to memory
|
lsl.w #2,d1 ; align to memory
|
.0001:
|
.0001
|
move.l d0,(a0,d1.w) ; try and write the semaphore
|
move.l d0,(a0,d1.w) ; try and write the semaphore
|
cmp.l (a0,d1.w),d0 ; did it lock?
|
cmp.l (a0,d1.w),d0 ; did it lock?
|
bne.s .0001 ; no, try again
|
bne.s .0001 ; no, try again
|
movem.l (a7)+,a0/d1 ; restore regs
|
movem.l (a7)+,a0/d1 ; restore regs
|
rts
|
rts
|
Line 638... |
Line 711... |
; d0 = key
|
; d0 = key
|
; d1 = semaphore number
|
; d1 = semaphore number
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
|
|
UnlockSemaphore:
|
UnlockSemaphore:
|
|
bra ForceUnlockSemaphore
|
movem.l d1/a0,-(a7) ; save registers
|
movem.l d1/a0,-(a7) ; save registers
|
lea semamem+$1000,a0 ; point to semaphore memory unlock area
|
lea semamem+$1000,a0 ; point to semaphore memory unlock area
|
andi.w #255,d1 ; make d1 word value
|
andi.w #255,d1 ; make d1 word value
|
lsl.w #2,d1 ; align to memory
|
lsl.w #2,d1 ; align to memory
|
move.l d0,(a0,d1.w) ; write matching value to unlock
|
move.l d0,(a0,d1.w) ; write matching value to unlock
|
Line 652... |
Line 726... |
; Parameters:
|
; Parameters:
|
; d1 = semaphore to lock / unlock
|
; d1 = semaphore to lock / unlock
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
|
|
T15LockSemaphore:
|
T15LockSemaphore:
|
movec coreno,d0
|
movec tr,d0
|
or.l RunningTCB,d0
|
|
bra LockSemaphore
|
bra LockSemaphore
|
|
|
T15UnlockSemaphore:
|
T15UnlockSemaphore:
|
movec coreno,d0
|
movec tr,d0
|
or.l RunningTCB,d0
|
|
bra UnlockSemaphore
|
bra UnlockSemaphore
|
|
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; Delay for a few seconds to allow some I/O reset operations to take place.
|
; Delay for a few seconds to allow some I/O reset operations to take place.
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
Line 3392... |
Line 3464... |
rte
|
rte
|
|
|
nmeSerial:
|
nmeSerial:
|
dc.b "Serial",0
|
dc.b "Serial",0
|
|
|
|
;===============================================================================
|
|
; Generic I2C routines
|
|
;===============================================================================
|
|
|
|
even
|
|
; i2c
|
|
i2c_setup:
|
|
; lea I2C,a6
|
|
; move.w #19,I2C_PREL(a6) ; setup prescale for 400kHz clock
|
|
; move.w #0,I2C_PREH(a6)
|
|
init_i2c:
|
|
lea I2C2,a6
|
|
move.b #19,I2C_PREL(a6) ; setup prescale for 400kHz clock, 40MHz master
|
|
move.b #0,I2C_PREH(a6)
|
|
rts
|
|
|
|
; Wait for I2C transfer to complete
|
|
;
|
|
; Parameters
|
|
; a6 - I2C controller base address
|
|
|
|
i2c_wait_tip:
|
|
move.l d0,-(a7)
|
|
.0001
|
|
move.b I2C_STAT(a6),d0 ; wait for tip to clear
|
|
btst #1,d0
|
|
bne.s .0001
|
|
move.l (a7)+,d0
|
|
rts
|
|
|
|
; Parameters
|
|
; d0.b - data to transmit
|
|
; d1.b - command value
|
|
; a6 - I2C controller base address
|
|
;
|
|
i2c_wr_cmd:
|
|
move.b d0,I2C_TXR(a6)
|
|
move.b d1,I2C_CMD(a6)
|
|
bsr i2c_wait_tip
|
|
move.b I2C_STAT(a6),d0
|
|
rts
|
|
|
|
i2c_xmit1:
|
|
move.l d0,-(a7)
|
|
move.b #1,I2C_CTRL(a6) ; enable the core
|
|
moveq #$76,d0 ; set slave address = %0111011
|
|
move.w #$90,d1 ; set STA, WR
|
|
bsr i2c_wr_cmd
|
|
bsr i2c_wait_rx_nack
|
|
move.l (a7)+,d0
|
|
move.w #$50,d1 ; set STO, WR
|
|
bsr i2c_wr_cmd
|
|
bsr i2c_wait_rx_nack
|
|
|
|
i2c_wait_rx_nack:
|
|
move.l d0,-(a7)
|
|
.0001
|
|
move.b I2C_STAT(a6),d0 ; wait for RXack = 0
|
|
btst #7,d0
|
|
bne.s .0001
|
|
move.l (a7)+,d0
|
|
rts
|
|
|
|
;===============================================================================
|
|
; Realtime clock routines
|
|
;===============================================================================
|
|
|
|
rtc_read:
|
|
movea.l #I2C2,a6
|
|
lea RTCBuf,a5
|
|
move.b #$80,I2C_CTRL(a6) ; enable I2C
|
|
move.b #$DE,d0 ; read address, write op
|
|
move.b #$90,d1 ; STA + wr bit
|
|
bsr i2c_wr_cmd
|
|
tst.b d0
|
|
bmi .rxerr
|
|
move.b #$00,d0 ; address zero
|
|
move.b #$10,d1 ; wr bit
|
|
bsr i2c_wr_cmd
|
|
tst.b d0
|
|
bmi .rxerr
|
|
move.b #$DF,d0 ; read address, read op
|
|
move.b #$90,d1 ; STA + wr bit
|
|
bsr i2c_wr_cmd
|
|
tst.b d0
|
|
bmi .rxerr
|
|
|
|
move.w #$20,d2
|
|
.0001
|
|
move.b #$20,I2C_CMD(a6) ; rd bit
|
|
bsr i2c_wait_tip
|
|
bsr i2c_wait_rx_nack
|
|
move.b I2C_STAT(a6),d0
|
|
tst.b d0
|
|
bmi .rxerr
|
|
move.b I2C_RXR(a6),d0
|
|
move.b d0,(a5,d2.w)
|
|
addi.w #1,d2
|
|
cmpi.w #$5F,d2
|
|
bne .0001
|
|
move.b #$68,I2C_CMD(a6) ; STO, rd bit + nack
|
|
bsr i2c_wait_tip
|
|
bsr i2c_wait_rx_nack
|
|
move.b I2C_STAT(a6),d0
|
|
tst.b d0
|
|
bmi .rxerr
|
|
move.b I2C_RXR(a6),d0
|
|
move.b d0,(a5,d2.w)
|
|
move.b #0,I2C_CTRL(a6) ; disable I2C and return 0
|
|
moveq #0,d0
|
|
rts
|
|
.rxerr
|
|
move.b #0,I2C_CTRL(a6) ; disable I2C and return status
|
|
rts
|
|
|
|
rtc_write:
|
|
movea.l #I2C2,a6
|
|
lea RTCBuf,a5
|
|
move.b #$80,I2C_CTRL(a6) ; enable I2C
|
|
move.b #$DE,d0 ; read address, write op
|
|
move.b #$90,d1 ; STA + wr bit
|
|
bsr i2c_wr_cmd
|
|
tst.b d0
|
|
bmi .rxerr
|
|
move.b #$00,d0 ; address zero
|
|
move.b #$10,d1 ; wr bit
|
|
bsr i2c_wr_cmd
|
|
tst.b d0
|
|
bmi .rxerr
|
|
move.w #$20,d2
|
|
.0001
|
|
move.b (a5,d2.w),d0
|
|
move.b #$10,d1
|
|
bsr i2c_wr_cmd
|
|
tst.b d0
|
|
bmi .rxerr
|
|
addi.w #1,d2
|
|
cmpi.w #$5F,d2
|
|
bne.s .0001
|
|
move.b (a5,d2.w),d0
|
|
move.b #$50,d1 ; STO, wr bit
|
|
bsr i2c_wr_cmd
|
|
tst.b d0
|
|
bmi .rxerr
|
|
move.b #0,I2C_CTRL(a6) ; disable I2C and return 0
|
|
moveq #0,d0
|
|
rts
|
|
.rxerr:
|
|
move.b #0,I2C_CTRL(a6) ; disable I2C and return status
|
|
rts
|
|
|
|
msgRtcReadFail:
|
|
dc.b "RTC read/write failed.",$0A,$0D,$00
|
|
|
|
even
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
even
|
even
|
|
|