;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
;
|
;
|
; system memory map
|
; system memory map
|
;
|
;
|
;
|
;
|
; 00000000 +----------------+ <+
|
; 00000000 +----------------+ <+
|
; | startup sp,pc | 8 B |
|
; | startup sp,pc | 8 B |
|
; 00000008 +----------------+ |
|
; 00000008 +----------------+ |
|
; | vectors | pair shared+
|
; | vectors | pair shared+
|
; 00000400 +----------------+ |
|
; 00000400 +----------------+ |
|
; | bios mem | |
|
; | bios mem | |
|
; 00001000 +----------------+ |
|
; 00001000 +----------------+ |
|
; | bios code | |
|
; | bios code | |
|
; 00008000 +----------------+ <+
|
; 00008000 +----------------+ <+
|
; | unused |
|
; | unused |
|
; 00040000 +----------------+
|
; 00040000 +----------------+
|
; | local ram |
|
; | local ram |
|
; 00042000 +----------------+
|
; 00042000 +----------------+
|
; | unused |
|
; | unused |
|
; 00100000 +----------------+
|
; 00100000 +----------------+
|
; | global ram |
|
; | global ram |
|
; 00101000 +----------------+
|
; 00101000 +----------------+
|
; | serial rcvbuf |
|
; | serial rcvbuf |
|
; 00102000 +----------------+
|
; 00102000 +----------------+
|
; | unused |
|
; | unused |
|
; 20000000 +----------------+
|
; 20000000 +----------------+
|
; | |
|
; | |
|
; | |
|
; | |
|
; | |
|
; | |
|
; : dram memory : 512 MB
|
; : dram memory : 512 MB
|
; | |
|
; | |
|
; | |
|
; | |
|
; | |
|
; | |
|
; 40000000 +----------------+
|
; 40000000 +----------------+
|
; | |
|
; | |
|
; : unused :
|
; : unused :
|
; | |
|
; | |
|
; FD000000 +----------------+
|
; FD000000 +----------------+
|
; | |
|
; | |
|
; : I/O area : 1.0 M
|
; : I/O area : 1.0 M
|
; | |
|
; | |
|
; FFE00000 +----------------+
|
; FFE00000 +----------------+
|
; | |
|
; | |
|
; : unused :
|
; : unused :
|
; | |
|
; | |
|
; 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
|
LF EQU $0A
|
LF EQU $0A
|
CR EQU $0D
|
CR EQU $0D
|
XON EQU $11
|
XON EQU $11
|
XOFF EQU $13
|
XOFF EQU $13
|
|
|
SC_F12 EQU $07
|
SC_F12 EQU $07
|
SC_C EQU $21
|
SC_C EQU $21
|
SC_T EQU $2C
|
SC_T EQU $2C
|
SC_Z EQU $1A
|
SC_Z EQU $1A
|
SC_KEYUP EQU $F0
|
SC_KEYUP EQU $F0
|
SC_EXTEND EQU $E0
|
SC_EXTEND EQU $E0
|
SC_CTRL EQU $14
|
SC_CTRL EQU $14
|
SC_RSHIFT EQU $59
|
SC_RSHIFT EQU $59
|
SC_NUMLOCK EQU $77
|
SC_NUMLOCK EQU $77
|
SC_SCROLLLOCK EQU $7E
|
SC_SCROLLLOCK EQU $7E
|
SC_CAPSLOCK EQU $58
|
SC_CAPSLOCK EQU $58
|
SC_ALT EQU $11
|
SC_ALT EQU $11
|
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
|
RAND EQU $1EFFD00
|
RAND EQU $1EFFD00
|
RAND_NUM EQU $1EFFD00
|
RAND_NUM EQU $1EFFD00
|
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
|
MEMORY_SEMA EQU 6
|
MEMORY_SEMA EQU 6
|
TCB_SEMA EQU 7
|
TCB_SEMA EQU 7
|
|
|
data
|
data
|
dc.l $00040FFC
|
dc.l $00040FFC
|
dc.l start
|
dc.l start
|
dc.l bus_err
|
dc.l bus_err
|
dc.l 0
|
dc.l 0
|
dc.l illegal_trap * ILLEGAL instruction
|
dc.l illegal_trap * ILLEGAL instruction
|
dc.l 0
|
dc.l 0
|
dc.l EXCEPTION_6 * CHK
|
dc.l EXCEPTION_6 * CHK
|
dc.l EXCEPTION_7 * TRAPV
|
dc.l EXCEPTION_7 * TRAPV
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
; 10
|
; 10
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
; 20
|
; 20
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l SpuriousIRQ
|
dc.l SpuriousIRQ
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l irq3_rout
|
dc.l irq3_rout
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
; 30
|
; 30
|
dc.l TickIRQ ; IRQ 30 - timer / keyboard
|
dc.l TickIRQ ; IRQ 30 - timer / keyboard
|
dc.l nmi_rout
|
dc.l nmi_rout
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l trap3 ; breakpoint
|
dc.l trap3 ; breakpoint
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
; 40
|
; 40
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l TRAP15
|
dc.l TRAP15
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
; 50
|
; 50
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l io_irq
|
dc.l io_irq
|
|
|
; 60
|
; 60
|
dc.l KeybdIRQ
|
dc.l KeybdIRQ
|
dc.l SerialIRQ
|
dc.l SerialIRQ
|
dc.l 0
|
dc.l 0
|
dc.l brdisp_trap
|
dc.l brdisp_trap
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
org $400
|
org $400
|
|
|
InstalledIRQ:
|
InstalledIRQ:
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
dc.l 0
|
|
|
org $500
|
org $500
|
|
|
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
|
|
; BIOS variables which must be local (not shared) to each core
|
; BIOS variables which must be local (not shared) to each core
|
|
|
CursorRow equ $40000
|
CursorRow equ $40000
|
CursorCol equ $40001
|
CursorCol equ $40001
|
TextPos equ $40002
|
TextPos equ $40002
|
TextCurpos equ $40002
|
TextCurpos equ $40002
|
TextScr equ $40004
|
TextScr equ $40004
|
S19StartAddress equ $40008
|
S19StartAddress equ $40008
|
KeybdEcho equ $4000C
|
KeybdEcho equ $4000C
|
KeybdWaitFlag equ $4000D
|
KeybdWaitFlag equ $4000D
|
CmdBuf equ $40040
|
CmdBuf equ $40040
|
CmdBufEnd equ $40080
|
CmdBufEnd equ $40080
|
fgColor equ $40084
|
fgColor equ $40084
|
bkColor equ $40088
|
bkColor equ $40088
|
TextRows equ $4008C
|
TextRows equ $4008C
|
TextCols equ $4008D
|
TextCols equ $4008D
|
Regsave equ $40100
|
Regsave equ $40100
|
numBreakpoints equ 8
|
numBreakpoints equ 8
|
BreakpointFlag equ $40200
|
BreakpointFlag equ $40200
|
NumSetBreakpoints equ $40202 ; to $40203
|
NumSetBreakpoints equ $40202 ; to $40203
|
Breakpoints equ $40220 ; to $40240
|
Breakpoints equ $40220 ; to $40240
|
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
|
_KeybdTail equ $00100012
|
_KeybdTail equ $00100012
|
_KeybdCnt equ $00100013
|
_KeybdCnt equ $00100013
|
KeybdID equ $00100016
|
KeybdID equ $00100016
|
_KeybdBuf equ $00100020
|
_KeybdBuf equ $00100020
|
S19Checksum equ $00100150
|
S19Checksum equ $00100150
|
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
|
dbra d0,.0111
|
dbra d0,.0111
|
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
|
; bsr FemtikiInit
|
; bsr FemtikiInit
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #1,d1
|
moveq #1,d1
|
bsr UnlockSemaphore ; allow another cpu access
|
bsr UnlockSemaphore ; allow another cpu access
|
moveq #0,d1
|
moveq #0,d1
|
bsr UnlockSemaphore ; allow other cpus to proceed
|
bsr UnlockSemaphore ; allow other cpus to proceed
|
move.w #$A4A4,leds ; diagnostics
|
move.w #$A4A4,leds ; diagnostics
|
bsr init_plic ; initialize platform level interrupt controller
|
bsr init_plic ; initialize platform level interrupt controller
|
bra StartMon
|
bra StartMon
|
bsr cpu_test
|
bsr cpu_test
|
; lea brdisp_trap,a0 ; set brdisp trap vector
|
; lea brdisp_trap,a0 ; set brdisp trap vector
|
; move.l a0,64*4
|
; move.l a0,64*4
|
|
|
loop2:
|
loop2:
|
move.l #-1,d0
|
move.l #-1,d0
|
loop1:
|
loop1:
|
move.l d0,d1
|
move.l d0,d1
|
lsr.l #8,d1
|
lsr.l #8,d1
|
lsr.l #8,d1
|
lsr.l #8,d1
|
move.b d1,leds
|
move.b d1,leds
|
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
|
; bsr FemtikiInitIRQ
|
; bsr FemtikiInitIRQ
|
do_nothing:
|
do_nothing:
|
bra StartMon
|
bra StartMon
|
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
|
dc.l $01E2,$02FD0300
|
dc.l $01E2,$02FD0300
|
dc.l $01E3,$03FD0300
|
dc.l $01E3,$03FD0300
|
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
|
move.l #510,d0 ; then override for IO later
|
move.l #510,d0 ; then override for IO later
|
.0002
|
.0002
|
move.l d2,d1
|
move.l d2,d1
|
bsr rbo
|
bsr rbo
|
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
|
; Initialize random number generator.
|
; Initialize random number generator.
|
;
|
;
|
; Modifies:
|
; Modifies:
|
; none
|
; none
|
; Parameters:
|
; Parameters:
|
; none
|
; none
|
; Returns:
|
; Returns:
|
; none
|
; none
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
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
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; RandWait
|
; RandWait
|
; Wait some random number of clock cycles before returning.
|
; Wait some random number of clock cycles before returning.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
RandWait:
|
RandWait:
|
movem.l d0/d1,-(a7)
|
movem.l d0/d1,-(a7)
|
bsr RandGetNum
|
bsr RandGetNum
|
andi.w #15,d1
|
andi.w #15,d1
|
.0001:
|
.0001:
|
nop
|
nop
|
dbra d1,.0001
|
dbra d1,.0001
|
movem.l (a7)+,d0/d1
|
movem.l (a7)+,d0/d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Initialize semaphores
|
; Initialize semaphores
|
; - all semaphores are set to unlocked except the first one, which is locked
|
; - all semaphores are set to unlocked except the first one, which is locked
|
; for core #2.
|
; for core #2.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
;
|
;
|
; Modifies:
|
; Modifies:
|
;
|
;
|
; Returns:
|
; Returns:
|
;
|
;
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
InitSemaphores:
|
InitSemaphores:
|
movem.l d1/a0,-(a7)
|
movem.l d1/a0,-(a7)
|
lea semamem,a0
|
lea semamem,a0
|
move.l #$20000,$2000(a0) ; lock the first semaphore for core #2, thread #0
|
move.l #$20000,$2000(a0) ; lock the first semaphore for core #2, thread #0
|
move.w #254,d1
|
move.w #254,d1
|
.0001:
|
.0001:
|
lea 4(a0),a0
|
lea 4(a0),a0
|
clr.l $2000(a0) ; write zeros to unlock
|
clr.l $2000(a0) ; write zeros to unlock
|
dbra d1,.0001
|
dbra d1,.0001
|
movem.l (a7)+,d1/a0
|
movem.l (a7)+,d1/a0
|
rts
|
rts
|
|
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; Parameters:
|
; Parameters:
|
; d1 semaphore number
|
; d1 semaphore number
|
;
|
;
|
; Side Effects:
|
; Side Effects:
|
; increments semaphore, saturates at 255
|
; increments semaphore, saturates at 255
|
;
|
;
|
; Returns:
|
; Returns:
|
; z flag set if semaphore was zero
|
; z flag set if semaphore was zero
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
|
|
;IncrementSemaphore:
|
;IncrementSemaphore:
|
; movem.l d1/a0,-(a7) ; save registers
|
; movem.l d1/a0,-(a7) ; save registers
|
; lea semamem,a0 ; point to semaphore memory
|
; lea semamem,a0 ; point to semaphore memory
|
; ext.w d1 ; make d1 word value
|
; ext.w d1 ; make d1 word value
|
; asl.w #4,d1 ; align to memory
|
; asl.w #4,d1 ; align to memory
|
; tst.b 1(a0,d1.w) ; read (test) value for zero
|
; tst.b 1(a0,d1.w) ; read (test) value for zero
|
; movem.l (a7)+,a0/d1 ; restore regs
|
; movem.l (a7)+,a0/d1 ; restore regs
|
; rts
|
; rts
|
|
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; Parameters:
|
; Parameters:
|
; d1 semaphore number
|
; d1 semaphore number
|
;
|
;
|
; Side Effects:
|
; Side Effects:
|
; decrements semaphore, saturates at zero
|
; decrements semaphore, saturates at zero
|
;
|
;
|
; Returns:
|
; Returns:
|
; z flag set if semaphore was zero
|
; z flag set if semaphore was zero
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
|
|
;DecrementSemaphore:
|
;DecrementSemaphore:
|
; movem.l d1/a0,-(a7) ; save registers
|
; movem.l d1/a0,-(a7) ; save registers
|
; lea semamem,a0 ; point to semaphore memory
|
; lea semamem,a0 ; point to semaphore memory
|
; andi.w #255,d1 ; make d1 word value
|
; andi.w #255,d1 ; make d1 word value
|
; asl.w #4,d1 ; align to memory
|
; asl.w #4,d1 ; align to memory
|
; tst.b 1(a0,d1.w) ; read (test) value for zero
|
; tst.b 1(a0,d1.w) ; read (test) value for zero
|
; movem.l (a7)+,a0/d1 ; restore regs
|
; movem.l (a7)+,a0/d1 ; restore regs
|
; rts
|
; rts
|
|
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; Lock a semaphore
|
; Lock a semaphore
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; 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
|
|
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; Unlocks a semaphore even if not the owner.
|
; Unlocks a semaphore even if not the owner.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; d1 semaphore number
|
; d1 semaphore number
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
|
|
ForceUnlockSemaphore:
|
ForceUnlockSemaphore:
|
movem.l d1/a0,-(a7) ; save registers
|
movem.l d1/a0,-(a7) ; save registers
|
lea semamem+$3000,a0 ; point to semaphore memory read/write area
|
lea semamem+$3000,a0 ; point to semaphore memory read/write 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
|
clr.l (a0,d1.w) ; write zero to unlock
|
clr.l (a0,d1.w) ; write zero to unlock
|
movem.l (a7)+,a0/d1 ; restore regs
|
movem.l (a7)+,a0/d1 ; restore regs
|
rts
|
rts
|
|
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; Unlocks a semaphore. Must be the owner to have effect.
|
; Unlocks a semaphore. Must be the owner to have effect.
|
; Three cases:
|
; Three cases:
|
; 1) the owner, the semaphore will be reset to zero
|
; 1) the owner, the semaphore will be reset to zero
|
; 2) not the owner, the write will be ignored
|
; 2) not the owner, the write will be ignored
|
; 3) already unlocked, the write will be ignored
|
; 3) already unlocked, the write will be ignored
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; 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
|
movem.l (a7)+,a0/d1 ; restore regs
|
movem.l (a7)+,a0/d1 ; restore regs
|
rts
|
rts
|
|
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; 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.
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
|
|
Delay3s:
|
Delay3s:
|
move.l #3000000,d0 ; this should take a few seconds to loop
|
move.l #3000000,d0 ; this should take a few seconds to loop
|
lea leds,a0 ; a0 = address of LED output register
|
lea leds,a0 ; a0 = address of LED output register
|
bra dly3s1 ; branch to the loop
|
bra dly3s1 ; branch to the loop
|
dly3s2:
|
dly3s2:
|
swap d0 ; loop is larger than 16-bits
|
swap d0 ; loop is larger than 16-bits
|
dly3s1:
|
dly3s1:
|
move.l d0,d1 ; the counter cycles fast, so use upper bits for display
|
move.l d0,d1 ; the counter cycles fast, so use upper bits for display
|
rol.l #8,d1 ; could use swap here, but lets test rol
|
rol.l #8,d1 ; could use swap here, but lets test rol
|
rol.l #8,d1
|
rol.l #8,d1
|
move.b d1,(a0) ; set the LEDs
|
move.b d1,(a0) ; set the LEDs
|
dbra d0,dly3s1 ; decrement and branch back
|
dbra d0,dly3s1 ; decrement and branch back
|
swap d0
|
swap d0
|
dbra d0,dly3s2
|
dbra d0,dly3s2
|
rts
|
rts
|
|
|
Delay3s2:
|
Delay3s2:
|
movec coreno,d0 ; vary delay by core to stagger startup
|
movec coreno,d0 ; vary delay by core to stagger startup
|
lsl.l #8,d0
|
lsl.l #8,d0
|
addi.l #3000000,d0 ; this should take a few seconds to loop
|
addi.l #3000000,d0 ; this should take a few seconds to loop
|
bra .0001 ; branch to the loop
|
bra .0001 ; branch to the loop
|
.0002
|
.0002
|
swap d0 ; loop is larger than 16-bits
|
swap d0 ; loop is larger than 16-bits
|
.0001
|
.0001
|
dbra d0,.0001 ; decrement and branch back
|
dbra d0,.0001 ; decrement and branch back
|
swap d0
|
swap d0
|
dbra d0,.0002
|
dbra d0,.0002
|
rts
|
rts
|
|
|
include "cputest.asm"
|
include "cputest.asm"
|
include "TinyBasic.asm"
|
include "TinyBasic.asm"
|
include "..\Femtiki\source\kernel\Femtiki.x68"
|
include "..\Femtiki\source\kernel\Femtiki.x68"
|
|
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; Gets the screen color in d0 and d1.
|
; Gets the screen color in d0 and d1.
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
|
|
get_screen_color:
|
get_screen_color:
|
move.l fgColor,d0 ; get foreground color
|
move.l fgColor,d0 ; get foreground color
|
asl.l #5,d0 ; shift into position
|
asl.l #5,d0 ; shift into position
|
ori.l #$40000000,d0 ; set priority
|
ori.l #$40000000,d0 ; set priority
|
move.l bkColor,d1
|
move.l bkColor,d1
|
lsr.l #8,d1
|
lsr.l #8,d1
|
lsr.l #8,d1
|
lsr.l #8,d1
|
andi.l #31,d1 ; mask off extra bits
|
andi.l #31,d1 ; mask off extra bits
|
or.l d1,d0 ; set background color bits in upper long word
|
or.l d1,d0 ; set background color bits in upper long word
|
move.l bkColor,d1 ; get background color
|
move.l bkColor,d1 ; get background color
|
asl.l #8,d1 ; shift into position for display ram
|
asl.l #8,d1 ; shift into position for display ram
|
asl.l #8,d1
|
asl.l #8,d1
|
rts
|
rts
|
|
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
|
|
get_screen_address:
|
get_screen_address:
|
move.l TextScr,a0
|
move.l TextScr,a0
|
rts
|
rts
|
|
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
|
|
clear_screen:
|
clear_screen:
|
movem.l d0/d1/d2/a0,-(a7)
|
movem.l d0/d1/d2/a0,-(a7)
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SCREEN_SEMA,d1
|
moveq #SCREEN_SEMA,d1
|
bsr LockSemaphore
|
bsr LockSemaphore
|
bsr get_screen_address ; a0 = pointer to screen area
|
bsr get_screen_address ; a0 = pointer to screen area
|
move.b TextRows,d0 ; d0 = rows
|
move.b TextRows,d0 ; d0 = rows
|
move.b TextCols,d2 ; d2 = cols
|
move.b TextCols,d2 ; d2 = cols
|
ext.w d0 ; convert to word
|
ext.w d0 ; convert to word
|
ext.w d2 ; convert to word
|
ext.w d2 ; convert to word
|
mulu d0,d2 ; d2 = number of character cells to clear
|
mulu d0,d2 ; d2 = number of character cells to clear
|
bsr get_screen_color ; get the color bits
|
bsr get_screen_color ; get the color bits
|
ori.w #32,d1 ; load space character
|
ori.w #32,d1 ; load space character
|
rol.w #8,d1 ; swap endian, text controller expects little endian
|
rol.w #8,d1 ; swap endian, text controller expects little endian
|
swap d1
|
swap d1
|
rol.w #8,d1
|
rol.w #8,d1
|
rol.w #8,d0 ; swap endian
|
rol.w #8,d0 ; swap endian
|
swap d0
|
swap d0
|
rol.w #8,d0
|
rol.w #8,d0
|
loop3:
|
loop3:
|
move.l d1,(a0)+ ; copy char plus bkcolor to cell
|
move.l d1,(a0)+ ; copy char plus bkcolor to cell
|
move.l d0,(a0)+ ; copy fgcolor to cell
|
move.l d0,(a0)+ ; copy fgcolor to cell
|
dbra d2,loop3
|
dbra d2,loop3
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SCREEN_SEMA,d1
|
moveq #SCREEN_SEMA,d1
|
bsr UnlockSemaphore
|
bsr UnlockSemaphore
|
movem.l (a7)+,d0/d1/d2/a0
|
movem.l (a7)+,d0/d1/d2/a0
|
rts
|
rts
|
|
|
CRLF:
|
CRLF:
|
move.l d1,-(a7)
|
move.l d1,-(a7)
|
move.b #13,d1
|
move.b #13,d1
|
bsr DisplayChar
|
bsr DisplayChar
|
move.b #10,d1
|
move.b #10,d1
|
bsr DisplayChar
|
bsr DisplayChar
|
move.l (a7)+,d1
|
move.l (a7)+,d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
UpdateTextPos:
|
UpdateTextPos:
|
move.b CursorRow,d0 ; compute screen location
|
move.b CursorRow,d0 ; compute screen location
|
andi.w #$7f,d0
|
andi.w #$7f,d0
|
move.b TextCols,d2
|
move.b TextCols,d2
|
ext.w d2
|
ext.w d2
|
mulu.w d2,d0
|
mulu.w d2,d0
|
move.l d0,d3
|
move.l d0,d3
|
move.b CursorCol,d2
|
move.b CursorCol,d2
|
andi.w #$ff,d2
|
andi.w #$ff,d2
|
add.w d2,d0
|
add.w d2,d0
|
move.w d0,TextPos ; save cursor pos
|
move.w d0,TextPos ; save cursor pos
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Calculate screen memory location from CursorRow,CursorCol.
|
; Calculate screen memory location from CursorRow,CursorCol.
|
; Destroys d0,d2,a0
|
; Destroys d0,d2,a0
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
CalcScreenLoc:
|
CalcScreenLoc:
|
bsr UpdateTextPos
|
bsr UpdateTextPos
|
ext.l d0 ; make it into a long
|
ext.l d0 ; make it into a long
|
asl.l #3,d0 ; 8 bytes per char
|
asl.l #3,d0 ; 8 bytes per char
|
bsr get_screen_address
|
bsr get_screen_address
|
add.l d0,a0 ; a0 = screen location
|
add.l d0,a0 ; a0 = screen location
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Display a character on the screen
|
; Display a character on the screen
|
; d1.b = char to display
|
; d1.b = char to display
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisplayChar:
|
DisplayChar:
|
movem.l d1/d2/d3,-(a7)
|
movem.l d1/d2/d3,-(a7)
|
movec coreno,d2
|
movec coreno,d2
|
cmpi.b #2,d2
|
cmpi.b #2,d2
|
; bne.s .0001
|
; bne.s .0001
|
; bsr SerialPutChar
|
; bsr SerialPutChar
|
.0001:
|
.0001:
|
andi.l #$ff,d1 ; zero out upper bytes of d1
|
andi.l #$ff,d1 ; zero out upper bytes of d1
|
cmpi.b #13,d1 ; carriage return ?
|
cmpi.b #13,d1 ; carriage return ?
|
bne dccr
|
bne dccr
|
clr.b CursorCol ; just set cursor column to zero on a CR
|
clr.b CursorCol ; just set cursor column to zero on a CR
|
dcx14:
|
dcx14:
|
bsr SyncCursor ; set position in text controller
|
bsr SyncCursor ; set position in text controller
|
dcx7:
|
dcx7:
|
movem.l (a7)+,d1/d2/d3
|
movem.l (a7)+,d1/d2/d3
|
rts
|
rts
|
dccr:
|
dccr:
|
cmpi.b #$91,d1 ; cursor right ?
|
cmpi.b #$91,d1 ; cursor right ?
|
bne.s dcx6
|
bne.s dcx6
|
move.b TextCols,d2
|
move.b TextCols,d2
|
sub.b #1,d2
|
sub.b #1,d2
|
sub.b CursorCol,d2
|
sub.b CursorCol,d2
|
beq.s dcx7
|
beq.s dcx7
|
addi.b #1,CursorCol
|
addi.b #1,CursorCol
|
bra.s dcx14
|
bra.s dcx14
|
dcx6:
|
dcx6:
|
cmpi.b #$90,d1 ; cursor up ?
|
cmpi.b #$90,d1 ; cursor up ?
|
bne.s dcx8
|
bne.s dcx8
|
cmpi.b #0,CursorRow
|
cmpi.b #0,CursorRow
|
beq.s dcx7
|
beq.s dcx7
|
subi.b #1,CursorRow
|
subi.b #1,CursorRow
|
bra.s dcx14
|
bra.s dcx14
|
dcx8:
|
dcx8:
|
cmpi.b #$93,d1 ; cursor left?
|
cmpi.b #$93,d1 ; cursor left?
|
bne.s dcx9
|
bne.s dcx9
|
cmpi.b #0,CursorCol
|
cmpi.b #0,CursorCol
|
beq.s dcx7
|
beq.s dcx7
|
subi.b #1,CursorCol
|
subi.b #1,CursorCol
|
bra.s dcx14
|
bra.s dcx14
|
dcx9:
|
dcx9:
|
cmpi.b #$92,d1 ; cursor down ?
|
cmpi.b #$92,d1 ; cursor down ?
|
bne.s dcx10
|
bne.s dcx10
|
move.b TextRows,d2
|
move.b TextRows,d2
|
sub.b #1,d2
|
sub.b #1,d2
|
cmp.b CursorRow,d2
|
cmp.b CursorRow,d2
|
beq.s dcx7
|
beq.s dcx7
|
addi.b #1,CursorRow
|
addi.b #1,CursorRow
|
bra.s dcx14
|
bra.s dcx14
|
dcx10:
|
dcx10:
|
cmpi.b #$94,d1 ; cursor home ?
|
cmpi.b #$94,d1 ; cursor home ?
|
bne.s dcx11
|
bne.s dcx11
|
cmpi.b #0,CursorCol
|
cmpi.b #0,CursorCol
|
beq.s dcx12
|
beq.s dcx12
|
clr.b CursorCol
|
clr.b CursorCol
|
bra dcx14
|
bra dcx14
|
dcx12:
|
dcx12:
|
clr.b CursorRow
|
clr.b CursorRow
|
bra dcx14
|
bra dcx14
|
dcx11:
|
dcx11:
|
movem.l d0/d1/d2/a0,-(a7)
|
movem.l d0/d1/d2/a0,-(a7)
|
cmpi.b #$99,d1 ; delete ?
|
cmpi.b #$99,d1 ; delete ?
|
beq.s doDelete
|
beq.s doDelete
|
cmpi.b #CTRLH,d1 ; backspace ?
|
cmpi.b #CTRLH,d1 ; backspace ?
|
beq.s doBackspace
|
beq.s doBackspace
|
cmpi.b #CTRLX,d1 ; delete line ?
|
cmpi.b #CTRLX,d1 ; delete line ?
|
beq doCtrlX
|
beq doCtrlX
|
cmpi.b #10,d1 ; linefeed ?
|
cmpi.b #10,d1 ; linefeed ?
|
beq.s dclf
|
beq.s dclf
|
|
|
; regular char
|
; regular char
|
bsr CalcScreenLoc ; a0 = screen location
|
bsr CalcScreenLoc ; a0 = screen location
|
move.l d1,d2 ; d2 = char
|
move.l d1,d2 ; d2 = char
|
bsr get_screen_color ; d0,d1 = color
|
bsr get_screen_color ; d0,d1 = color
|
or.l d2,d1 ; d1 = char + color
|
or.l d2,d1 ; d1 = char + color
|
rol.w #8,d1 ; text controller expects little endian data
|
rol.w #8,d1 ; text controller expects little endian data
|
swap d1
|
swap d1
|
rol.w #8,d1
|
rol.w #8,d1
|
move.l d1,(a0)
|
move.l d1,(a0)
|
rol.w #8,d0 ; swap bytes
|
rol.w #8,d0 ; swap bytes
|
swap d0 ; swap halfs
|
swap d0 ; swap halfs
|
rol.w #8,d0 ; swap remaining bytes
|
rol.w #8,d0 ; swap remaining bytes
|
move.l d0,4(a0)
|
move.l d0,4(a0)
|
bsr IncCursorPos
|
bsr IncCursorPos
|
bsr SyncCursor
|
bsr SyncCursor
|
bra dcx4
|
bra dcx4
|
dclf:
|
dclf:
|
bsr IncCursorRow
|
bsr IncCursorRow
|
dcx16:
|
dcx16:
|
bsr SyncCursor
|
bsr SyncCursor
|
dcx4:
|
dcx4:
|
movem.l (a7)+,d0/d1/d2/a0 ; get back a0
|
movem.l (a7)+,d0/d1/d2/a0 ; get back a0
|
movem.l (a7)+,d1/d2/d3
|
movem.l (a7)+,d1/d2/d3
|
rts
|
rts
|
|
|
;---------------------------
|
;---------------------------
|
; CTRL-H: backspace
|
; CTRL-H: backspace
|
;---------------------------
|
;---------------------------
|
doBackspace:
|
doBackspace:
|
cmpi.b #0,CursorCol ; if already at start of line
|
cmpi.b #0,CursorCol ; if already at start of line
|
beq.s dcx4 ; nothing to do
|
beq.s dcx4 ; nothing to do
|
subi.b #1,CursorCol ; decrement column
|
subi.b #1,CursorCol ; decrement column
|
|
|
;---------------------------
|
;---------------------------
|
; Delete key
|
; Delete key
|
;---------------------------
|
;---------------------------
|
doDelete:
|
doDelete:
|
movem.l d0/d1/a0,-(a7) ; save off screen location
|
movem.l d0/d1/a0,-(a7) ; save off screen location
|
bsr CalcScreenLoc ; a0 = screen location
|
bsr CalcScreenLoc ; a0 = screen location
|
move.b CursorCol,d0
|
move.b CursorCol,d0
|
.0001:
|
.0001:
|
move.l 8(a0),(a0) ; pull remaining characters on line over 1
|
move.l 8(a0),(a0) ; pull remaining characters on line over 1
|
move.l 12(a0),4(a0) ; pull remaining characters on line over 1
|
move.l 12(a0),4(a0) ; pull remaining characters on line over 1
|
lea 8(a0),a0
|
lea 8(a0),a0
|
addi.b #1,d0
|
addi.b #1,d0
|
cmp.b TextCols,d0
|
cmp.b TextCols,d0
|
blo.s .0001
|
blo.s .0001
|
bsr get_screen_color
|
bsr get_screen_color
|
move.w #' ',d1 ; terminate line with a space
|
move.w #' ',d1 ; terminate line with a space
|
rol.w #8,d1
|
rol.w #8,d1
|
swap d1
|
swap d1
|
rol.w #8,d1
|
rol.w #8,d1
|
move.l d1,-8(a0)
|
move.l d1,-8(a0)
|
movem.l (a7)+,d0/d1/a0
|
movem.l (a7)+,d0/d1/a0
|
bra.s dcx16 ; finished
|
bra.s dcx16 ; finished
|
|
|
;---------------------------
|
;---------------------------
|
; CTRL-X: erase line
|
; CTRL-X: erase line
|
;---------------------------
|
;---------------------------
|
doCtrlX:
|
doCtrlX:
|
clr.b CursorCol ; Reset cursor to start of line
|
clr.b CursorCol ; Reset cursor to start of line
|
move.b TextCols,d0 ; and display TextCols number of spaces
|
move.b TextCols,d0 ; and display TextCols number of spaces
|
ext.w d0
|
ext.w d0
|
ext.l d0
|
ext.l d0
|
move.b #' ',d1 ; d1 = space char
|
move.b #' ',d1 ; d1 = space char
|
.0001:
|
.0001:
|
; DisplayChar is called recursively here
|
; DisplayChar is called recursively here
|
; It's safe to do because we know it won't recurse again due to the
|
; It's safe to do because we know it won't recurse again due to the
|
; fact we know the character being displayed is a space char
|
; fact we know the character being displayed is a space char
|
bsr DisplayChar
|
bsr DisplayChar
|
subq #1,d0
|
subq #1,d0
|
bne.s .0001
|
bne.s .0001
|
clr.b CursorCol ; now really go back to start of line
|
clr.b CursorCol ; now really go back to start of line
|
bra.s dcx16 ; we're done
|
bra.s dcx16 ; we're done
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Increment the cursor position, scroll the screen if needed.
|
; Increment the cursor position, scroll the screen if needed.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
IncCursorPos:
|
IncCursorPos:
|
addi.w #1,TextCurpos
|
addi.w #1,TextCurpos
|
addi.b #1,CursorCol
|
addi.b #1,CursorCol
|
move.b TextCols,d0
|
move.b TextCols,d0
|
cmp.b CursorCol,d0
|
cmp.b CursorCol,d0
|
bhs.s icc1
|
bhs.s icc1
|
clr.b CursorCol
|
clr.b CursorCol
|
IncCursorRow:
|
IncCursorRow:
|
addi.b #1,CursorRow
|
addi.b #1,CursorRow
|
move.b TextRows,d0
|
move.b TextRows,d0
|
cmp.b CursorRow,d0
|
cmp.b CursorRow,d0
|
bhi.s icc1
|
bhi.s icc1
|
move.b TextRows,d0
|
move.b TextRows,d0
|
move.b d0,CursorRow ; in case CursorRow is way over
|
move.b d0,CursorRow ; in case CursorRow is way over
|
subi.b #1,CursorRow
|
subi.b #1,CursorRow
|
ext.w d0
|
ext.w d0
|
asl.w #1,d0
|
asl.w #1,d0
|
sub.w d0,TextCurpos
|
sub.w d0,TextCurpos
|
bsr ScrollUp
|
bsr ScrollUp
|
icc1:
|
icc1:
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Scroll screen up.
|
; Scroll screen up.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
ScrollUp:
|
ScrollUp:
|
movem.l d0/d1/a0/a5,-(a7) ; save off some regs
|
movem.l d0/d1/a0/a5,-(a7) ; save off some regs
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SCREEN_SEMA,d1
|
moveq #SCREEN_SEMA,d1
|
bsr LockSemaphore
|
bsr LockSemaphore
|
bsr get_screen_address
|
bsr get_screen_address
|
move.l a0,a5 ; a5 = pointer to text screen
|
move.l a0,a5 ; a5 = pointer to text screen
|
.0003:
|
.0003:
|
move.b TextCols,d0 ; d0 = columns
|
move.b TextCols,d0 ; d0 = columns
|
move.b TextRows,d1 ; d1 = rows
|
move.b TextRows,d1 ; d1 = rows
|
ext.w d0 ; make cols into a word value
|
ext.w d0 ; make cols into a word value
|
ext.w d1 ; make rows into a word value
|
ext.w d1 ; make rows into a word value
|
asl.w #3,d0 ; make into cell index
|
asl.w #3,d0 ; make into cell index
|
lea 0(a5,d0.w),a0 ; a0 = pointer to second row of text screen
|
lea 0(a5,d0.w),a0 ; a0 = pointer to second row of text screen
|
lsr.w #3,d0 ; get back d0
|
lsr.w #3,d0 ; get back d0
|
subq #1,d1 ; number of rows-1
|
subq #1,d1 ; number of rows-1
|
mulu d1,d0 ; d0 = count of characters to move
|
mulu d1,d0 ; d0 = count of characters to move
|
.0001:
|
.0001:
|
move.l (a0)+,(a5)+ ; each char is 64 bits
|
move.l (a0)+,(a5)+ ; each char is 64 bits
|
move.l (a0)+,(a5)+
|
move.l (a0)+,(a5)+
|
dbra d0,.0001
|
dbra d0,.0001
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SCREEN_SEMA,d1
|
moveq #SCREEN_SEMA,d1
|
bsr UnlockSemaphore
|
bsr UnlockSemaphore
|
movem.l (a7)+,d0/d1/a0/a5
|
movem.l (a7)+,d0/d1/a0/a5
|
; Fall through into blanking out last line
|
; Fall through into blanking out last line
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Blank out the last line on the screen.
|
; Blank out the last line on the screen.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
BlankLastLine:
|
BlankLastLine:
|
movem.l d0/d1/d2/a0,-(a7)
|
movem.l d0/d1/d2/a0,-(a7)
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SCREEN_SEMA,d1
|
moveq #SCREEN_SEMA,d1
|
bsr LockSemaphore
|
bsr LockSemaphore
|
bsr get_screen_address
|
bsr get_screen_address
|
move.b TextRows,d0 ; d0 = rows
|
move.b TextRows,d0 ; d0 = rows
|
move.b TextCols,d1 ; d1 = columns
|
move.b TextCols,d1 ; d1 = columns
|
ext.w d0
|
ext.w d0
|
ext.w d1
|
ext.w d1
|
subq #1,d0 ; last row = #rows-1
|
subq #1,d0 ; last row = #rows-1
|
mulu d1,d0 ; d0 = index of last line
|
mulu d1,d0 ; d0 = index of last line
|
lsl.w #3,d0 ; *8 bytes per char
|
lsl.w #3,d0 ; *8 bytes per char
|
lea (a0,d0.w),a0 ; point a0 to last row
|
lea (a0,d0.w),a0 ; point a0 to last row
|
move.b TextCols,d2 ; number of text cells to clear
|
move.b TextCols,d2 ; number of text cells to clear
|
ext.w d2
|
ext.w d2
|
subi.w #1,d2 ; count must be one less than desired
|
subi.w #1,d2 ; count must be one less than desired
|
bsr get_screen_color ; d0,d1 = screen color
|
bsr get_screen_color ; d0,d1 = screen color
|
move.w #32,d1 ; set the character for display in low 16 bits
|
move.w #32,d1 ; set the character for display in low 16 bits
|
bsr rbo ; reverse the byte order
|
bsr rbo ; reverse the byte order
|
rol.w #8,d0
|
rol.w #8,d0
|
swap d0
|
swap d0
|
rol.w #8,d0
|
rol.w #8,d0
|
.0001:
|
.0001:
|
move.l d0,(a0)+
|
move.l d0,(a0)+
|
move.l d1,(a0)+
|
move.l d1,(a0)+
|
dbra d2,.0001
|
dbra d2,.0001
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SCREEN_SEMA,d1
|
moveq #SCREEN_SEMA,d1
|
bsr UnlockSemaphore
|
bsr UnlockSemaphore
|
movem.l (a7)+,d0/d1/d2/a0
|
movem.l (a7)+,d0/d1/d2/a0
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Display a string on the screen.
|
; Display a string on the screen.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisplayString:
|
DisplayString:
|
movem.l d0/d1/a1,-(a7)
|
movem.l d0/d1/a1,-(a7)
|
dspj1:
|
dspj1:
|
clr.l d1 ; clear upper bits of d1
|
clr.l d1 ; clear upper bits of d1
|
move.b (a1)+,d1 ; move string char into d1
|
move.b (a1)+,d1 ; move string char into d1
|
beq.s dsret ; is it end of string ?
|
beq.s dsret ; is it end of string ?
|
bsr DisplayChar ; display character
|
bsr DisplayChar ; display character
|
bra.s dspj1 ; go back for next character
|
bra.s dspj1 ; go back for next character
|
dsret:
|
dsret:
|
movem.l (a7)+,d0/d1/a1
|
movem.l (a7)+,d0/d1/a1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Display a string on the screen followed by carriage return / linefeed.
|
; Display a string on the screen followed by carriage return / linefeed.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisplayStringCRLF:
|
DisplayStringCRLF:
|
bsr DisplayString
|
bsr DisplayString
|
bra CRLF
|
bra CRLF
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Display a string on the screen limited to 255 chars max.
|
; Display a string on the screen limited to 255 chars max.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisplayStringLimited:
|
DisplayStringLimited:
|
movem.l d0/d1/d2/a1,-(a7)
|
movem.l d0/d1/d2/a1,-(a7)
|
move.w d1,d2 ; d2 = max count
|
move.w d1,d2 ; d2 = max count
|
andi.w #$00FF,d2 ; limit to 255 chars
|
andi.w #$00FF,d2 ; limit to 255 chars
|
bra.s .0003 ; enter loop at bottom
|
bra.s .0003 ; enter loop at bottom
|
.0001:
|
.0001:
|
clr.l d1 ; clear upper bits of d1
|
clr.l d1 ; clear upper bits of d1
|
move.b (a1)+,d1 ; move string char into d1
|
move.b (a1)+,d1 ; move string char into d1
|
beq.s .0002 ; is it end of string ?
|
beq.s .0002 ; is it end of string ?
|
bsr DisplayChar ; display character
|
bsr DisplayChar ; display character
|
.0003:
|
.0003:
|
dbra d2,.0001 ; go back for next character
|
dbra d2,.0001 ; go back for next character
|
.0002:
|
.0002:
|
movem.l (a7)+,d0/d1/d2/a1
|
movem.l (a7)+,d0/d1/d2/a1
|
rts
|
rts
|
|
|
DisplayStringLimitedCRLF:
|
DisplayStringLimitedCRLF:
|
bsr DisplayStringLimited
|
bsr DisplayStringLimited
|
bra CRLF
|
bra CRLF
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Set cursor position to top left of screen.
|
; Set cursor position to top left of screen.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
;
|
;
|
; Returns:
|
; Returns:
|
;
|
;
|
; Registers Affected:
|
; Registers Affected:
|
;
|
;
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
HomeCursor:
|
HomeCursor:
|
clr.b CursorRow
|
clr.b CursorRow
|
clr.b CursorCol
|
clr.b CursorCol
|
clr.w TextPos
|
clr.w TextPos
|
; fall through
|
; fall through
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; SyncCursor:
|
; SyncCursor:
|
;
|
;
|
; Sync the hardware cursor's position to the text cursor position but only for
|
; Sync the hardware cursor's position to the text cursor position but only for
|
; the core with the IO focus.
|
; the core with the IO focus.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
;
|
;
|
; Returns:
|
; Returns:
|
;
|
;
|
; Registers Affected:
|
; Registers Affected:
|
;
|
;
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SyncCursor:
|
SyncCursor:
|
movem.l d0/d2,-(a7)
|
movem.l d0/d2,-(a7)
|
bsr UpdateTextPos
|
bsr UpdateTextPos
|
movec coreno,d2
|
movec coreno,d2
|
cmp.b IOFocus,d2
|
cmp.b IOFocus,d2
|
bne.s .0001
|
bne.s .0001
|
subi.w #2,d2 ; factor in location of screen in controller
|
subi.w #2,d2 ; factor in location of screen in controller
|
mulu #2048,d2 ; 2048 cells per screen
|
mulu #2048,d2 ; 2048 cells per screen
|
add.w d2,d0
|
add.w d2,d0
|
rol.w #8,d0 ; swap byte order
|
rol.w #8,d0 ; swap byte order
|
move.w d0,TEXTREG+$24
|
move.w d0,TEXTREG+$24
|
.0001:
|
.0001:
|
movem.l (a7)+,d0/d2
|
movem.l (a7)+,d0/d2
|
rts
|
rts
|
|
|
;==============================================================================
|
;==============================================================================
|
; TRAP #15 handler
|
; TRAP #15 handler
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; d0.w = function number to perform
|
; d0.w = function number to perform
|
;==============================================================================
|
;==============================================================================
|
|
|
TRAP15:
|
TRAP15:
|
movem.l d0/a0,-(a7)
|
movem.l d0/a0,-(a7)
|
lea T15DispatchTable,a0
|
lea T15DispatchTable,a0
|
asl.l #2,d0
|
asl.l #2,d0
|
move.l (a0,d0.w),a0
|
move.l (a0,d0.w),a0
|
jsr (a0)
|
jsr (a0)
|
movem.l (a7)+,d0/a0
|
movem.l (a7)+,d0/a0
|
rte
|
rte
|
|
|
align 2
|
align 2
|
T15DispatchTable:
|
T15DispatchTable:
|
dc.l DisplayStringLimitedCRLF
|
dc.l DisplayStringLimitedCRLF
|
dc.l DisplayStringLimited
|
dc.l DisplayStringLimited
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l GetKey
|
dc.l GetKey
|
dc.l DisplayChar
|
dc.l DisplayChar
|
dc.l CheckForKey
|
dc.l CheckForKey
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
; 10
|
; 10
|
dc.l StubRout
|
dc.l StubRout
|
dc.l Cursor1
|
dc.l Cursor1
|
dc.l SetKeyboardEcho
|
dc.l SetKeyboardEcho
|
dc.l DisplayStringCRLF
|
dc.l DisplayStringCRLF
|
dc.l DisplayString
|
dc.l DisplayString
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
; 20
|
; 20
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
; 30
|
; 30
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l StubRout
|
dc.l rotate_iofocus
|
dc.l rotate_iofocus
|
dc.l SerialPeekCharDirect
|
dc.l SerialPeekCharDirect
|
dc.l SerialPutChar
|
dc.l SerialPutChar
|
dc.l SerialPeekChar
|
dc.l SerialPeekChar
|
dc.l SerialGetChar
|
dc.l SerialGetChar
|
dc.l T15LockSemaphore
|
dc.l T15LockSemaphore
|
dc.l T15UnlockSemaphore
|
dc.l T15UnlockSemaphore
|
dc.l StubRout
|
dc.l StubRout
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Cursor positioning / Clear screen
|
; Cursor positioning / Clear screen
|
; - out of range settings are ignored
|
; - out of range settings are ignored
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; d1.w cursor position, bits 0 to 7 are row, bits 8 to 15 are column.
|
; d1.w cursor position, bits 0 to 7 are row, bits 8 to 15 are column.
|
; Returns:
|
; Returns:
|
; none
|
; none
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
Cursor1:
|
Cursor1:
|
move.l d1,-(a7)
|
move.l d1,-(a7)
|
cmpi.w #$FF00,d1
|
cmpi.w #$FF00,d1
|
bne.s .0002
|
bne.s .0002
|
bsr clear_screen
|
bsr clear_screen
|
bra HomeCursor
|
bra HomeCursor
|
.0002:
|
.0002:
|
cmp.b TextRows,d1 ; if cursor pos out of range, ignore setting
|
cmp.b TextRows,d1 ; if cursor pos out of range, ignore setting
|
bhs.s .0003
|
bhs.s .0003
|
move.b d1,CursorRow
|
move.b d1,CursorRow
|
.0003:
|
.0003:
|
ror.w #8,d1
|
ror.w #8,d1
|
cmp.b TextCols,d1
|
cmp.b TextCols,d1
|
bhs.s .0001
|
bhs.s .0001
|
move.b d1,CursorCol
|
move.b d1,CursorCol
|
.0001:
|
.0001:
|
bsr SyncCursor ; update hardware cursor
|
bsr SyncCursor ; update hardware cursor
|
move.l (a7)+,d1
|
move.l (a7)+,d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Stub routine for unimplemented functionality.
|
; Stub routine for unimplemented functionality.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
StubRout:
|
StubRout:
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Select a specific IO focus.
|
; Select a specific IO focus.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
select_iofocus:
|
select_iofocus:
|
cmpi.b #2,d1
|
cmpi.b #2,d1
|
blo.s .0001
|
blo.s .0001
|
cmpi.b #9,d1
|
cmpi.b #9,d1
|
bhi.s .0001
|
bhi.s .0001
|
move.l d1,d0
|
move.l d1,d0
|
bra.s select_focus1
|
bra.s select_focus1
|
.0001:
|
.0001:
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Rotate the IO focus, done when ALT-Tab is pressed.
|
; Rotate the IO focus, done when ALT-Tab is pressed.
|
;
|
;
|
; Modifies:
|
; Modifies:
|
; d0, IOFocus BIOS variable
|
; d0, IOFocus BIOS variable
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
rotate_iofocus:
|
rotate_iofocus:
|
move.b IOFocus,d0 ; d0 = focus, we can trash d0
|
move.b IOFocus,d0 ; d0 = focus, we can trash d0
|
add.b #1,d0 ; increment the focus
|
add.b #1,d0 ; increment the focus
|
cmp.b #9,d0 ; limit to 2 to 9
|
cmp.b #9,d0 ; limit to 2 to 9
|
bls.s .0001
|
bls.s .0001
|
move.b #2,d0
|
move.b #2,d0
|
.0001:
|
.0001:
|
select_focus1:
|
select_focus1:
|
move.b d0,IOFocus ; set IO focus
|
move.b d0,IOFocus ; set IO focus
|
subi.b #2,d0 ; screen is 0 to 7, focus is 2 to 9
|
subi.b #2,d0 ; screen is 0 to 7, focus is 2 to 9
|
ext.w d0 ; make into long value
|
ext.w d0 ; make into long value
|
mulu #2048,d0 ; * 2048 cells per screen
|
mulu #2048,d0 ; * 2048 cells per screen
|
rol.w #8,d0 ; swap byte order
|
rol.w #8,d0 ; swap byte order
|
move.w d0,TEXTREG+$28 ; update screen address in text controller
|
move.w d0,TEXTREG+$28 ; update screen address in text controller
|
bra SyncCursor ; set cursor position
|
bra SyncCursor ; set cursor position
|
|
|
;==============================================================================
|
;==============================================================================
|
; PLIC - platform level interrupt controller
|
; PLIC - platform level interrupt controller
|
;
|
;
|
; Register layout:
|
; Register layout:
|
; bits 0 to 7 = cause code to issue (vector number)
|
; bits 0 to 7 = cause code to issue (vector number)
|
; bits 8 to 11 = irq level to issue
|
; bits 8 to 11 = irq level to issue
|
; bit 16 = irq enable
|
; bit 16 = irq enable
|
; bit 17 = edge sensitivity
|
; bit 17 = edge sensitivity
|
; bit 18 = 0=vpa, 1=inta
|
; bit 18 = 0=vpa, 1=inta
|
; bit 24 to 29 target core
|
; bit 24 to 29 target core
|
;
|
;
|
; Note byte order must be reversed for PLIC.
|
; Note byte order must be reversed for PLIC.
|
;==============================================================================
|
;==============================================================================
|
|
|
init_plic:
|
init_plic:
|
lea PLIC,a0 ; a0 points to PLIC
|
lea PLIC,a0 ; a0 points to PLIC
|
lea $80+4*29(a0),a1 ; point to timer registers (29)
|
lea $80+4*29(a0),a1 ; point to timer registers (29)
|
move.l #$0006033F,(a1) ; initialize, core=63,edge sensitive,enabled,irq6,vpa
|
move.l #$0006033F,(a1) ; initialize, core=63,edge sensitive,enabled,irq6,vpa
|
lea 4(a1),a1 ; point to keyboard registers (30)
|
lea 4(a1),a1 ; point to keyboard registers (30)
|
move.l #$3C060502,(a1) ; core=2,level sensitive,enabled,irq6,inta
|
move.l #$3C060502,(a1) ; core=2,level sensitive,enabled,irq6,inta
|
lea 4(a1),a1 ; point to nmi button register (31)
|
lea 4(a1),a1 ; point to nmi button register (31)
|
move.l #$00070302,(a1) ; initialize, core=2,edge sensitive,enabled,irq7,vpa
|
move.l #$00070302,(a1) ; initialize, core=2,edge sensitive,enabled,irq7,vpa
|
lea $80+4*16(a0),a1 ; a1 points to ACIA register
|
lea $80+4*16(a0),a1 ; a1 points to ACIA register
|
move.l #$3D030502,(a1) ; core=2,level sensitive,enabled,irq3,inta
|
move.l #$3D030502,(a1) ; core=2,level sensitive,enabled,irq3,inta
|
lea $80+4*4(a0),a1 ; a1 points to io_bitmap irq
|
lea $80+4*4(a0),a1 ; a1 points to io_bitmap irq
|
move.l #$3B060702,(a1) ; core=2,edge sensitive,enabled,irq6,inta
|
move.l #$3B060702,(a1) ; core=2,edge sensitive,enabled,irq6,inta
|
rts
|
rts
|
|
|
;==============================================================================
|
;==============================================================================
|
; Keyboard stuff
|
; Keyboard stuff
|
;
|
;
|
; KeyState2_
|
; KeyState2_
|
; 876543210
|
; 876543210
|
; ||||||||+ = shift
|
; ||||||||+ = shift
|
; |||||||+- = alt
|
; |||||||+- = alt
|
; ||||||+-- = control
|
; ||||||+-- = control
|
; |||||+--- = numlock
|
; |||||+--- = numlock
|
; ||||+---- = capslock
|
; ||||+---- = capslock
|
; |||+----- = scrolllock
|
; |||+----- = scrolllock
|
; ||+------ =
|
; ||+------ =
|
; |+------- =
|
; |+------- =
|
; +-------- = extended
|
; +-------- = extended
|
;
|
;
|
;==============================================================================
|
;==============================================================================
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Get ID - get the keyboards identifier code.
|
; Get ID - get the keyboards identifier code.
|
;
|
;
|
; Parameters: none
|
; Parameters: none
|
; Returns: d = $AB83, $00 on fail
|
; Returns: d = $AB83, $00 on fail
|
; Modifies: d, KeybdID updated
|
; Modifies: d, KeybdID updated
|
; Stack Space: 2 words
|
; Stack Space: 2 words
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
KeybdGetID:
|
KeybdGetID:
|
move.w #$F2,d1
|
move.w #$F2,d1
|
bsr KeybdSendByte
|
bsr KeybdSendByte
|
bsr KeybdWaitTx
|
bsr KeybdWaitTx
|
bsr KeybdRecvByte
|
bsr KeybdRecvByte
|
btst #7,d1
|
btst #7,d1
|
bne kgnotKbd
|
bne kgnotKbd
|
cmpi.b #$AB,d1
|
cmpi.b #$AB,d1
|
bne kgnotKbd
|
bne kgnotKbd
|
bsr KeybdRecvByte
|
bsr KeybdRecvByte
|
btst #7,d1
|
btst #7,d1
|
bne kgnotKbd
|
bne kgnotKbd
|
cmpi.b #$83,d1
|
cmpi.b #$83,d1
|
bne kgnotKbd
|
bne kgnotKbd
|
move.l #$AB83,d1
|
move.l #$AB83,d1
|
kgid1:
|
kgid1:
|
move.w d1,KeybdID
|
move.w d1,KeybdID
|
rts
|
rts
|
kgnotKbd:
|
kgnotKbd:
|
moveq #0,d1
|
moveq #0,d1
|
bra kgid1
|
bra kgid1
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Set the LEDs on the keyboard.
|
; Set the LEDs on the keyboard.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; d1.b = LED state
|
; d1.b = LED state
|
; Modifies:
|
; Modifies:
|
; none
|
; none
|
; Returns:
|
; Returns:
|
; none
|
; none
|
; Stack Space:
|
; Stack Space:
|
; 1 long word
|
; 1 long word
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
KeybdSetLED:
|
KeybdSetLED:
|
move.l d1,-(a7)
|
move.l d1,-(a7)
|
move.b #$ED,d1
|
move.b #$ED,d1
|
bsr KeybdSendByte
|
bsr KeybdSendByte
|
bsr KeybdWaitTx
|
bsr KeybdWaitTx
|
bsr KeybdRecvByte
|
bsr KeybdRecvByte
|
tst.b d1
|
tst.b d1
|
bmi .0001
|
bmi .0001
|
cmpi.b #$FA,d1
|
cmpi.b #$FA,d1
|
move.l (a7),d1
|
move.l (a7),d1
|
bsr KeybdSendByte
|
bsr KeybdSendByte
|
bsr KeybdWaitTx
|
bsr KeybdWaitTx
|
bsr KeybdRecvByte
|
bsr KeybdRecvByte
|
.0001:
|
.0001:
|
move.l (a7)+,d1
|
move.l (a7)+,d1
|
rts
|
rts
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Initialize the keyboard.
|
; Initialize the keyboard.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; none
|
; none
|
; Modifies:
|
; Modifies:
|
; none
|
; none
|
; Returns:
|
; Returns:
|
; none
|
; none
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
_KeybdInit:
|
_KeybdInit:
|
KeybdInit:
|
KeybdInit:
|
; movem.l d0/d1/d3/a1,-(a7)
|
; movem.l d0/d1/d3/a1,-(a7)
|
clr.b _KeyState1 ; records key up/down state
|
clr.b _KeyState1 ; records key up/down state
|
clr.b _KeyState2 ; records shift,ctrl,alt state
|
clr.b _KeyState2 ; records shift,ctrl,alt state
|
rts
|
rts
|
|
|
bsr Wait300ms
|
bsr Wait300ms
|
bsr _KeybdGetStatus ; wait for response from keyboard
|
bsr _KeybdGetStatus ; wait for response from keyboard
|
tst.b d1
|
tst.b d1
|
bpl .0001 ; is input buffer full ? no, branch
|
bpl .0001 ; is input buffer full ? no, branch
|
bsr _KeybdGetScancode
|
bsr _KeybdGetScancode
|
cmpi.b #$AA,d1 ; keyboard Okay
|
cmpi.b #$AA,d1 ; keyboard Okay
|
beq kbdi0005
|
beq kbdi0005
|
.0001:
|
.0001:
|
moveq #10,d3
|
moveq #10,d3
|
kbdi0002:
|
kbdi0002:
|
bsr Wait10ms
|
bsr Wait10ms
|
clr.b KEYBD+1 ; clear receive register (write $00 to status reg)
|
clr.b KEYBD+1 ; clear receive register (write $00 to status reg)
|
moveq #-1,d1 ; send reset code to keyboard
|
moveq #-1,d1 ; send reset code to keyboard
|
move.b d1,KEYBD+1 ; write $FF to status reg to clear TX state
|
move.b d1,KEYBD+1 ; write $FF to status reg to clear TX state
|
bsr KeybdSendByte ; now write ($FF) to transmit register for reset
|
bsr KeybdSendByte ; now write ($FF) to transmit register for reset
|
bsr KeybdWaitTx ; wait until no longer busy
|
bsr KeybdWaitTx ; wait until no longer busy
|
tst.l d1
|
tst.l d1
|
bmi kbdiXmitBusy
|
bmi kbdiXmitBusy
|
bsr KeybdRecvByte ; look for an ACK ($FA)
|
bsr KeybdRecvByte ; look for an ACK ($FA)
|
cmpi.b #$FA,d1
|
cmpi.b #$FA,d1
|
bne .0001
|
bne .0001
|
bsr KeybdRecvByte ; look for BAT completion code ($AA)
|
bsr KeybdRecvByte ; look for BAT completion code ($AA)
|
.0001:
|
.0001:
|
cmpi.b #$FC,d1 ; reset error ?
|
cmpi.b #$FC,d1 ; reset error ?
|
beq kbdiTryAgain
|
beq kbdiTryAgain
|
cmpi.b #$AA,d1 ; reset complete okay ?
|
cmpi.b #$AA,d1 ; reset complete okay ?
|
bne kbdiTryAgain
|
bne kbdiTryAgain
|
|
|
; After a reset, scan code set #2 should be active
|
; After a reset, scan code set #2 should be active
|
.config:
|
.config:
|
move.w #$F0,d1 ; send scan code select
|
move.w #$F0,d1 ; send scan code select
|
move.b d1,leds
|
move.b d1,leds
|
bsr KeybdSendByte
|
bsr KeybdSendByte
|
bsr KeybdWaitTx
|
bsr KeybdWaitTx
|
tst.l d1
|
tst.l d1
|
bmi kbdiXmitBusy
|
bmi kbdiXmitBusy
|
bsr KeybdRecvByte ; wait for response from keyboard
|
bsr KeybdRecvByte ; wait for response from keyboard
|
tst.w d1
|
tst.w d1
|
bmi kbdiTryAgain
|
bmi kbdiTryAgain
|
cmpi.b #$FA,d1 ; ACK
|
cmpi.b #$FA,d1 ; ACK
|
beq kbdi0004
|
beq kbdi0004
|
kbdiTryAgain:
|
kbdiTryAgain:
|
dbra d3,kbdi0002
|
dbra d3,kbdi0002
|
.keybdErr:
|
.keybdErr:
|
lea msgBadKeybd,a1
|
lea msgBadKeybd,a1
|
bsr DisplayStringCRLF
|
bsr DisplayStringCRLF
|
bra ledxit
|
bra ledxit
|
kbdi0004:
|
kbdi0004:
|
moveq #2,d1 ; select scan code set #2
|
moveq #2,d1 ; select scan code set #2
|
bsr KeybdSendByte
|
bsr KeybdSendByte
|
bsr KeybdWaitTx
|
bsr KeybdWaitTx
|
tst.l d1
|
tst.l d1
|
bmi kbdiXmitBusy
|
bmi kbdiXmitBusy
|
bsr KeybdRecvByte ; wait for response from keyboard
|
bsr KeybdRecvByte ; wait for response from keyboard
|
tst.w d1
|
tst.w d1
|
bmi kbdiTryAgain
|
bmi kbdiTryAgain
|
cmpi.b #$FA,d1
|
cmpi.b #$FA,d1
|
bne kbdiTryAgain
|
bne kbdiTryAgain
|
kbdi0005:
|
kbdi0005:
|
bsr KeybdGetID
|
bsr KeybdGetID
|
ledxit:
|
ledxit:
|
moveq #$07,d1
|
moveq #$07,d1
|
bsr KeybdSetLED
|
bsr KeybdSetLED
|
bsr Wait300ms
|
bsr Wait300ms
|
moveq #$00,d1
|
moveq #$00,d1
|
bsr KeybdSetLED
|
bsr KeybdSetLED
|
movem.l (a7)+,d0/d1/d3/a1
|
movem.l (a7)+,d0/d1/d3/a1
|
rts
|
rts
|
kbdiXmitBusy:
|
kbdiXmitBusy:
|
lea msgXmitBusy,a1
|
lea msgXmitBusy,a1
|
bsr DisplayStringCRLF
|
bsr DisplayStringCRLF
|
movem.l (a7)+,d0/d1/d3/a1
|
movem.l (a7)+,d0/d1/d3/a1
|
rts
|
rts
|
|
|
msgBadKeybd:
|
msgBadKeybd:
|
dc.b "Keyboard error",0
|
dc.b "Keyboard error",0
|
msgXmitBusy:
|
msgXmitBusy:
|
dc.b "Keyboard transmitter stuck",0
|
dc.b "Keyboard transmitter stuck",0
|
|
|
even
|
even
|
_KeybdGetStatus:
|
_KeybdGetStatus:
|
moveq #0,d1
|
moveq #0,d1
|
move.b KEYBD+1,d1
|
move.b KEYBD+1,d1
|
rts
|
rts
|
|
|
; Get the scancode from the keyboard port
|
; Get the scancode from the keyboard port
|
|
|
_KeybdGetScancode:
|
_KeybdGetScancode:
|
moveq #0,d1
|
moveq #0,d1
|
move.b KEYBD,d1 ; get the scan code
|
move.b KEYBD,d1 ; get the scan code
|
move.b #0,KEYBD+1 ; clear receive register
|
move.b #0,KEYBD+1 ; clear receive register
|
rts
|
rts
|
|
|
; Recieve a byte from the keyboard, used after a command is sent to the
|
; Recieve a byte from the keyboard, used after a command is sent to the
|
; keyboard in order to wait for a response.
|
; keyboard in order to wait for a response.
|
;
|
;
|
KeybdRecvByte:
|
KeybdRecvByte:
|
move.l d3,-(a7)
|
move.l d3,-(a7)
|
move.w #100,d3 ; wait up to 1s
|
move.w #100,d3 ; wait up to 1s
|
.0003:
|
.0003:
|
bsr _KeybdGetStatus ; wait for response from keyboard
|
bsr _KeybdGetStatus ; wait for response from keyboard
|
tst.b d1
|
tst.b d1
|
bmi .0004 ; is input buffer full ? yes, branch
|
bmi .0004 ; is input buffer full ? yes, branch
|
bsr Wait10ms ; wait a bit
|
bsr Wait10ms ; wait a bit
|
dbra d3,.0003 ; go back and try again
|
dbra d3,.0003 ; go back and try again
|
move.l (a7)+,d3
|
move.l (a7)+,d3
|
moveq #-1,d1 ; return -1
|
moveq #-1,d1 ; return -1
|
rts
|
rts
|
.0004:
|
.0004:
|
bsr _KeybdGetScancode
|
bsr _KeybdGetScancode
|
move.l (a7)+,d3
|
move.l (a7)+,d3
|
rts
|
rts
|
|
|
|
|
; Wait until the keyboard transmit is complete
|
; Wait until the keyboard transmit is complete
|
; Returns -1 if timedout, 0 if transmit completed
|
; Returns -1 if timedout, 0 if transmit completed
|
;
|
;
|
KeybdWaitTx:
|
KeybdWaitTx:
|
movem.l d2/d3,-(a7)
|
movem.l d2/d3,-(a7)
|
moveq #100,d3 ; wait a max of 1s
|
moveq #100,d3 ; wait a max of 1s
|
.0001:
|
.0001:
|
bsr _KeybdGetStatus
|
bsr _KeybdGetStatus
|
btst #6,d1 ; check for transmit complete bit
|
btst #6,d1 ; check for transmit complete bit
|
bne .0002 ; branch if bit set
|
bne .0002 ; branch if bit set
|
bsr Wait10ms ; delay a little bit
|
bsr Wait10ms ; delay a little bit
|
dbra d3,.0001 ; go back and try again
|
dbra d3,.0001 ; go back and try again
|
movem.l (a7)+,d2/d3
|
movem.l (a7)+,d2/d3
|
moveq #-1,d1 ; return -1
|
moveq #-1,d1 ; return -1
|
rts
|
rts
|
.0002:
|
.0002:
|
movem.l (a7)+,d2/d3
|
movem.l (a7)+,d2/d3
|
moveq #0,d1 ; return 0
|
moveq #0,d1 ; return 0
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; d1.b 0=echo off, non-zero = echo on
|
; d1.b 0=echo off, non-zero = echo on
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SetKeyboardEcho:
|
SetKeyboardEcho:
|
move.b d1,KeybdEcho
|
move.b d1,KeybdEcho
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Get key pending status into d1.b
|
; Get key pending status into d1.b
|
;
|
;
|
; Returns:
|
; Returns:
|
; d1.b = 1 if a key is available, otherwise zero.
|
; d1.b = 1 if a key is available, otherwise zero.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
CheckForKey:
|
CheckForKey:
|
moveq.l #0,d1 ; clear high order bits
|
moveq.l #0,d1 ; clear high order bits
|
; move.b KEYBD+1,d1 ; get keyboard port status
|
; move.b KEYBD+1,d1 ; get keyboard port status
|
; smi.b d1 ; set true/false
|
; smi.b d1 ; set true/false
|
; andi.b #1,d1 ; return true (1) if key available, 0 otherwise
|
; andi.b #1,d1 ; return true (1) if key available, 0 otherwise
|
tst.b _KeybdCnt
|
tst.b _KeybdCnt
|
sne.b d1
|
sne.b d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; GetKey
|
; GetKey
|
; Get a character from the keyboard.
|
; Get a character from the keyboard.
|
;
|
;
|
; Modifies:
|
; Modifies:
|
; d1
|
; d1
|
; Returns:
|
; Returns:
|
; d1 = -1 if no key available or not in focus, otherwise key
|
; d1 = -1 if no key available or not in focus, otherwise key
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
GetKey:
|
GetKey:
|
move.l d0,-(a7) ; push d0
|
move.l d0,-(a7) ; push d0
|
move.b IOFocus,d1 ; Check if the core has the IO focus
|
move.b IOFocus,d1 ; Check if the core has the IO focus
|
movec.l coreno,d0
|
movec.l coreno,d0
|
cmp.b d0,d1
|
cmp.b d0,d1
|
bne.s .0004 ; go return no key available, if not in focus
|
bne.s .0004 ; go return no key available, if not in focus
|
bsr KeybdGetCharNoWait ; get a character
|
bsr KeybdGetCharNoWait ; get a character
|
tst.l d1 ; was a key available?
|
tst.l d1 ; was a key available?
|
bmi.s .0004
|
bmi.s .0004
|
tst.b KeybdEcho ; is keyboard echo on ?
|
tst.b KeybdEcho ; is keyboard echo on ?
|
beq.s .0003 ; no echo, just return the key
|
beq.s .0003 ; no echo, just return the key
|
cmpi.b #CR,d1 ; convert CR keystroke into CRLF
|
cmpi.b #CR,d1 ; convert CR keystroke into CRLF
|
bne.s .0005
|
bne.s .0005
|
bsr CRLF
|
bsr CRLF
|
bra.s .0003
|
bra.s .0003
|
.0005:
|
.0005:
|
bsr DisplayChar
|
bsr DisplayChar
|
.0003:
|
.0003:
|
move.l (a7)+,d0 ; pop d0
|
move.l (a7)+,d0 ; pop d0
|
rts ; return key
|
rts ; return key
|
; Return -1 indicating no char was available
|
; Return -1 indicating no char was available
|
.0004:
|
.0004:
|
move.l (a7)+,d0 ; pop d0
|
move.l (a7)+,d0 ; pop d0
|
moveq #-1,d1 ; return no key available
|
moveq #-1,d1 ; return no key available
|
rts
|
rts
|
|
|
CheckForCtrlC:
|
CheckForCtrlC:
|
bsr KeybdGetCharNoWait
|
bsr KeybdGetCharNoWait
|
cmpi.b #CTRLC,d1
|
cmpi.b #CTRLC,d1
|
beq Monitor
|
beq Monitor
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
KeybdGetCharNoWait:
|
KeybdGetCharNoWait:
|
clr.b KeybdWaitFlag
|
clr.b KeybdWaitFlag
|
bra KeybdGetChar
|
bra KeybdGetChar
|
|
|
KeybdGetCharWait:
|
KeybdGetCharWait:
|
move.b #-1,KeybdWaitFlag
|
move.b #-1,KeybdWaitFlag
|
|
|
KeybdGetChar:
|
KeybdGetChar:
|
movem.l d0/d2/d3/a0,-(a7)
|
movem.l d0/d2/d3/a0,-(a7)
|
.0003:
|
.0003:
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #KEYBD_SEMA,d1
|
moveq #KEYBD_SEMA,d1
|
bsr LockSemaphore
|
bsr LockSemaphore
|
move.b _KeybdCnt,d2 ; get count of buffered scan codes
|
move.b _KeybdCnt,d2 ; get count of buffered scan codes
|
beq.s .0015 ;
|
beq.s .0015 ;
|
move.b _KeybdHead,d2 ; d2 = buffer head
|
move.b _KeybdHead,d2 ; d2 = buffer head
|
ext.w d2
|
ext.w d2
|
lea _KeybdBuf,a0 ; a0 = pointer to keyboard buffer
|
lea _KeybdBuf,a0 ; a0 = pointer to keyboard buffer
|
clr.l d1
|
clr.l d1
|
move.b (a0,d2.w),d1 ; d1 = scan code from buffer
|
move.b (a0,d2.w),d1 ; d1 = scan code from buffer
|
addi.b #1,d2 ; increment keyboard head index
|
addi.b #1,d2 ; increment keyboard head index
|
andi.b #31,d2 ; and wrap around at buffer size
|
andi.b #31,d2 ; and wrap around at buffer size
|
move.b d2,_KeybdHead
|
move.b d2,_KeybdHead
|
subi.b #1,_KeybdCnt ; decrement count of scan codes in buffer
|
subi.b #1,_KeybdCnt ; decrement count of scan codes in buffer
|
exg d1,d2 ; save scancode value in d2
|
exg d1,d2 ; save scancode value in d2
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #KEYBD_SEMA,d1
|
moveq #KEYBD_SEMA,d1
|
bsr UnlockSemaphore
|
bsr UnlockSemaphore
|
exg d2,d1 ; restore scancode value
|
exg d2,d1 ; restore scancode value
|
bra .0001 ; go process scan code
|
bra .0001 ; go process scan code
|
.0014:
|
.0014:
|
bsr _KeybdGetStatus ; check keyboard status for key available
|
bsr _KeybdGetStatus ; check keyboard status for key available
|
bmi .0006 ; yes, go process
|
bmi .0006 ; yes, go process
|
.0015:
|
.0015:
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #KEYBD_SEMA,d1
|
moveq #KEYBD_SEMA,d1
|
bsr UnlockSemaphore
|
bsr UnlockSemaphore
|
tst.b KeybdWaitFlag ; are we willing to wait for a key ?
|
tst.b KeybdWaitFlag ; are we willing to wait for a key ?
|
bmi .0003 ; yes, branch back
|
bmi .0003 ; yes, branch back
|
movem.l (a7)+,d0/d2/d3/a0
|
movem.l (a7)+,d0/d2/d3/a0
|
moveq #-1,d1 ; flag no char available
|
moveq #-1,d1 ; flag no char available
|
rts
|
rts
|
.0006:
|
.0006:
|
bsr _KeybdGetScancode
|
bsr _KeybdGetScancode
|
.0001:
|
.0001:
|
move.w #1,leds
|
move.w #1,leds
|
cmp.b #SC_KEYUP,d1
|
cmp.b #SC_KEYUP,d1
|
beq .doKeyup
|
beq .doKeyup
|
cmp.b #SC_EXTEND,d1
|
cmp.b #SC_EXTEND,d1
|
beq .doExtend
|
beq .doExtend
|
cmp.b #SC_CTRL,d1
|
cmp.b #SC_CTRL,d1
|
beq .doCtrl
|
beq .doCtrl
|
cmp.b #SC_LSHIFT,d1
|
cmp.b #SC_LSHIFT,d1
|
beq .doShift
|
beq .doShift
|
cmp.b #SC_RSHIFT,d1
|
cmp.b #SC_RSHIFT,d1
|
beq .doShift
|
beq .doShift
|
cmp.b #SC_NUMLOCK,d1
|
cmp.b #SC_NUMLOCK,d1
|
beq .doNumLock
|
beq .doNumLock
|
cmp.b #SC_CAPSLOCK,d1
|
cmp.b #SC_CAPSLOCK,d1
|
beq .doCapsLock
|
beq .doCapsLock
|
cmp.b #SC_SCROLLLOCK,d1
|
cmp.b #SC_SCROLLLOCK,d1
|
beq .doScrollLock
|
beq .doScrollLock
|
cmp.b #SC_ALT,d1
|
cmp.b #SC_ALT,d1
|
beq .doAlt
|
beq .doAlt
|
move.b _KeyState1,d2 ; check key up/down
|
move.b _KeyState1,d2 ; check key up/down
|
move.b #0,_KeyState1 ; clear keyup status
|
move.b #0,_KeyState1 ; clear keyup status
|
tst.b d2
|
tst.b d2
|
bne .0003 ; ignore key up
|
bne .0003 ; ignore key up
|
cmp.b #SC_TAB,d1
|
cmp.b #SC_TAB,d1
|
beq .doTab
|
beq .doTab
|
.0013:
|
.0013:
|
move.b _KeyState2,d2
|
move.b _KeyState2,d2
|
bpl .0010 ; is it extended code ?
|
bpl .0010 ; is it extended code ?
|
and.b #$7F,d2 ; clear extended bit
|
and.b #$7F,d2 ; clear extended bit
|
move.b d2,_KeyState2
|
move.b d2,_KeyState2
|
move.b #0,_KeyState1 ; clear keyup
|
move.b #0,_KeyState1 ; clear keyup
|
lea _keybdExtendedCodes,a0
|
lea _keybdExtendedCodes,a0
|
move.b (a0,d1.w),d1
|
move.b (a0,d1.w),d1
|
bra .0008
|
bra .0008
|
.0010:
|
.0010:
|
btst #2,d2 ; is it CTRL code ?
|
btst #2,d2 ; is it CTRL code ?
|
beq .0009
|
beq .0009
|
and.w #$7F,d1
|
and.w #$7F,d1
|
lea _keybdControlCodes,a0
|
lea _keybdControlCodes,a0
|
move.b (a0,d1.w),d1
|
move.b (a0,d1.w),d1
|
bra .0008
|
bra .0008
|
.0009:
|
.0009:
|
btst #0,d2 ; is it shift down ?
|
btst #0,d2 ; is it shift down ?
|
beq .0007
|
beq .0007
|
lea _shiftedScanCodes,a0
|
lea _shiftedScanCodes,a0
|
move.b (a0,d1.w),d1
|
move.b (a0,d1.w),d1
|
bra .0008
|
bra .0008
|
.0007:
|
.0007:
|
lea _unshiftedScanCodes,a0
|
lea _unshiftedScanCodes,a0
|
move.b (a0,d1.w),d1
|
move.b (a0,d1.w),d1
|
move.w #$0202,leds
|
move.w #$0202,leds
|
.0008:
|
.0008:
|
move.w #$0303,leds
|
move.w #$0303,leds
|
movem.l (a7)+,d0/d2/d3/a0
|
movem.l (a7)+,d0/d2/d3/a0
|
rts
|
rts
|
.doKeyup:
|
.doKeyup:
|
move.b #-1,_KeyState1
|
move.b #-1,_KeyState1
|
bra .0003
|
bra .0003
|
.doExtend:
|
.doExtend:
|
or.b #$80,_KeyState2
|
or.b #$80,_KeyState2
|
bra .0003
|
bra .0003
|
.doCtrl:
|
.doCtrl:
|
move.b _KeyState1,d1
|
move.b _KeyState1,d1
|
clr.b _KeyState1
|
clr.b _KeyState1
|
tst.b d1
|
tst.b d1
|
bpl.s .0004
|
bpl.s .0004
|
bclr #2,_KeyState2
|
bclr #2,_KeyState2
|
bra .0003
|
bra .0003
|
.0004:
|
.0004:
|
bset #2,_KeyState2
|
bset #2,_KeyState2
|
bra .0003
|
bra .0003
|
.doAlt:
|
.doAlt:
|
move.b _KeyState1,d1
|
move.b _KeyState1,d1
|
clr.b _KeyState1
|
clr.b _KeyState1
|
tst.b d1
|
tst.b d1
|
bpl .0011
|
bpl .0011
|
bclr #1,_KeyState2
|
bclr #1,_KeyState2
|
bra .0003
|
bra .0003
|
.0011:
|
.0011:
|
bset #1,_KeyState2
|
bset #1,_KeyState2
|
bra .0003
|
bra .0003
|
.doTab:
|
.doTab:
|
move.l d1,-(a7)
|
move.l d1,-(a7)
|
move.b _KeyState2,d1
|
move.b _KeyState2,d1
|
btst #1,d1 ; is ALT down ?
|
btst #1,d1 ; is ALT down ?
|
beq .0012
|
beq .0012
|
; inc _iof_switch
|
; inc _iof_switch
|
move.l (a7)+,d1
|
move.l (a7)+,d1
|
bra .0003
|
bra .0003
|
.0012:
|
.0012:
|
move.l (a7)+,d1
|
move.l (a7)+,d1
|
bra .0013
|
bra .0013
|
.doShift:
|
.doShift:
|
move.b _KeyState1,d1
|
move.b _KeyState1,d1
|
clr.b _KeyState1
|
clr.b _KeyState1
|
tst.b d1
|
tst.b d1
|
bpl.s .0005
|
bpl.s .0005
|
bclr #0,_KeyState2
|
bclr #0,_KeyState2
|
bra .0003
|
bra .0003
|
.0005:
|
.0005:
|
bset #0,_KeyState2
|
bset #0,_KeyState2
|
bra .0003
|
bra .0003
|
.doNumLock:
|
.doNumLock:
|
bchg #4,_KeyState2
|
bchg #4,_KeyState2
|
bsr KeybdSetLEDStatus
|
bsr KeybdSetLEDStatus
|
bra .0003
|
bra .0003
|
.doCapsLock:
|
.doCapsLock:
|
bchg #5,_KeyState2
|
bchg #5,_KeyState2
|
bsr KeybdSetLEDStatus
|
bsr KeybdSetLEDStatus
|
bra .0003
|
bra .0003
|
.doScrollLock:
|
.doScrollLock:
|
bchg #6,_KeyState2
|
bchg #6,_KeyState2
|
bsr KeybdSetLEDStatus
|
bsr KeybdSetLEDStatus
|
bra .0003
|
bra .0003
|
|
|
KeybdSetLEDStatus:
|
KeybdSetLEDStatus:
|
movem.l d2/d3,-(a7)
|
movem.l d2/d3,-(a7)
|
clr.b KeybdLEDs
|
clr.b KeybdLEDs
|
btst #4,_KeyState2
|
btst #4,_KeyState2
|
beq.s .0002
|
beq.s .0002
|
move.b #2,KeybdLEDs
|
move.b #2,KeybdLEDs
|
.0002:
|
.0002:
|
btst #5,_KeyState2
|
btst #5,_KeyState2
|
beq.s .0003
|
beq.s .0003
|
bset #2,KeybdLEDs
|
bset #2,KeybdLEDs
|
.0003:
|
.0003:
|
btst #6,_KeyState2
|
btst #6,_KeyState2
|
beq.s .0004
|
beq.s .0004
|
bset #0,KeybdLEDs
|
bset #0,KeybdLEDs
|
.0004:
|
.0004:
|
move.b KeybdLEDs,d1
|
move.b KeybdLEDs,d1
|
bsr KeybdSetLED
|
bsr KeybdSetLED
|
movem.l (a7)+,d2/d3
|
movem.l (a7)+,d2/d3
|
rts
|
rts
|
|
|
KeybdSendByte:
|
KeybdSendByte:
|
move.b d1,KEYBD
|
move.b d1,KEYBD
|
rts
|
rts
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Wait for 10 ms
|
; Wait for 10 ms
|
;
|
;
|
; Parameters: none
|
; Parameters: none
|
; Returns: none
|
; Returns: none
|
; Modifies: none
|
; Modifies: none
|
; Stack Space: 2 long words
|
; Stack Space: 2 long words
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
Wait10ms:
|
Wait10ms:
|
movem.l d0/d1,-(a7)
|
movem.l d0/d1,-(a7)
|
movec tick,d0
|
movec tick,d0
|
addi.l #400000,d0 ; 400,000 cycles at 40MHz
|
addi.l #400000,d0 ; 400,000 cycles at 40MHz
|
.0001:
|
.0001:
|
movec tick,d1
|
movec tick,d1
|
cmp.l d1,d0
|
cmp.l d1,d0
|
bhi .0001
|
bhi .0001
|
movem.l (a7)+,d0/d1
|
movem.l (a7)+,d0/d1
|
rts
|
rts
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Wait for 300 ms
|
; Wait for 300 ms
|
;
|
;
|
; Parameters: none
|
; Parameters: none
|
; Returns: none
|
; Returns: none
|
; Modifies: none
|
; Modifies: none
|
; Stack Space: 2 long words
|
; Stack Space: 2 long words
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
Wait300ms:
|
Wait300ms:
|
movem.l d0/d1,-(a7)
|
movem.l d0/d1,-(a7)
|
movec tick,d0
|
movec tick,d0
|
addi.l #12000000,d0 ; 12,000,000 cycles at 40MHz
|
addi.l #12000000,d0 ; 12,000,000 cycles at 40MHz
|
.0001:
|
.0001:
|
movec tick,d1
|
movec tick,d1
|
cmp.l d1,d0
|
cmp.l d1,d0
|
bhi .0001
|
bhi .0001
|
movem.l (a7)+,d0/d1
|
movem.l (a7)+,d0/d1
|
rts
|
rts
|
|
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
; Keyboard IRQ routine.
|
; Keyboard IRQ routine.
|
;
|
;
|
; Returns:
|
; Returns:
|
; d1 = -1 if keyboard routine handled interrupt, otherwise positive.
|
; d1 = -1 if keyboard routine handled interrupt, otherwise positive.
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
|
|
KeybdIRQ:
|
KeybdIRQ:
|
move.w #$2600,sr ; disable lower interrupts
|
move.w #$2600,sr ; disable lower interrupts
|
movem.l d0/d1/a0,-(a7)
|
movem.l d0/d1/a0,-(a7)
|
bsr _KeybdGetStatus ; check if keyboard
|
bsr _KeybdGetStatus ; check if keyboard
|
tst.b d1
|
tst.b d1
|
bpl .0001 ; branch if not keyboard
|
bpl .0001 ; branch if not keyboard
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #KEYBD_SEMA,d1
|
moveq #KEYBD_SEMA,d1
|
bsr LockSemaphore
|
bsr LockSemaphore
|
btst #1,_KeyState2 ; Is Alt down?
|
btst #1,_KeyState2 ; Is Alt down?
|
beq.s .0003
|
beq.s .0003
|
move.b KEYBD,d0 ; get scan code
|
move.b KEYBD,d0 ; get scan code
|
cmpi.b #SC_TAB,d0 ; is Alt-Tab?
|
cmpi.b #SC_TAB,d0 ; is Alt-Tab?
|
bne.s .0003
|
bne.s .0003
|
bsr _KeybdGetScancode ; grab the scan code (clears interrupt)
|
bsr _KeybdGetScancode ; grab the scan code (clears interrupt)
|
bsr rotate_iofocus
|
bsr rotate_iofocus
|
clr.b _KeybdHead ; clear keyboard buffer
|
clr.b _KeybdHead ; clear keyboard buffer
|
clr.b _KeybdTail
|
clr.b _KeybdTail
|
clr.b _KeybdCnt
|
clr.b _KeybdCnt
|
bra .0002 ; do not store Alt-Tab
|
bra .0002 ; do not store Alt-Tab
|
.0003:
|
.0003:
|
; Insert keyboard scan code into raw keyboard buffer
|
; Insert keyboard scan code into raw keyboard buffer
|
bsr _KeybdGetScancode ; grab the scan code (clears interrupt)
|
bsr _KeybdGetScancode ; grab the scan code (clears interrupt)
|
cmpi.b #32,_KeybdCnt ; see if keyboard buffer full
|
cmpi.b #32,_KeybdCnt ; see if keyboard buffer full
|
bhs.s .0002
|
bhs.s .0002
|
move.b _KeybdTail,d0 ; keyboard buffer not full, add to tail
|
move.b _KeybdTail,d0 ; keyboard buffer not full, add to tail
|
ext.w d0
|
ext.w d0
|
lea _KeybdBuf,a0 ; a0 = pointer to buffer
|
lea _KeybdBuf,a0 ; a0 = pointer to buffer
|
move.b d1,(a0,d0.w) ; put scancode in buffer
|
move.b d1,(a0,d0.w) ; put scancode in buffer
|
addi.b #1,d0 ; increment tail index
|
addi.b #1,d0 ; increment tail index
|
andi.b #31,d0 ; wrap at buffer limit
|
andi.b #31,d0 ; wrap at buffer limit
|
move.b d0,_KeybdTail ; update tail index
|
move.b d0,_KeybdTail ; update tail index
|
addi.b #1,_KeybdCnt ; increment buffer count
|
addi.b #1,_KeybdCnt ; increment buffer count
|
.0002:
|
.0002:
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #KEYBD_SEMA,d1
|
moveq #KEYBD_SEMA,d1
|
bsr UnlockSemaphore
|
bsr UnlockSemaphore
|
.0001:
|
.0001:
|
movem.l (a7)+,d0/d1/a0 ; return
|
movem.l (a7)+,d0/d1/a0 ; return
|
rte
|
rte
|
|
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
; PS2 scan codes to ascii conversion tables.
|
; PS2 scan codes to ascii conversion tables.
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
;
|
;
|
_unshiftedScanCodes:
|
_unshiftedScanCodes:
|
dc.b $2e,$a9,$2e,$a5,$a3,$a1,$a2,$ac
|
dc.b $2e,$a9,$2e,$a5,$a3,$a1,$a2,$ac
|
dc.b $2e,$aa,$a8,$a6,$a4,$09,$60,$2e
|
dc.b $2e,$aa,$a8,$a6,$a4,$09,$60,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$71,$31,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$71,$31,$2e
|
dc.b $2e,$2e,$7a,$73,$61,$77,$32,$2e
|
dc.b $2e,$2e,$7a,$73,$61,$77,$32,$2e
|
dc.b $2e,$63,$78,$64,$65,$34,$33,$2e
|
dc.b $2e,$63,$78,$64,$65,$34,$33,$2e
|
dc.b $2e,$20,$76,$66,$74,$72,$35,$2e
|
dc.b $2e,$20,$76,$66,$74,$72,$35,$2e
|
dc.b $2e,$6e,$62,$68,$67,$79,$36,$2e
|
dc.b $2e,$6e,$62,$68,$67,$79,$36,$2e
|
dc.b $2e,$2e,$6d,$6a,$75,$37,$38,$2e
|
dc.b $2e,$2e,$6d,$6a,$75,$37,$38,$2e
|
dc.b $2e,$2c,$6b,$69,$6f,$30,$39,$2e
|
dc.b $2e,$2c,$6b,$69,$6f,$30,$39,$2e
|
dc.b $2e,$2e,$2f,$6c,$3b,$70,$2d,$2e
|
dc.b $2e,$2e,$2f,$6c,$3b,$70,$2d,$2e
|
dc.b $2e,$2e,$27,$2e,$5b,$3d,$2e,$2e
|
dc.b $2e,$2e,$27,$2e,$5b,$3d,$2e,$2e
|
dc.b $ad,$2e,$0d,$5d,$2e,$5c,$2e,$2e
|
dc.b $ad,$2e,$0d,$5d,$2e,$5c,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
|
dc.b $2e,$95,$2e,$93,$94,$2e,$2e,$2e
|
dc.b $2e,$95,$2e,$93,$94,$2e,$2e,$2e
|
dc.b $98,$7f,$92,$2e,$91,$90,$1b,$af
|
dc.b $98,$7f,$92,$2e,$91,$90,$1b,$af
|
dc.b $ab,$2e,$97,$2e,$2e,$96,$ae,$2e
|
dc.b $ab,$2e,$97,$2e,$2e,$96,$ae,$2e
|
|
|
dc.b $2e,$2e,$2e,$a7,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$a7,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$fa,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$fa,$2e,$2e,$2e,$2e,$2e
|
|
|
_shiftedScanCodes:
|
_shiftedScanCodes:
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$51,$21,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$51,$21,$2e
|
dc.b $2e,$2e,$5a,$53,$41,$57,$40,$2e
|
dc.b $2e,$2e,$5a,$53,$41,$57,$40,$2e
|
dc.b $2e,$43,$58,$44,$45,$24,$23,$2e
|
dc.b $2e,$43,$58,$44,$45,$24,$23,$2e
|
dc.b $2e,$20,$56,$46,$54,$52,$25,$2e
|
dc.b $2e,$20,$56,$46,$54,$52,$25,$2e
|
dc.b $2e,$4e,$42,$48,$47,$59,$5e,$2e
|
dc.b $2e,$4e,$42,$48,$47,$59,$5e,$2e
|
dc.b $2e,$2e,$4d,$4a,$55,$26,$2a,$2e
|
dc.b $2e,$2e,$4d,$4a,$55,$26,$2a,$2e
|
dc.b $2e,$3c,$4b,$49,$4f,$29,$28,$2e
|
dc.b $2e,$3c,$4b,$49,$4f,$29,$28,$2e
|
dc.b $2e,$3e,$3f,$4c,$3a,$50,$5f,$2e
|
dc.b $2e,$3e,$3f,$4c,$3a,$50,$5f,$2e
|
dc.b $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e
|
dc.b $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e
|
dc.b $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e
|
dc.b $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e
|
dc.b $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
|
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
|
|
; control
|
; control
|
_keybdControlCodes:
|
_keybdControlCodes:
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$11,$21,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$11,$21,$2e
|
dc.b $2e,$2e,$1a,$13,$01,$17,$40,$2e
|
dc.b $2e,$2e,$1a,$13,$01,$17,$40,$2e
|
dc.b $2e,$03,$18,$04,$05,$24,$23,$2e
|
dc.b $2e,$03,$18,$04,$05,$24,$23,$2e
|
dc.b $2e,$20,$16,$06,$14,$12,$25,$2e
|
dc.b $2e,$20,$16,$06,$14,$12,$25,$2e
|
dc.b $2e,$0e,$02,$08,$07,$19,$5e,$2e
|
dc.b $2e,$0e,$02,$08,$07,$19,$5e,$2e
|
dc.b $2e,$2e,$0d,$0a,$15,$26,$2a,$2e
|
dc.b $2e,$2e,$0d,$0a,$15,$26,$2a,$2e
|
dc.b $2e,$3c,$0b,$09,$0f,$29,$28,$2e
|
dc.b $2e,$3c,$0b,$09,$0f,$29,$28,$2e
|
dc.b $2e,$3e,$3f,$0c,$3a,$10,$5f,$2e
|
dc.b $2e,$3e,$3f,$0c,$3a,$10,$5f,$2e
|
dc.b $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e
|
dc.b $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e
|
dc.b $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e
|
dc.b $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e
|
dc.b $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
|
|
_keybdExtendedCodes:
|
_keybdExtendedCodes:
|
dc.b $2e,$2e,$2e,$2e,$a3,$a1,$a2,$2e
|
dc.b $2e,$2e,$2e,$2e,$a3,$a1,$a2,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
|
dc.b $2e,$95,$2e,$93,$94,$2e,$2e,$2e
|
dc.b $2e,$95,$2e,$93,$94,$2e,$2e,$2e
|
dc.b $98,$99,$92,$2e,$91,$90,$2e,$2e
|
dc.b $98,$99,$92,$2e,$91,$90,$2e,$2e
|
dc.b $2e,$2e,$97,$2e,$2e,$96,$2e,$2e
|
dc.b $2e,$2e,$97,$2e,$2e,$96,$2e,$2e
|
|
|
;==============================================================================
|
;==============================================================================
|
;==============================================================================
|
;==============================================================================
|
; Monitor
|
; Monitor
|
;==============================================================================
|
;==============================================================================
|
;==============================================================================
|
;==============================================================================
|
|
|
cmdString:
|
cmdString:
|
dc.b '?'+$80 ; ? display help
|
dc.b '?'+$80 ; ? display help
|
dc.b 'L'+$80 ; L load S19 file
|
dc.b 'L'+$80 ; L load S19 file
|
dc.b 'F','B'+$80 ; FB fill with byte
|
dc.b 'F','B'+$80 ; FB fill with byte
|
dc.b 'F','W'+$80 ; FW fill with wyde
|
dc.b 'F','W'+$80 ; FW fill with wyde
|
dc.b 'F','L'+$80 ; FL fill with long wyde
|
dc.b 'F','L'+$80 ; FL fill with long wyde
|
dc.b 'B','A'+$80 ; BA start Tiny Basic
|
dc.b 'B','A'+$80 ; BA start Tiny Basic
|
dc.b 'B','R'+$80 ; BR breakpoint
|
dc.b 'B','R'+$80 ; BR breakpoint
|
dc.b 'D','R'+$80 ; DR dump registers
|
dc.b 'D','R'+$80 ; DR dump registers
|
dc.b 'D'+$80 ; D dump memory
|
dc.b 'D'+$80 ; D dump memory
|
dc.b 'J'+$80 ; J jump to code
|
dc.b 'J'+$80 ; J jump to code
|
dc.b ':'+$80 ; : edit memory
|
dc.b ':'+$80 ; : edit memory
|
dc.b "CL",'S'+$80 ; CLS clear screen
|
dc.b "CL",'S'+$80 ; CLS clear screen
|
dc.b "COR",'E'+$80 ; CORE switch to core
|
dc.b "COR",'E'+$80 ; CORE switch to core
|
dc.b "TRA",'M'+$80 ; TRAM test RAM
|
dc.b "TRA",'M'+$80 ; TRAM test RAM
|
dc.b 'T','R'+$80 ; TR test serial receive
|
dc.b 'T','R'+$80 ; TR test serial receive
|
dc.b 'T'+$80 ; T test CPU
|
dc.b 'T'+$80 ; T test CPU
|
dc.b 'S'+$80 ; S send serial
|
dc.b 'S'+$80 ; S send serial
|
dc.b "RESE",'T'+$80 ; RESET
|
dc.b "RESE",'T'+$80 ; RESET
|
dc.b "CLOC",'K'+$80 ; CLOCK
|
dc.b "CLOC",'K'+$80 ; CLOCK
|
dc.b 'R'+$80 ; R receive serial
|
dc.b 'R'+$80 ; R receive serial
|
|
|
align 2
|
align 2
|
cmdTable:
|
cmdTable:
|
dc.w cmdHelp
|
dc.w cmdHelp
|
dc.w cmdLoadS19
|
dc.w cmdLoadS19
|
dc.w cmdFillB
|
dc.w cmdFillB
|
dc.w cmdFillW
|
dc.w cmdFillW
|
dc.w cmdFillL
|
dc.w cmdFillL
|
dc.w cmdTinyBasic
|
dc.w cmdTinyBasic
|
dc.w cmdBreakpoint
|
dc.w cmdBreakpoint
|
dc.w cmdDumpRegs
|
dc.w cmdDumpRegs
|
dc.w cmdDumpMemory
|
dc.w cmdDumpMemory
|
dc.w cmdJump
|
dc.w cmdJump
|
dc.w cmdEditMemory
|
dc.w cmdEditMemory
|
dc.w cmdClearScreen
|
dc.w cmdClearScreen
|
dc.w cmdCore
|
dc.w cmdCore
|
dc.w cmdTestRAM
|
dc.w cmdTestRAM
|
dc.w cmdTestSerialReceive
|
dc.w cmdTestSerialReceive
|
dc.w cmdTestCPU
|
dc.w cmdTestCPU
|
dc.w cmdSendSerial
|
dc.w cmdSendSerial
|
dc.w cmdReset
|
dc.w cmdReset
|
dc.w cmdClock
|
dc.w cmdClock
|
dc.w cmdReceiveSerial
|
dc.w cmdReceiveSerial
|
dc.w cmdMonitor
|
dc.w cmdMonitor
|
|
|
; Get a word from screen memory and swap byte order
|
; Get a word from screen memory and swap byte order
|
|
|
FromScreen:
|
FromScreen:
|
move.l (a0),d1
|
move.l (a0),d1
|
bsr rbo
|
bsr rbo
|
lea 8(a0),a0 ; increment screen pointer
|
lea 8(a0),a0 ; increment screen pointer
|
rts
|
rts
|
|
|
StartMon:
|
StartMon:
|
clr.w NumSetBreakpoints
|
clr.w NumSetBreakpoints
|
bsr ClearBreakpointList
|
bsr ClearBreakpointList
|
cmdMonitor:
|
cmdMonitor:
|
Monitor:
|
Monitor:
|
; Reset the stack pointer on each entry into the monitor
|
; Reset the stack pointer on each entry into the monitor
|
move.l #$40FFC,sp ; reset core's stack
|
move.l #$40FFC,sp ; reset core's stack
|
move.w #$2200,sr ; enable level 2 and higher interrupts
|
move.w #$2200,sr ; enable level 2 and higher interrupts
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #1,d1
|
moveq #1,d1
|
bsr UnlockSemaphore
|
bsr UnlockSemaphore
|
clr.b KeybdEcho ; turn off keyboard echo
|
clr.b KeybdEcho ; turn off keyboard echo
|
PromptLn:
|
PromptLn:
|
bsr CRLF
|
bsr CRLF
|
move.b #'$',d1
|
move.b #'$',d1
|
bsr DisplayChar
|
bsr DisplayChar
|
|
|
; Get characters until a CR is keyed
|
; Get characters until a CR is keyed
|
;
|
;
|
Prompt3:
|
Prompt3:
|
bsr GetKey
|
bsr GetKey
|
cmpi.b #-1,d1
|
cmpi.b #-1,d1
|
beq.s Prompt3
|
beq.s Prompt3
|
cmpi.b #CR,d1
|
cmpi.b #CR,d1
|
beq.s Prompt1
|
beq.s Prompt1
|
bsr DisplayChar
|
bsr DisplayChar
|
bra.s Prompt3
|
bra.s Prompt3
|
|
|
; Process the screen line that the CR was keyed on
|
; Process the screen line that the CR was keyed on
|
|
|
Prompt1:
|
Prompt1:
|
clr.b CursorCol ; go back to the start of the line
|
clr.b CursorCol ; go back to the start of the line
|
bsr CalcScreenLoc ; a0 = screen memory location
|
bsr CalcScreenLoc ; a0 = screen memory location
|
.0001:
|
.0001:
|
bsr FromScreen ; grab character off screen
|
bsr FromScreen ; grab character off screen
|
cmpi.b #'$',d1 ; skip over '$' prompt character
|
cmpi.b #'$',d1 ; skip over '$' prompt character
|
beq.s .0001
|
beq.s .0001
|
|
|
; Dispatch based on command string
|
; Dispatch based on command string
|
|
|
cmdDispatch:
|
cmdDispatch:
|
lea cmdString,a2
|
lea cmdString,a2
|
clr.l d4 ; command counter
|
clr.l d4 ; command counter
|
lea -8(a0),a0 ; backup a character
|
lea -8(a0),a0 ; backup a character
|
move.l a0,a3 ; a3 = start of command on screen
|
move.l a0,a3 ; a3 = start of command on screen
|
.checkNextCmd:
|
.checkNextCmd:
|
bsr FromScreen ; d1 = char from input screen
|
bsr FromScreen ; d1 = char from input screen
|
move.b (a2)+,d5
|
move.b (a2)+,d5
|
eor.b d5,d1 ; does it match with command string?
|
eor.b d5,d1 ; does it match with command string?
|
beq.s .checkNextCmd ; If it does, keep matching for longest match
|
beq.s .checkNextCmd ; If it does, keep matching for longest match
|
cmpi.b #$80,d1 ; didn't match, was it the end of the command?
|
cmpi.b #$80,d1 ; didn't match, was it the end of the command?
|
beq.s .foundCmd
|
beq.s .foundCmd
|
tst.b -1(a2) ; was end of table hit?
|
tst.b -1(a2) ; was end of table hit?
|
beq.s .endOfTable
|
beq.s .endOfTable
|
addi.w #2,d4 ; increment command counter
|
addi.w #2,d4 ; increment command counter
|
move.l a3,a0 ; reset input pointer
|
move.l a3,a0 ; reset input pointer
|
tst.b -1(a2) ; were we at the end of the command?
|
tst.b -1(a2) ; were we at the end of the command?
|
bmi.s .checkNextCmd ; if were at end continue, otherwise scan for enf of cmd
|
bmi.s .checkNextCmd ; if were at end continue, otherwise scan for enf of cmd
|
.scanToEndOfCmd
|
.scanToEndOfCmd
|
tst.b (a2)+ ; scan to end of command
|
tst.b (a2)+ ; scan to end of command
|
beq.s .endOfTable
|
beq.s .endOfTable
|
bpl.s .scanToEndOfCmd
|
bpl.s .scanToEndOfCmd
|
bmi.s .checkNextCmd
|
bmi.s .checkNextCmd
|
.endOfTable
|
.endOfTable
|
lea msgUnknownCmd,a1
|
lea msgUnknownCmd,a1
|
bsr DisplayStringCRLF
|
bsr DisplayStringCRLF
|
bra Monitor
|
bra Monitor
|
.foundCmd:
|
.foundCmd:
|
lea cmdTable,a1 ; a1 = pointer to command address table
|
lea cmdTable,a1 ; a1 = pointer to command address table
|
move.w (a1,d4.w),a1 ; fetch command routine address from table
|
move.w (a1,d4.w),a1 ; fetch command routine address from table
|
jmp (a1) ; go execute command
|
jmp (a1) ; go execute command
|
|
|
cmdBreakpoint:
|
cmdBreakpoint:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr FromScreen
|
bsr FromScreen
|
cmpi.b #'+',d1
|
cmpi.b #'+',d1
|
beq ArmBreakpoint
|
beq ArmBreakpoint
|
cmpi.b #'-',d1
|
cmpi.b #'-',d1
|
beq DisarmBreakpoint
|
beq DisarmBreakpoint
|
cmpi.b #'L',d1
|
cmpi.b #'L',d1
|
beq ListBreakpoints
|
beq ListBreakpoints
|
bra Monitor
|
bra Monitor
|
|
|
cmdTinyBasic:
|
cmdTinyBasic:
|
bra CSTART
|
bra CSTART
|
|
|
cmdTestCPU:
|
cmdTestCPU:
|
bsr cpu_test
|
bsr cpu_test
|
lea msg_test_done,a1
|
lea msg_test_done,a1
|
bsr DisplayStringCRLF
|
bsr DisplayStringCRLF
|
bra Monitor
|
bra Monitor
|
|
|
cmdClearScreen:
|
cmdClearScreen:
|
bsr ClearScreen
|
bsr ClearScreen
|
bsr HomeCursor
|
bsr HomeCursor
|
bra Monitor
|
bra Monitor
|
|
|
cmdCore:
|
cmdCore:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr FromScreen
|
bsr FromScreen
|
cmpi.b #'2',d1 ; check range
|
cmpi.b #'2',d1 ; check range
|
blo Monitor
|
blo Monitor
|
cmpi.b #'9',d1
|
cmpi.b #'9',d1
|
bhi Monitor
|
bhi Monitor
|
subi.b #'0',d1 ; convert ascii to binary
|
subi.b #'0',d1 ; convert ascii to binary
|
bsr select_iofocus
|
bsr select_iofocus
|
bra Monitor
|
bra Monitor
|
|
|
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
; CLOCK
|
; CLOCK
|
; Set the clock register to n which will turn off or on clocks to the CPUs.
|
; Set the clock register to n which will turn off or on clocks to the CPUs.
|
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
|
|
cmdClock:
|
cmdClock:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
tst.b d0 ; was there a number?
|
tst.b d0 ; was there a number?
|
beq Monitor
|
beq Monitor
|
ori.w #4,d0 ; primary core's clock cannot be turned off
|
ori.w #4,d0 ; primary core's clock cannot be turned off
|
rol.w #8,d1 ; switch byte order
|
rol.w #8,d1 ; switch byte order
|
move.w d1,RST_REG+2
|
move.w d1,RST_REG+2
|
bra Monitor
|
bra Monitor
|
|
|
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
; RESET
|
; RESET
|
; Reset the specified core. Resetting the core automatically turns on the
|
; Reset the specified core. Resetting the core automatically turns on the
|
; core's clock.
|
; core's clock.
|
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
|
|
cmdReset:
|
cmdReset:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr FromScreen
|
bsr FromScreen
|
cmpi.b #'2',d1 ; check range
|
cmpi.b #'2',d1 ; check range
|
blo Monitor
|
blo Monitor
|
cmpi.b #'9',d1
|
cmpi.b #'9',d1
|
bhi Monitor
|
bhi Monitor
|
subi.b #'0',d1 ; convert ascii to binary
|
subi.b #'0',d1 ; convert ascii to binary
|
lsl.w #1,d1 ; make into index
|
lsl.w #1,d1 ; make into index
|
lea tblPow2,a1
|
lea tblPow2,a1
|
move.w (a1,d1.w),d1
|
move.w (a1,d1.w),d1
|
rol.w #8,d1 ; reverse byte order
|
rol.w #8,d1 ; reverse byte order
|
move.w d1,RST_REG
|
move.w d1,RST_REG
|
bra Monitor
|
bra Monitor
|
|
|
tblPow2:
|
tblPow2:
|
dc.w 1
|
dc.w 1
|
dc.w 2
|
dc.w 2
|
dc.w 4
|
dc.w 4
|
dc.w 8
|
dc.w 8
|
dc.w 16
|
dc.w 16
|
dc.w 32
|
dc.w 32
|
dc.w 64
|
dc.w 64
|
dc.w 128
|
dc.w 128
|
dc.w 256
|
dc.w 256
|
dc.w 512
|
dc.w 512
|
dc.w 1024
|
dc.w 1024
|
dc.w 2048
|
dc.w 2048
|
dc.w 4096
|
dc.w 4096
|
dc.w 8192
|
dc.w 8192
|
dc.w 16384
|
dc.w 16384
|
dc.w 32768
|
dc.w 32768
|
even
|
even
|
|
|
cmdHelp:
|
cmdHelp:
|
DisplayHelp:
|
DisplayHelp:
|
lea HelpMsg,a1
|
lea HelpMsg,a1
|
bsr DisplayString
|
bsr DisplayString
|
bra Monitor
|
bra Monitor
|
|
|
HelpMsg:
|
HelpMsg:
|
dc.b "? = Display help",LF,CR
|
dc.b "? = Display help",LF,CR
|
dc.b "CORE n = switch to core n, n = 2 to 7",LF,CR
|
dc.b "CORE n = switch to core n, n = 2 to 7",LF,CR
|
dc.b "RESET n = reset core n",LF,CR
|
dc.b "RESET n = reset core n",LF,CR
|
dc.b "CLS = clear screen",LF,CR
|
dc.b "CLS = clear screen",LF,CR
|
dc.b ": = Edit memory bytes",LF,CR
|
dc.b ": = Edit memory bytes",LF,CR
|
dc.b "FB = Fill memory bytes, FW, FL",LF,CR
|
dc.b "FB = Fill memory bytes, FW, FL",LF,CR
|
dc.b "L = Load S19 file",LF,CR
|
dc.b "L = Load S19 file",LF,CR
|
dc.b "D = Dump memory, DR = dump registers",LF,CR
|
dc.b "D = Dump memory, DR = dump registers",LF,CR
|
dc.b "BA = start tiny basic",LF,CR
|
dc.b "BA = start tiny basic",LF,CR
|
dc.b "BR = set breakpoint",LF,CR
|
dc.b "BR = set breakpoint",LF,CR
|
dc.b "J = Jump to code",LF,CR
|
dc.b "J = Jump to code",LF,CR
|
dc.b "S = send to serial port",LF,CR
|
dc.b "S = send to serial port",LF,CR
|
dc.b "T = cpu test program",LF,CR
|
dc.b "T = cpu test program",LF,CR
|
dc.b "TRAM = test RAM",LF,CR,0
|
dc.b "TRAM = test RAM",LF,CR,0
|
|
|
msgUnknownCmd:
|
msgUnknownCmd:
|
dc.b "command unknown",0
|
dc.b "command unknown",0
|
|
|
msgHello:
|
msgHello:
|
dc.b LF,CR,"Hello World!",LF,CR,0
|
dc.b LF,CR,"Hello World!",LF,CR,0
|
even
|
even
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; This routine borrowed from Gordo's Tiny Basic interpreter.
|
; This routine borrowed from Gordo's Tiny Basic interpreter.
|
; Used to fetch a command line. (Not currently used).
|
; Used to fetch a command line. (Not currently used).
|
;
|
;
|
; d0.b - command prompt
|
; d0.b - command prompt
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
GetCmdLine:
|
GetCmdLine:
|
bsr DisplayChar ; display prompt
|
bsr DisplayChar ; display prompt
|
move.b #' ',d0
|
move.b #' ',d0
|
bsr DisplayChar
|
bsr DisplayChar
|
lea CmdBuf,a0
|
lea CmdBuf,a0
|
.0001:
|
.0001:
|
bsr GetKey
|
bsr GetKey
|
cmp.b #CTRLH,d0
|
cmp.b #CTRLH,d0
|
beq.s .0003
|
beq.s .0003
|
cmp.b #CTRLX,d0
|
cmp.b #CTRLX,d0
|
beq.s .0004
|
beq.s .0004
|
cmp.b #CR,d0
|
cmp.b #CR,d0
|
beq.s .0002
|
beq.s .0002
|
cmp.b #' ',d0
|
cmp.b #' ',d0
|
bcs.s .0001
|
bcs.s .0001
|
.0002:
|
.0002:
|
move.b d0,(a0)
|
move.b d0,(a0)
|
lea 8(a0),a0
|
lea 8(a0),a0
|
bsr DisplayChar
|
bsr DisplayChar
|
cmp.b #CR,d0
|
cmp.b #CR,d0
|
beq .0007
|
beq .0007
|
cmp.l #CmdBufEnd-1,a0
|
cmp.l #CmdBufEnd-1,a0
|
bcs.s .0001
|
bcs.s .0001
|
.0003:
|
.0003:
|
move.b #CTRLH,d0
|
move.b #CTRLH,d0
|
bsr DisplayChar
|
bsr DisplayChar
|
move.b #' ',d0
|
move.b #' ',d0
|
bsr DisplayChar
|
bsr DisplayChar
|
cmp.l #CmdBuf,a0
|
cmp.l #CmdBuf,a0
|
bls.s .0001
|
bls.s .0001
|
move.b #CTRLH,d0
|
move.b #CTRLH,d0
|
bsr DisplayChar
|
bsr DisplayChar
|
subq.l #1,a0
|
subq.l #1,a0
|
bra.s .0001
|
bra.s .0001
|
.0004:
|
.0004:
|
move.l a0,d1
|
move.l a0,d1
|
sub.l #CmdBuf,d1
|
sub.l #CmdBuf,d1
|
beq.s .0006
|
beq.s .0006
|
subq #1,d1
|
subq #1,d1
|
.0005:
|
.0005:
|
move.b #CTRLH,d0
|
move.b #CTRLH,d0
|
bsr DisplayChar
|
bsr DisplayChar
|
move.b #' ',d0
|
move.b #' ',d0
|
bsr DisplayChar
|
bsr DisplayChar
|
move.b #CTRLH,d0
|
move.b #CTRLH,d0
|
bsr DisplayChar
|
bsr DisplayChar
|
dbra d1,.0005
|
dbra d1,.0005
|
.0006:
|
.0006:
|
lea CmdBuf,a0
|
lea CmdBuf,a0
|
bra .0001
|
bra .0001
|
.0007:
|
.0007:
|
move.b #LF,d0
|
move.b #LF,d0
|
bsr DisplayChar
|
bsr DisplayChar
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; S
|
; S
|
; Send data buffer to serial port
|
; Send data buffer to serial port
|
; S 40000 40
|
; S 40000 40
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
cmdSendSerial:
|
cmdSendSerial:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
beq Monitor
|
beq Monitor
|
move.l d1,d6 ; d6 points to buffer
|
move.l d1,d6 ; d6 points to buffer
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
bne.s .0003
|
bne.s .0003
|
moveq #16,d1
|
moveq #16,d1
|
.0003:
|
.0003:
|
move.l d6,a1 ; a1 points to buffer
|
move.l d6,a1 ; a1 points to buffer
|
move.l d1,d2 ; d2 = count of bytes to send
|
move.l d1,d2 ; d2 = count of bytes to send
|
bra.s .0002 ; enter loop at bottom
|
bra.s .0002 ; enter loop at bottom
|
.0001:
|
.0001:
|
move.b (a1)+,d1
|
move.b (a1)+,d1
|
move.w #34,d0 ; serial putchar
|
move.w #34,d0 ; serial putchar
|
trap #15
|
trap #15
|
.0002:
|
.0002:
|
dbra d2,.0001
|
dbra d2,.0001
|
bra Monitor
|
bra Monitor
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; R
|
; R
|
; Send data buffer to serial port
|
; Send data buffer to serial port
|
; R 10000 40
|
; R 10000 40
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
cmdReceiveSerial:
|
cmdReceiveSerial:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
beq Monitor
|
beq Monitor
|
move.l d1,d6 ; d6 points to buffer
|
move.l d1,d6 ; d6 points to buffer
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
bne.s .0003
|
bne.s .0003
|
moveq #16,d1
|
moveq #16,d1
|
.0003:
|
.0003:
|
move.l d6,a1 ; a1 points to buffer
|
move.l d6,a1 ; a1 points to buffer
|
move.l d1,d2 ; d2 = count of bytes to send
|
move.l d1,d2 ; d2 = count of bytes to send
|
bra.s .0002 ; enter loop at bottom
|
bra.s .0002 ; enter loop at bottom
|
.0001:
|
.0001:
|
move.w #36,d0 ; serial peek char
|
move.w #36,d0 ; serial peek char
|
trap #15
|
trap #15
|
tst.l d1
|
tst.l d1
|
bmi.s .0001
|
bmi.s .0001
|
move.b d1,(a1)+
|
move.b d1,(a1)+
|
.0002:
|
.0002:
|
dbra d2,.0001
|
dbra d2,.0001
|
bra Monitor
|
bra Monitor
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Fill memory
|
; Fill memory
|
;
|
;
|
; FB = fill bytes FB 00000010 100 FF ; fill starting at 10 for 256 bytes
|
; FB = fill bytes FB 00000010 100 FF ; fill starting at 10 for 256 bytes
|
; FW = fill words
|
; FW = fill words
|
; FL = fill longs
|
; FL = fill longs
|
; F = fill bytes
|
; F = fill bytes
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
cmdFillB:
|
cmdFillB:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
move.l d1,a1 ; a1 = start
|
move.l d1,a1 ; a1 = start
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
move.l d1,d3 ; d3 = count
|
move.l d1,d3 ; d3 = count
|
beq Monitor
|
beq Monitor
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber ; fill value
|
bsr GetHexNumber ; fill value
|
.fmem:
|
.fmem:
|
move.b d1,(a1)+
|
move.b d1,(a1)+
|
sub.l #1,d3
|
sub.l #1,d3
|
bne.s .fmem
|
bne.s .fmem
|
bra Monitor
|
bra Monitor
|
|
|
cmdFillW:
|
cmdFillW:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
move.l d1,a1 ; a1 = start
|
move.l d1,a1 ; a1 = start
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
move.l d1,d3 ; d3 = count
|
move.l d1,d3 ; d3 = count
|
beq Monitor
|
beq Monitor
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber ; fill value
|
bsr GetHexNumber ; fill value
|
.fmem:
|
.fmem:
|
move.w d1,(a1)+
|
move.w d1,(a1)+
|
sub.l #1,d3
|
sub.l #1,d3
|
bne.s .fmem
|
bne.s .fmem
|
bra Monitor
|
bra Monitor
|
|
|
cmdFillL:
|
cmdFillL:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
move.l d1,a1 ; a1 = start
|
move.l d1,a1 ; a1 = start
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
move.l d1,d3 ; d3 = count
|
move.l d1,d3 ; d3 = count
|
beq Monitor
|
beq Monitor
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber ; fill value
|
bsr GetHexNumber ; fill value
|
.fmem:
|
.fmem:
|
move.l d1,(a1)+
|
move.l d1,(a1)+
|
sub.l #1,d3
|
sub.l #1,d3
|
bne.s .fmem
|
bne.s .fmem
|
bra Monitor
|
bra Monitor
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Modifies:
|
; Modifies:
|
; a0 - text pointer
|
; a0 - text pointer
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
ignBlanks:
|
ignBlanks:
|
move.l d1,-(a7)
|
move.l d1,-(a7)
|
.0001:
|
.0001:
|
bsr FromScreen
|
bsr FromScreen
|
cmpi.b #' ',d1
|
cmpi.b #' ',d1
|
beq.s .0001
|
beq.s .0001
|
lea -8(a0),a0
|
lea -8(a0),a0
|
move.l (a7)+,d1
|
move.l (a7)+,d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Edit memory byte.
|
; Edit memory byte.
|
; Bytes are built into long words in case the memory is only longword
|
; Bytes are built into long words in case the memory is only longword
|
; accessible.
|
; accessible.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
cmdEditMemory:
|
cmdEditMemory:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
move.l d1,a1
|
move.l d1,a1
|
edtmem1:
|
edtmem1:
|
clr.l d2
|
clr.l d2
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
move.b d1,d2
|
move.b d1,d2
|
; move.b d1,(a1)+
|
; move.b d1,(a1)+
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
lsl.l #8,d2
|
lsl.l #8,d2
|
move.b d1,d2
|
move.b d1,d2
|
; move.b d1,(a1)+
|
; move.b d1,(a1)+
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
lsl.l #8,d2
|
lsl.l #8,d2
|
move.b d1,d2
|
move.b d1,d2
|
; move.b d1,(a1)+
|
; move.b d1,(a1)+
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
lsl.l #8,d2
|
lsl.l #8,d2
|
move.b d1,d2
|
move.b d1,d2
|
move.l d2,(a1)+
|
move.l d2,(a1)+
|
; move.b d1,(a1)+
|
; move.b d1,(a1)+
|
clr.l d2
|
clr.l d2
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
move.b d1,d2
|
move.b d1,d2
|
; move.b d1,(a1)+
|
; move.b d1,(a1)+
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
lsl.l #8,d2
|
lsl.l #8,d2
|
move.b d1,d2
|
move.b d1,d2
|
; move.b d1,(a1)+
|
; move.b d1,(a1)+
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
lsl.l #8,d2
|
lsl.l #8,d2
|
move.b d1,d2
|
move.b d1,d2
|
; move.b d1,(a1)+
|
; move.b d1,(a1)+
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
lsl.l #8,d2
|
lsl.l #8,d2
|
move.b d1,d2
|
move.b d1,d2
|
; move.b d1,(a1)+
|
; move.b d1,(a1)+
|
move.l d2,(a1)+
|
move.l d2,(a1)+
|
bra Monitor
|
bra Monitor
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Execute code at the specified address.
|
; Execute code at the specified address.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
cmdJump:
|
cmdJump:
|
ExecuteCode:
|
ExecuteCode:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
move.l d1,a0
|
move.l d1,a0
|
jsr (a0)
|
jsr (a0)
|
bra Monitor
|
bra Monitor
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Do a memory dump of the requested location.
|
; Do a memory dump of the requested location.
|
; D 0800 0850
|
; D 0800 0850
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
cmdDumpMemory:
|
cmdDumpMemory:
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
beq Monitor ; was there a number ? no, other garbage, just ignore
|
beq Monitor ; was there a number ? no, other garbage, just ignore
|
move.l d1,d3 ; save off start of range
|
move.l d1,d3 ; save off start of range
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
bne.s DumpMem1
|
bne.s DumpMem1
|
move.l d3,d1
|
move.l d3,d1
|
addi.l #64,d1 ; no end specified, just dump 64 bytes
|
addi.l #64,d1 ; no end specified, just dump 64 bytes
|
DumpMem1:
|
DumpMem1:
|
move.l d3,a0
|
move.l d3,a0
|
move.l d1,a1
|
move.l d1,a1
|
bsr CRLF
|
bsr CRLF
|
.0001:
|
.0001:
|
cmpa.l a0,a1
|
cmpa.l a0,a1
|
bls Monitor
|
bls Monitor
|
bsr DisplayMem
|
bsr DisplayMem
|
bra.s .0001
|
bra.s .0001
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Display memory dump in a format suitable for edit.
|
; Display memory dump in a format suitable for edit.
|
;
|
;
|
; :12345678 00 11 22 33 44 55 66 77 "........"
|
; :12345678 00 11 22 33 44 55 66 77 "........"
|
;
|
;
|
; Modifies:
|
; Modifies:
|
; d1,d2,a0
|
; d1,d2,a0
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisplayMem:
|
DisplayMem:
|
move.b #':',d1
|
move.b #':',d1
|
bsr DisplayChar
|
bsr DisplayChar
|
move.l a0,d1
|
move.l a0,d1
|
bsr DisplayTetra
|
bsr DisplayTetra
|
moveq #7,d2
|
moveq #7,d2
|
dspmem1:
|
dspmem1:
|
move.b #' ',d1
|
move.b #' ',d1
|
bsr DisplayChar
|
bsr DisplayChar
|
move.b (a0)+,d1
|
move.b (a0)+,d1
|
bsr DisplayByte
|
bsr DisplayByte
|
dbra d2,dspmem1
|
dbra d2,dspmem1
|
bsr DisplayTwoSpaces
|
bsr DisplayTwoSpaces
|
move.b #34,d1
|
move.b #34,d1
|
bsr DisplayChar
|
bsr DisplayChar
|
lea -8(a0),a0
|
lea -8(a0),a0
|
moveq #7,d2
|
moveq #7,d2
|
.0002:
|
.0002:
|
move.b (a0)+,d1
|
move.b (a0)+,d1
|
cmp.b #' ',d1
|
cmp.b #' ',d1
|
blo.s .0003
|
blo.s .0003
|
cmp.b #127,d1
|
cmp.b #127,d1
|
bls.s .0001
|
bls.s .0001
|
.0003:
|
.0003:
|
move.b #'.',d1
|
move.b #'.',d1
|
.0001:
|
.0001:
|
bsr DisplayChar
|
bsr DisplayChar
|
dbra d2,.0002
|
dbra d2,.0002
|
move.b #34,d1
|
move.b #34,d1
|
bsr DisplayChar
|
bsr DisplayChar
|
bsr CheckForCtrlC
|
bsr CheckForCtrlC
|
bra CRLF
|
bra CRLF
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Dump Registers
|
; Dump Registers
|
; The dump is in a format that allows the register value to be edited.
|
; The dump is in a format that allows the register value to be edited.
|
;
|
;
|
; RegD0 12345678
|
; RegD0 12345678
|
; RegD1 77777777
|
; RegD1 77777777
|
; ... etc
|
; ... etc
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
cmdDumpRegs:
|
cmdDumpRegs:
|
bsr CRLF
|
bsr CRLF
|
move.w #15,d0 ; number of registers-1
|
move.w #15,d0 ; number of registers-1
|
lea msg_reglist,a0 ;
|
lea msg_reglist,a0 ;
|
lea msg_regs,a1
|
lea msg_regs,a1
|
lea Regsave,a2 ; a2 points to register save area
|
lea Regsave,a2 ; a2 points to register save area
|
.0001:
|
.0001:
|
bsr DisplayString
|
bsr DisplayString
|
move.b (a0)+,d1
|
move.b (a0)+,d1
|
bsr DisplayChar
|
bsr DisplayChar
|
move.b (a0)+,d1
|
move.b (a0)+,d1
|
bsr DisplayChar
|
bsr DisplayChar
|
bsr DisplaySpace
|
bsr DisplaySpace
|
move.l (a2)+,d1
|
move.l (a2)+,d1
|
bsr DisplayTetra
|
bsr DisplayTetra
|
bsr CRLF
|
bsr CRLF
|
dbra d0,.0001
|
dbra d0,.0001
|
bsr DisplayString
|
bsr DisplayString
|
move.b (a0)+,d1
|
move.b (a0)+,d1
|
bsr DisplayChar
|
bsr DisplayChar
|
move.b (a0)+,d1
|
move.b (a0)+,d1
|
bsr DisplayChar
|
bsr DisplayChar
|
bsr DisplaySpace
|
bsr DisplaySpace
|
move.l Regsave+$44,d1
|
move.l Regsave+$44,d1
|
bsr DisplayTetra
|
bsr DisplayTetra
|
bsr CRLF
|
bsr CRLF
|
bsr DisplayString
|
bsr DisplayString
|
move.b (a0)+,d1
|
move.b (a0)+,d1
|
bsr DisplayChar
|
bsr DisplayChar
|
move.b (a0)+,d1
|
move.b (a0)+,d1
|
bsr DisplayChar
|
bsr DisplayChar
|
bsr DisplaySpace
|
bsr DisplaySpace
|
move.w Regsave+$40,d1
|
move.w Regsave+$40,d1
|
bsr DisplayWyde
|
bsr DisplayWyde
|
bsr CRLF
|
bsr CRLF
|
bra Monitor
|
bra Monitor
|
|
|
msg_regs:
|
msg_regs:
|
dc.b "Reg",0
|
dc.b "Reg",0
|
msg_reglist:
|
msg_reglist:
|
dc.b "D0D1D2D3D4D5D6D7A0A1A2A3A4A5A6A7PCSR",0
|
dc.b "D0D1D2D3D4D5D6D7A0A1A2A3A4A5A6A7PCSR",0
|
|
|
align 1
|
align 1
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
cmdTestSerialReceive:
|
cmdTestSerialReceive:
|
.0002:
|
.0002:
|
moveq #36,d0 ; serial get char from buffer
|
moveq #36,d0 ; serial get char from buffer
|
trap #15
|
trap #15
|
; bsr SerialPeekCharDirect
|
; bsr SerialPeekCharDirect
|
tst.w d1
|
tst.w d1
|
bmi.s .0001
|
bmi.s .0001
|
cmpi.b #CTRLZ,d1
|
cmpi.b #CTRLZ,d1
|
beq .0003
|
beq .0003
|
bsr DisplayChar
|
bsr DisplayChar
|
.0001:
|
.0001:
|
bsr CheckForCtrlC
|
bsr CheckForCtrlC
|
bra .0002
|
bra .0002
|
.0003:
|
.0003:
|
bsr _KeybdInit
|
bsr _KeybdInit
|
bra Monitor
|
bra Monitor
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Get a hexidecimal number. Maximum of eight digits.
|
; Get a hexidecimal number. Maximum of eight digits.
|
;
|
;
|
; Returns:
|
; Returns:
|
; d0 = number of digits
|
; d0 = number of digits
|
; d1 = value of number
|
; d1 = value of number
|
; zf = number of digits == 0
|
; zf = number of digits == 0
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
GetHexNumber:
|
GetHexNumber:
|
move.l d2,-(a7)
|
move.l d2,-(a7)
|
clr.l d2
|
clr.l d2
|
moveq #0,d0
|
moveq #0,d0
|
.0002:
|
.0002:
|
bsr FromScreen
|
bsr FromScreen
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
cmp.b #$ff,d1
|
cmp.b #$ff,d1
|
beq.s .0001
|
beq.s .0001
|
lsl.l #4,d2
|
lsl.l #4,d2
|
andi.l #$0f,d1
|
andi.l #$0f,d1
|
or.l d1,d2
|
or.l d1,d2
|
addq #1,d0
|
addq #1,d0
|
cmpi.b #8,d0
|
cmpi.b #8,d0
|
blo.s .0002
|
blo.s .0002
|
.0001:
|
.0001:
|
move.l d2,d1
|
move.l d2,d1
|
move.l (a7)+,d2
|
move.l (a7)+,d2
|
tst.b d0
|
tst.b d0
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Convert ASCII character in the range '0' to '9', 'a' tr 'f' or 'A' to 'F'
|
; Convert ASCII character in the range '0' to '9', 'a' tr 'f' or 'A' to 'F'
|
; to a hex nybble.
|
; to a hex nybble.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
AsciiToHexNybble:
|
AsciiToHexNybble:
|
cmpi.b #'0',d1
|
cmpi.b #'0',d1
|
blo.s gthx3
|
blo.s gthx3
|
cmpi.b #'9',d1
|
cmpi.b #'9',d1
|
bhi.s gthx5
|
bhi.s gthx5
|
subi.b #'0',d1
|
subi.b #'0',d1
|
rts
|
rts
|
gthx5:
|
gthx5:
|
cmpi.b #'A',d1
|
cmpi.b #'A',d1
|
blo.s gthx3
|
blo.s gthx3
|
cmpi.b #'F',d1
|
cmpi.b #'F',d1
|
bhi.s gthx6
|
bhi.s gthx6
|
addi.b #10-'A',d1
|
addi.b #10-'A',d1
|
rts
|
rts
|
gthx6:
|
gthx6:
|
cmpi.b #'a',d1
|
cmpi.b #'a',d1
|
blo.s gthx3
|
blo.s gthx3
|
cmpi.b #'f',d1
|
cmpi.b #'f',d1
|
bhi.s gthx3
|
bhi.s gthx3
|
addi.b #10-'a',d1
|
addi.b #10-'a',d1
|
rts
|
rts
|
gthx3:
|
gthx3:
|
moveq #-1,d1 ; not a hex number
|
moveq #-1,d1 ; not a hex number
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisplayTwoSpaces:
|
DisplayTwoSpaces:
|
move.l d1,-(a7)
|
move.l d1,-(a7)
|
move.b #' ',d1
|
move.b #' ',d1
|
bsr DisplayChar
|
bsr DisplayChar
|
dspspc1:
|
dspspc1:
|
bsr DisplayChar
|
bsr DisplayChar
|
move.l (a7)+,d1
|
move.l (a7)+,d1
|
rts
|
rts
|
|
|
DisplaySpace:
|
DisplaySpace:
|
move.l d1,-(a7)
|
move.l d1,-(a7)
|
move.b #' ',d1
|
move.b #' ',d1
|
bra dspspc1
|
bra dspspc1
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Display the 32 bit word in D1.L
|
; Display the 32 bit word in D1.L
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisplayTetra:
|
DisplayTetra:
|
swap d1
|
swap d1
|
bsr DisplayWyde
|
bsr DisplayWyde
|
swap d1
|
swap d1
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Display the byte in D1.W
|
; Display the byte in D1.W
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisplayWyde:
|
DisplayWyde:
|
ror.w #8,d1
|
ror.w #8,d1
|
bsr DisplayByte
|
bsr DisplayByte
|
rol.w #8,d1
|
rol.w #8,d1
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Display the byte in D1.B
|
; Display the byte in D1.B
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisplayByte:
|
DisplayByte:
|
ror.b #4,d1
|
ror.b #4,d1
|
bsr DisplayNybble
|
bsr DisplayNybble
|
rol.b #4,d1
|
rol.b #4,d1
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Display nybble in D1.B
|
; Display nybble in D1.B
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisplayNybble:
|
DisplayNybble:
|
move.l d1,-(a7)
|
move.l d1,-(a7)
|
andi.b #$F,d1
|
andi.b #$F,d1
|
addi.b #'0',d1
|
addi.b #'0',d1
|
cmpi.b #'9',d1
|
cmpi.b #'9',d1
|
bls.s .0001
|
bls.s .0001
|
addi.b #7,d1
|
addi.b #7,d1
|
.0001:
|
.0001:
|
bsr DisplayChar
|
bsr DisplayChar
|
move.l (a7)+,d1
|
move.l (a7)+,d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;
|
;
|
;DisplayHexNumber:
|
;DisplayHexNumber:
|
; move.w #$A6A6,leds ; diagnostics
|
; move.w #$A6A6,leds ; diagnostics
|
; move.l #VDGREG,a6
|
; move.l #VDGREG,a6
|
; move.w #7,d2 ; number-1 of digits to display
|
; move.w #7,d2 ; number-1 of digits to display
|
;disphnum1:
|
;disphnum1:
|
; move.b d1,d0 ; get digit into d0.b
|
; move.b d1,d0 ; get digit into d0.b
|
; andi.w #$0f,d0
|
; andi.w #$0f,d0
|
; cmpi.w #$09,d0
|
; cmpi.w #$09,d0
|
; bls.s disphnum2
|
; bls.s disphnum2
|
; addi.w #7,d0
|
; addi.w #7,d0
|
;disphnum2:
|
;disphnum2:
|
; addi.w #$30,d0 ; convert to display char
|
; addi.w #$30,d0 ; convert to display char
|
; move.w d2,d3 ; char count into d3
|
; move.w d2,d3 ; char count into d3
|
; asl.w #3,d3 ; scale * 8
|
; asl.w #3,d3 ; scale * 8
|
;disphnum3:
|
;disphnum3:
|
; move.w $42C(a6),d4 ; read character queue index into d4
|
; move.w $42C(a6),d4 ; read character queue index into d4
|
; cmp.w #28,d4 ; allow up 28 entries to be in progress
|
; cmp.w #28,d4 ; allow up 28 entries to be in progress
|
; bhs.s disphnum3 ; branch if too many chars queued
|
; bhs.s disphnum3 ; branch if too many chars queued
|
; ext.w d0 ; zero out high order bits
|
; ext.w d0 ; zero out high order bits
|
; move.w d0,$420(a6) ; set char code
|
; move.w d0,$420(a6) ; set char code
|
; move.w #WHITE,$422(a6) ; set fg color
|
; move.w #WHITE,$422(a6) ; set fg color
|
; move.w #DARK_BLUE,$424(a6) ; set bk color
|
; move.w #DARK_BLUE,$424(a6) ; set bk color
|
; move.w d3,$426(a6) ; set x pos
|
; move.w d3,$426(a6) ; set x pos
|
; move.w #8,$428(a6) ; set y pos
|
; move.w #8,$428(a6) ; set y pos
|
; move.w #$0707,$42A(a6) ; set font x,y extent
|
; move.w #$0707,$42A(a6) ; set font x,y extent
|
; move.w #0,$42E(a6) ; pulse character queue write signal
|
; move.w #0,$42E(a6) ; pulse character queue write signal
|
; ror.l #4,d1 ; rot to next digit
|
; ror.l #4,d1 ; rot to next digit
|
; dbeq d2,disphnum1
|
; dbeq d2,disphnum1
|
; jmp (a5)
|
; jmp (a5)
|
|
|
;===============================================================================
|
;===============================================================================
|
; Perform ram test. (Uses checkerboard testing).
|
; Perform ram test. (Uses checkerboard testing).
|
;
|
;
|
; Local ram, which does not get tested, is used for the stack.
|
; Local ram, which does not get tested, is used for the stack.
|
;===============================================================================
|
;===============================================================================
|
|
|
DisplayAddr:
|
DisplayAddr:
|
move.l a0,d1
|
move.l a0,d1
|
lsr.l #8,d1
|
lsr.l #8,d1
|
lsr.l #8,d1
|
lsr.l #8,d1
|
lsr.l #4,d1
|
lsr.l #4,d1
|
subi.w #512,d1
|
subi.w #512,d1
|
bin2bcd d1
|
bin2bcd d1
|
bsr DisplayWyde
|
bsr DisplayWyde
|
move.b #CR,d1
|
move.b #CR,d1
|
bra DisplayChar
|
bra DisplayChar
|
btst #$83,d0
|
btst #$83,d0
|
|
|
cmdTestRAM:
|
cmdTestRAM:
|
ramtest:
|
ramtest:
|
move.w #$A5A5,leds ; diagnostics
|
move.w #$A5A5,leds ; diagnostics
|
move.l #$aaaaaaaa,d3
|
move.l #$aaaaaaaa,d3
|
move.l #$55555555,d4
|
move.l #$55555555,d4
|
bsr ramtest0
|
bsr ramtest0
|
; switch checkerboard pattern and repeat test.
|
; switch checkerboard pattern and repeat test.
|
exg d3,d4
|
exg d3,d4
|
bsr ramtest0
|
bsr ramtest0
|
; Save last ram address in end of memory pointer.
|
; Save last ram address in end of memory pointer.
|
rmtst5:
|
rmtst5:
|
moveq #37,d0 ; lock semaphore
|
moveq #37,d0 ; lock semaphore
|
moveq #MEMORY_SEMA,d1
|
moveq #MEMORY_SEMA,d1
|
trap #15
|
trap #15
|
move.l a0,memend
|
move.l a0,memend
|
; Create very first memory block.
|
; Create very first memory block.
|
suba.l #12,a0
|
suba.l #12,a0
|
move.l a0,$20000004 ; length of block
|
move.l a0,$20000004 ; length of block
|
move.l #$46524545,$20000000
|
move.l #$46524545,$20000000
|
moveq #38,d0 ; unlock semaphore
|
moveq #38,d0 ; unlock semaphore
|
moveq #MEMORY_SEMA,d1
|
moveq #MEMORY_SEMA,d1
|
trap #15
|
trap #15
|
rts
|
rts
|
|
|
ramtest0:
|
ramtest0:
|
move.l d3,d0
|
move.l d3,d0
|
movea.l #$20000000,a0
|
movea.l #$20000000,a0
|
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
; Write checkerboard pattern to ram then read it back to
|
; Write checkerboard pattern to ram then read it back to
|
; find the highest usable ram address (maybe). This address
|
; find the highest usable ram address (maybe). This address
|
; must be lower than the start of the rom (0xe00000).
|
; must be lower than the start of the rom (0xe00000).
|
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
ramtest1:
|
ramtest1:
|
move.l d3,(a0)+
|
move.l d3,(a0)+
|
move.l d4,(a0)+
|
move.l d4,(a0)+
|
move.l a0,d1
|
move.l a0,d1
|
tst.w d1
|
tst.w d1
|
bne.s rmtst1
|
bne.s rmtst1
|
bsr DisplayAddr
|
bsr DisplayAddr
|
bsr CheckForCtrlC
|
bsr CheckForCtrlC
|
rmtst1:
|
rmtst1:
|
cmpa.l #$3FFFFFF8,a0
|
cmpa.l #$3FFFFFF8,a0
|
blo.s ramtest1
|
blo.s ramtest1
|
bsr CRLF
|
bsr CRLF
|
;------------------------------------------------------
|
;------------------------------------------------------
|
; Save maximum useable address for later comparison.
|
; Save maximum useable address for later comparison.
|
;------------------------------------------------------
|
;------------------------------------------------------
|
ramtest6:
|
ramtest6:
|
move.w #$A7A7,leds ; diagnostics
|
move.w #$A7A7,leds ; diagnostics
|
movea.l a0,a2
|
movea.l a0,a2
|
movea.l #$20000000,a0
|
movea.l #$20000000,a0
|
;--------------------------------------------
|
;--------------------------------------------
|
; Read back checkerboard pattern from ram.
|
; Read back checkerboard pattern from ram.
|
;--------------------------------------------
|
;--------------------------------------------
|
ramtest2
|
ramtest2
|
move.l (a0)+,d5
|
move.l (a0)+,d5
|
move.l (a0)+,d6
|
move.l (a0)+,d6
|
cmpa.l a2,a0
|
cmpa.l a2,a0
|
bhs.s ramtest3
|
bhs.s ramtest3
|
move.l a0,d1
|
move.l a0,d1
|
tst.w d1
|
tst.w d1
|
bne.s rmtst2
|
bne.s rmtst2
|
bsr DisplayAddr
|
bsr DisplayAddr
|
bsr CheckForCtrlC
|
bsr CheckForCtrlC
|
rmtst2
|
rmtst2
|
cmp.l d3,d5
|
cmp.l d3,d5
|
bne.s rmtst3
|
bne.s rmtst3
|
cmp.l d4,d6
|
cmp.l d4,d6
|
beq.s ramtest2
|
beq.s ramtest2
|
;----------------------------------
|
;----------------------------------
|
; Report error in ram.
|
; Report error in ram.
|
;----------------------------------
|
;----------------------------------
|
rmtst3
|
rmtst3
|
bsr CRLF
|
bsr CRLF
|
moveq #'E',d1
|
moveq #'E',d1
|
bsr DisplayChar
|
bsr DisplayChar
|
bsr DisplaySpace
|
bsr DisplaySpace
|
move.l a0,d1
|
move.l a0,d1
|
bsr DisplayTetra
|
bsr DisplayTetra
|
bsr DisplaySpace
|
bsr DisplaySpace
|
move.l d5,d1
|
move.l d5,d1
|
bsr DisplayTetra
|
bsr DisplayTetra
|
bsr CheckForCtrlC
|
bsr CheckForCtrlC
|
bra ramtest2
|
bra ramtest2
|
ramtest3
|
ramtest3
|
rts
|
rts
|
|
|
;==============================================================================
|
;==============================================================================
|
; Load an S19 format file
|
; Load an S19 format file
|
;==============================================================================
|
;==============================================================================
|
|
|
cmdLoadS19:
|
cmdLoadS19:
|
bsr CRLF
|
bsr CRLF
|
bra ProcessRec
|
bra ProcessRec
|
NextRec:
|
NextRec:
|
bsr sGetChar
|
bsr sGetChar
|
cmpi.b #LF,d1
|
cmpi.b #LF,d1
|
bne NextRec
|
bne NextRec
|
move.b #'.',d1
|
move.b #'.',d1
|
bsr DisplayChar
|
bsr DisplayChar
|
ProcessRec:
|
ProcessRec:
|
bsr CheckForCtrlC ; check for CTRL-C once per record
|
bsr CheckForCtrlC ; check for CTRL-C once per record
|
bsr sGetChar
|
bsr sGetChar
|
cmpi.b #CR,d1
|
cmpi.b #CR,d1
|
beq.s ProcessRec
|
beq.s ProcessRec
|
clr.b S19Checksum
|
clr.b S19Checksum
|
move.b d1,d4
|
move.b d1,d4
|
cmpi.b #CTRLZ,d4 ; CTRL-Z ?
|
cmpi.b #CTRLZ,d4 ; CTRL-Z ?
|
beq Monitor
|
beq Monitor
|
cmpi.b #'S',d4 ; All records must begin with an 'S'
|
cmpi.b #'S',d4 ; All records must begin with an 'S'
|
bne.s NextRec
|
bne.s NextRec
|
bsr sGetChar
|
bsr sGetChar
|
move.b d1,d4
|
move.b d1,d4
|
cmpi.b #'0',d4 ; Record type must be between '0' and '9'
|
cmpi.b #'0',d4 ; Record type must be between '0' and '9'
|
blo.s NextRec
|
blo.s NextRec
|
cmpi.b #'9',d4 ; d4 = record type
|
cmpi.b #'9',d4 ; d4 = record type
|
bhi.s NextRec
|
bhi.s NextRec
|
bsr sGetChar ; get byte count for record
|
bsr sGetChar ; get byte count for record
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
move.b d1,d2
|
move.b d1,d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.b #4,d2
|
lsl.b #4,d2
|
or.b d2,d1 ; d1 = byte count
|
or.b d2,d1 ; d1 = byte count
|
move.b d1,d3 ; d3 = byte count
|
move.b d1,d3 ; d3 = byte count
|
add.b d3,S19Checksum
|
add.b d3,S19Checksum
|
cmpi.b #'0',d4 ; manufacturer ID record, ignore
|
cmpi.b #'0',d4 ; manufacturer ID record, ignore
|
beq NextRec
|
beq NextRec
|
cmpi.b #'1',d4
|
cmpi.b #'1',d4
|
beq ProcessS1
|
beq ProcessS1
|
cmpi.b #'2',d4
|
cmpi.b #'2',d4
|
beq ProcessS2
|
beq ProcessS2
|
cmpi.b #'3',d4
|
cmpi.b #'3',d4
|
beq ProcessS3
|
beq ProcessS3
|
cmpi.b #'5',d4 ; record count record, ignore
|
cmpi.b #'5',d4 ; record count record, ignore
|
beq NextRec
|
beq NextRec
|
cmpi.b #'7',d4
|
cmpi.b #'7',d4
|
beq ProcessS7
|
beq ProcessS7
|
cmpi.b #'8',d4
|
cmpi.b #'8',d4
|
beq ProcessS8
|
beq ProcessS8
|
cmpi.b #'9',d4
|
cmpi.b #'9',d4
|
beq ProcessS9
|
beq ProcessS9
|
bra NextRec
|
bra NextRec
|
|
|
pcssxa:
|
pcssxa:
|
move.l a1,d1
|
move.l a1,d1
|
bsr DisplayTetra
|
bsr DisplayTetra
|
move.b #CR,d1
|
move.b #CR,d1
|
bsr DisplayChar
|
bsr DisplayChar
|
andi.w #$ff,d3
|
andi.w #$ff,d3
|
subi.w #1,d3 ; one less for dbra
|
subi.w #1,d3 ; one less for dbra
|
.0001:
|
.0001:
|
clr.l d2
|
clr.l d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.l #4,d2
|
lsl.l #4,d2
|
or.b d1,d2
|
or.b d1,d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.l #4,d2
|
lsl.l #4,d2
|
or.b d1,d2
|
or.b d1,d2
|
add.b d2,S19Checksum
|
add.b d2,S19Checksum
|
move.b d2,(a1)+ ; move byte to memory
|
move.b d2,(a1)+ ; move byte to memory
|
dbra d3,.0001
|
dbra d3,.0001
|
; Get the checksum byte
|
; Get the checksum byte
|
clr.l d2
|
clr.l d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.l #4,d2
|
lsl.l #4,d2
|
or.b d1,d2
|
or.b d1,d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.l #4,d2
|
lsl.l #4,d2
|
or.b d1,d2
|
or.b d1,d2
|
eor.b #$FF,d2
|
eor.b #$FF,d2
|
cmp.b S19Checksum,d2
|
cmp.b S19Checksum,d2
|
beq NextRec
|
beq NextRec
|
move.b #'E',d1
|
move.b #'E',d1
|
bsr DisplayChar
|
bsr DisplayChar
|
bra NextRec
|
bra NextRec
|
|
|
ProcessS1:
|
ProcessS1:
|
bsr S19Get16BitAddress
|
bsr S19Get16BitAddress
|
bra pcssxa
|
bra pcssxa
|
ProcessS2:
|
ProcessS2:
|
bsr S19Get24BitAddress
|
bsr S19Get24BitAddress
|
bra pcssxa
|
bra pcssxa
|
ProcessS3:
|
ProcessS3:
|
bsr S19Get32BitAddress
|
bsr S19Get32BitAddress
|
bra pcssxa
|
bra pcssxa
|
ProcessS7:
|
ProcessS7:
|
bsr S19Get32BitAddress
|
bsr S19Get32BitAddress
|
move.l a1,S19StartAddress
|
move.l a1,S19StartAddress
|
bsr _KeybdInit
|
bsr _KeybdInit
|
bra Monitor
|
bra Monitor
|
ProcessS8:
|
ProcessS8:
|
bsr S19Get24BitAddress
|
bsr S19Get24BitAddress
|
move.l a1,S19StartAddress
|
move.l a1,S19StartAddress
|
bsr _KeybdInit
|
bsr _KeybdInit
|
bra Monitor
|
bra Monitor
|
ProcessS9:
|
ProcessS9:
|
bsr S19Get16BitAddress
|
bsr S19Get16BitAddress
|
move.l a1,S19StartAddress
|
move.l a1,S19StartAddress
|
bsr _KeybdInit
|
bsr _KeybdInit
|
bra Monitor
|
bra Monitor
|
|
|
S19Get16BitAddress:
|
S19Get16BitAddress:
|
clr.l d2
|
clr.l d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
move.b d1,d2
|
move.b d1,d2
|
bra S1932b
|
bra S1932b
|
|
|
S19Get24BitAddress:
|
S19Get24BitAddress:
|
clr.l d2
|
clr.l d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
move.b d1,d2
|
move.b d1,d2
|
bra S1932a
|
bra S1932a
|
|
|
S19Get32BitAddress:
|
S19Get32BitAddress:
|
clr.l d2
|
clr.l d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
move.b d1,d2
|
move.b d1,d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.l #4,d2
|
lsl.l #4,d2
|
or.b d1,d2
|
or.b d1,d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.l #4,d2
|
lsl.l #4,d2
|
or.b d1,d2
|
or.b d1,d2
|
S1932a:
|
S1932a:
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.l #4,d2
|
lsl.l #4,d2
|
or.b d1,d2
|
or.b d1,d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.l #4,d2
|
lsl.l #4,d2
|
or.b d1,d2
|
or.b d1,d2
|
S1932b:
|
S1932b:
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.l #4,d2
|
lsl.l #4,d2
|
or.b d1,d2
|
or.b d1,d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.l #4,d2
|
lsl.l #4,d2
|
or.b d1,d2
|
or.b d1,d2
|
bsr sGetChar
|
bsr sGetChar
|
bsr AsciiToHexNybble
|
bsr AsciiToHexNybble
|
lsl.l #4,d2
|
lsl.l #4,d2
|
or.b d1,d2
|
or.b d1,d2
|
clr.l d4
|
clr.l d4
|
move.l d2,a1
|
move.l d2,a1
|
; Add bytes from address value to checksum
|
; Add bytes from address value to checksum
|
add.b d2,S19Checksum
|
add.b d2,S19Checksum
|
lsr.l #8,d2
|
lsr.l #8,d2
|
add.b d2,S19Checksum
|
add.b d2,S19Checksum
|
lsr.l #8,d2
|
lsr.l #8,d2
|
add.b d2,S19Checksum
|
add.b d2,S19Checksum
|
lsr.l #8,d2
|
lsr.l #8,d2
|
add.b d2,S19Checksum
|
add.b d2,S19Checksum
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Get a character from auxillary input. Waiting for a character is limited to
|
; Get a character from auxillary input. Waiting for a character is limited to
|
; 32000 tries. If a character is not available within the limit, then a return
|
; 32000 tries. If a character is not available within the limit, then a return
|
; to the monitor is done.
|
; to the monitor is done.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; none
|
; none
|
; Returns:
|
; Returns:
|
; d1 = character from receive buffer or -1 if no char available
|
; d1 = character from receive buffer or -1 if no char available
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
sGetChar:
|
sGetChar:
|
movem.l d0/d2,-(a7)
|
movem.l d0/d2,-(a7)
|
move.w #32000,d2
|
move.w #32000,d2
|
.0001:
|
.0001:
|
moveq #36,d0 ; serial get char from buffer
|
moveq #36,d0 ; serial get char from buffer
|
trap #15
|
trap #15
|
tst.w d1 ; was there a char available?
|
tst.w d1 ; was there a char available?
|
bpl.s .0002
|
bpl.s .0002
|
dbra d2,.0001 ; no - try again
|
dbra d2,.0001 ; no - try again
|
movem.l (a7)+,d0/d2
|
movem.l (a7)+,d0/d2
|
.0003:
|
.0003:
|
bsr _KeybdInit
|
bsr _KeybdInit
|
bra Monitor ; ran out of tries
|
bra Monitor ; ran out of tries
|
.0002:
|
.0002:
|
movem.l (a7)+,d0/d2
|
movem.l (a7)+,d0/d2
|
cmpi.b #CTRLZ,d1 ; receive end of file?
|
cmpi.b #CTRLZ,d1 ; receive end of file?
|
beq .0003
|
beq .0003
|
rts
|
rts
|
|
|
AudioInputTest:
|
AudioInputTest:
|
rts
|
rts
|
BouncingBalls:
|
BouncingBalls:
|
rts
|
rts
|
GraphicsDemo:
|
GraphicsDemo:
|
rts
|
rts
|
ClearScreen:
|
ClearScreen:
|
bra clear_screen
|
bra clear_screen
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Reverse the order of bytes in d1.
|
; Reverse the order of bytes in d1.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
rbo:
|
rbo:
|
rol.w #8,d1
|
rol.w #8,d1
|
swap d1
|
swap d1
|
rol.w #8,d1
|
rol.w #8,d1
|
rts
|
rts
|
|
|
;==============================================================================
|
;==============================================================================
|
; Serial I/O routines
|
; Serial I/O routines
|
;==============================================================================
|
;==============================================================================
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Initialize the serial port an enhanced 6551 circuit.
|
; Initialize the serial port an enhanced 6551 circuit.
|
;
|
;
|
; Select internal baud rate clock divider for 9600 baud
|
; Select internal baud rate clock divider for 9600 baud
|
; Reset fifos, set threshold to 3/4 full on transmit and 3/4 empty on receive
|
; Reset fifos, set threshold to 3/4 full on transmit and 3/4 empty on receive
|
; Note that the byte order is swapped.
|
; Note that the byte order is swapped.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialInit:
|
SerialInit:
|
clr.w SerHeadRcv ; clear receive buffer indexes
|
clr.w SerHeadRcv ; clear receive buffer indexes
|
clr.w SerTailRcv
|
clr.w SerTailRcv
|
clr.b SerRcvXon ; and Xon,Xoff flags
|
clr.b SerRcvXon ; and Xon,Xoff flags
|
clr.b SerRcvXoff
|
clr.b SerRcvXoff
|
move.l #$09000000,d0 ; dtr,rts active, rxint enabled, no parity
|
move.l #$09000000,d0 ; dtr,rts active, rxint enabled, no parity
|
move.l d0,ACIA+ACIA_CMD
|
move.l d0,ACIA+ACIA_CMD
|
; move.l #$1E00F700,d0 ; fifos enabled
|
; move.l #$1E00F700,d0 ; fifos enabled
|
move.l #$1E000000,d0 ; fifos disabled
|
move.l #$1E000000,d0 ; fifos disabled
|
move.l d0,ACIA+ACIA_CTRL
|
move.l d0,ACIA+ACIA_CTRL
|
rts
|
rts
|
; move.l #$0F000000,d0 ; transmit a break for a while
|
; move.l #$0F000000,d0 ; transmit a break for a while
|
; move.l d0,ACIA+ACIA_CMD
|
; move.l d0,ACIA+ACIA_CMD
|
; move.l #300000,d2 ; wait 100 ms
|
; move.l #300000,d2 ; wait 100 ms
|
; bra .0001
|
; bra .0001
|
;.0003:
|
;.0003:
|
; swap d2
|
; swap d2
|
;.0001:
|
;.0001:
|
; nop
|
; nop
|
; dbra d2,.0001
|
; dbra d2,.0001
|
;.0002:
|
;.0002:
|
; swap d2
|
; swap d2
|
; dbra d2,.0003
|
; dbra d2,.0003
|
; move.l #$07000000,d0 ; clear break
|
; move.l #$07000000,d0 ; clear break
|
; move.l d0,ACIA+ACIA_CMD
|
; move.l d0,ACIA+ACIA_CMD
|
; rts
|
; rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; SerialGetChar
|
; SerialGetChar
|
;
|
;
|
; Check the serial port buffer to see if there's a char available. If there's
|
; Check the serial port buffer to see if there's a char available. If there's
|
; a char available then return it. If the buffer is almost empty then send an
|
; a char available then return it. If the buffer is almost empty then send an
|
; XON.
|
; XON.
|
;
|
;
|
; Stack Space:
|
; Stack Space:
|
; 2 long words
|
; 2 long words
|
; Parameters:
|
; Parameters:
|
; none
|
; none
|
; Modifies:
|
; Modifies:
|
; d0,a0
|
; d0,a0
|
; Returns:
|
; Returns:
|
; d1 = character or -1
|
; d1 = character or -1
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialGetChar:
|
SerialGetChar:
|
move.l d2,-(a7)
|
move.l d2,-(a7)
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SERIAL_SEMA,d1
|
moveq #SERIAL_SEMA,d1
|
bsr LockSemaphore
|
bsr LockSemaphore
|
bsr SerialRcvCount ; check number of chars in receive buffer
|
bsr SerialRcvCount ; check number of chars in receive buffer
|
cmpi.w #8,d0 ; less than 8?
|
cmpi.w #8,d0 ; less than 8?
|
bhi .sgc2
|
bhi .sgc2
|
tst.b SerRcvXon ; skip sending XON if already sent
|
tst.b SerRcvXon ; skip sending XON if already sent
|
bne .sgc2 ; XON already sent?
|
bne .sgc2 ; XON already sent?
|
move.b #XON,d1 ; if <8 send an XON
|
move.b #XON,d1 ; if <8 send an XON
|
clr.b SerRcvXoff ; clear XOFF status
|
clr.b SerRcvXoff ; clear XOFF status
|
move.b d1,SerRcvXon ; flag so we don't send it multiple times
|
move.b d1,SerRcvXon ; flag so we don't send it multiple times
|
bsr SerialPutChar ; send it
|
bsr SerialPutChar ; send it
|
.sgc2:
|
.sgc2:
|
move.w SerHeadRcv,d1 ; check if anything is in buffer
|
move.w SerHeadRcv,d1 ; check if anything is in buffer
|
cmp.w SerTailRcv,d1
|
cmp.w SerTailRcv,d1
|
beq .NoChars ; no?
|
beq .NoChars ; no?
|
lea SerRcvBuf,a0
|
lea SerRcvBuf,a0
|
move.b (a0,d1.w),d1 ; get byte from buffer
|
move.b (a0,d1.w),d1 ; get byte from buffer
|
addi.w #1,SerHeadRcv
|
addi.w #1,SerHeadRcv
|
andi.w #$FFF,SerHeadRcv ; 4k wrap around
|
andi.w #$FFF,SerHeadRcv ; 4k wrap around
|
andi.l #$FF,d1
|
andi.l #$FF,d1
|
bra .Xit
|
bra .Xit
|
.NoChars:
|
.NoChars:
|
moveq #-1,d1
|
moveq #-1,d1
|
.Xit:
|
.Xit:
|
exg d1,d2
|
exg d1,d2
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SERIAL_SEMA,d1
|
moveq #SERIAL_SEMA,d1
|
bsr UnlockSemaphore
|
bsr UnlockSemaphore
|
exg d2,d1
|
exg d2,d1
|
move.l (a7)+,d2
|
move.l (a7)+,d2
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; SerialPeekChar
|
; SerialPeekChar
|
;
|
;
|
; Check the serial port buffer to see if there's a char available. If there's
|
; Check the serial port buffer to see if there's a char available. If there's
|
; a char available then return it. But don't update the buffer indexes. No need
|
; a char available then return it. But don't update the buffer indexes. No need
|
; to send an XON here.
|
; to send an XON here.
|
;
|
;
|
; Stack Space:
|
; Stack Space:
|
; 0 words
|
; 0 words
|
; Parameters:
|
; Parameters:
|
; none
|
; none
|
; Modifies:
|
; Modifies:
|
; d0,d2,a0
|
; d0,d2,a0
|
; Returns:
|
; Returns:
|
; d1 = character or -1
|
; d1 = character or -1
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialPeekChar:
|
SerialPeekChar:
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SERIAL_SEMA,d1
|
moveq #SERIAL_SEMA,d1
|
bsr LockSemaphore
|
bsr LockSemaphore
|
move.w SerHeadRcv,d2 ; check if anything is in buffer
|
move.w SerHeadRcv,d2 ; check if anything is in buffer
|
cmp.w SerTailRcv,d2
|
cmp.w SerTailRcv,d2
|
beq .NoChars ; no?
|
beq .NoChars ; no?
|
lea SerRcvBuf,a0
|
lea SerRcvBuf,a0
|
move.b (a0,d2.w),d2 ; get byte from buffer
|
move.b (a0,d2.w),d2 ; get byte from buffer
|
bra .Xit
|
bra .Xit
|
.NoChars:
|
.NoChars:
|
moveq #-1,d2
|
moveq #-1,d2
|
.Xit:
|
.Xit:
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SERIAL_SEMA,d1
|
moveq #SERIAL_SEMA,d1
|
bsr LockSemaphore
|
bsr LockSemaphore
|
move d2,d1
|
move d2,d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; SerialPeekChar
|
; SerialPeekChar
|
; Get a character directly from the I/O port. This bypasses the input
|
; Get a character directly from the I/O port. This bypasses the input
|
; buffer.
|
; buffer.
|
;
|
;
|
; Stack Space:
|
; Stack Space:
|
; 0 words
|
; 0 words
|
; Parameters:
|
; Parameters:
|
; none
|
; none
|
; Modifies:
|
; Modifies:
|
; d
|
; d
|
; Returns:
|
; Returns:
|
; d1 = character or -1
|
; d1 = character or -1
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialPeekCharDirect:
|
SerialPeekCharDirect:
|
move.b ACIA+ACIA_STAT,d1 ; get serial status
|
move.b ACIA+ACIA_STAT,d1 ; get serial status
|
btst #3,d1 ; look for Rx not empty
|
btst #3,d1 ; look for Rx not empty
|
beq.s .0001
|
beq.s .0001
|
moveq.l #0,d1 ; clear upper bits of return value
|
moveq.l #0,d1 ; clear upper bits of return value
|
move.b ACIA+ACIA_RX,d1 ; get data from ACIA
|
move.b ACIA+ACIA_RX,d1 ; get data from ACIA
|
rts ; return
|
rts ; return
|
.0001:
|
.0001:
|
moveq #-1,d1
|
moveq #-1,d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; SerialPutChar
|
; SerialPutChar
|
; Put a character to the serial transmitter. This routine blocks until the
|
; Put a character to the serial transmitter. This routine blocks until the
|
; transmitter is empty.
|
; transmitter is empty.
|
;
|
;
|
; Stack Space
|
; Stack Space
|
; 0 words
|
; 0 words
|
; Parameters:
|
; Parameters:
|
; d1.b = character to put
|
; d1.b = character to put
|
; Modifies:
|
; Modifies:
|
; none
|
; none
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialPutChar:
|
SerialPutChar:
|
movem.l d0/d1,-(a7) ; push d0,d1
|
movem.l d0/d1,-(a7) ; push d0,d1
|
.0001:
|
.0001:
|
move.b ACIA+ACIA_STAT,d0 ; wait until the uart indicates tx empty
|
move.b ACIA+ACIA_STAT,d0 ; wait until the uart indicates tx empty
|
btst #4,d0 ; bit #4 of the status reg
|
btst #4,d0 ; bit #4 of the status reg
|
beq.s .0001 ; branch if transmitter is not empty
|
beq.s .0001 ; branch if transmitter is not empty
|
move.b d1,ACIA+ACIA_TX ; send the byte
|
move.b d1,ACIA+ACIA_TX ; send the byte
|
movem.l (a7)+,d0/d1 ; pop d0,d1
|
movem.l (a7)+,d0/d1 ; pop d0,d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Reverse the order of bytes in d1.
|
; Reverse the order of bytes in d1.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialRbo:
|
SerialRbo:
|
rol.w #8,d1
|
rol.w #8,d1
|
swap d1
|
swap d1
|
rol.w #8,d1
|
rol.w #8,d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Calculate number of character in input buffer
|
; Calculate number of character in input buffer
|
;
|
;
|
; Returns:
|
; Returns:
|
; d0 = number of bytes in buffer.
|
; d0 = number of bytes in buffer.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialRcvCount:
|
SerialRcvCount:
|
move.w SerTailRcv,d0
|
move.w SerTailRcv,d0
|
sub.w SerHeadRcv,d0
|
sub.w SerHeadRcv,d0
|
bge .0001
|
bge .0001
|
move.w #$1000,d0
|
move.w #$1000,d0
|
sub.w SerHeadRcv,d0
|
sub.w SerHeadRcv,d0
|
add.w SerTailRcv,d0
|
add.w SerTailRcv,d0
|
.0001:
|
.0001:
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Serial IRQ routine
|
; Serial IRQ routine
|
;
|
;
|
; Keeps looping as long as it finds characters in the ACIA recieve buffer/fifo.
|
; Keeps looping as long as it finds characters in the ACIA recieve buffer/fifo.
|
; Received characters are buffered. If the buffer becomes full, new characters
|
; Received characters are buffered. If the buffer becomes full, new characters
|
; will be lost.
|
; will be lost.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; none
|
; none
|
; Modifies:
|
; Modifies:
|
; none
|
; none
|
; Returns:
|
; Returns:
|
; d1 = -1 if IRQ handled, otherwise zero
|
; d1 = -1 if IRQ handled, otherwise zero
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialIRQ:
|
SerialIRQ:
|
move.w #$2300,sr ; disable lower level IRQs
|
move.w #$2300,sr ; disable lower level IRQs
|
movem.l d0/d1/d2/a0,-(a7)
|
movem.l d0/d1/d2/a0,-(a7)
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SERIAL_SEMA,d1
|
moveq #SERIAL_SEMA,d1
|
bsr LockSemaphore
|
bsr LockSemaphore
|
sirqNxtByte:
|
sirqNxtByte:
|
move.b ACIA+ACIA_STAT,d1 ; check the status
|
move.b ACIA+ACIA_STAT,d1 ; check the status
|
btst #3,d1 ; bit 3 = rx full
|
btst #3,d1 ; bit 3 = rx full
|
beq notRxInt
|
beq notRxInt
|
move.b ACIA+ACIA_RX,d1
|
move.b ACIA+ACIA_RX,d1
|
sirq0001:
|
sirq0001:
|
move.w SerTailRcv,d0 ; check if recieve buffer full
|
move.w SerTailRcv,d0 ; check if recieve buffer full
|
addi.w #1,d0
|
addi.w #1,d0
|
andi.w #$FFF,d0
|
andi.w #$FFF,d0
|
cmp.w SerHeadRcv,d0
|
cmp.w SerHeadRcv,d0
|
beq sirqRxFull
|
beq sirqRxFull
|
move.w d0,SerTailRcv ; update tail pointer
|
move.w d0,SerTailRcv ; update tail pointer
|
subi.w #1,d0 ; backup
|
subi.w #1,d0 ; backup
|
andi.w #$FFF,d0
|
andi.w #$FFF,d0
|
lea SerRcvBuf,a0 ; a0 = buffer address
|
lea SerRcvBuf,a0 ; a0 = buffer address
|
move.b d1,(a0,d0.w) ; store recieved byte in buffer
|
move.b d1,(a0,d0.w) ; store recieved byte in buffer
|
tst.b SerRcvXoff ; check if xoff already sent
|
tst.b SerRcvXoff ; check if xoff already sent
|
bne sirqNxtByte
|
bne sirqNxtByte
|
bsr SerialRcvCount ; if more than 4080 chars in buffer
|
bsr SerialRcvCount ; if more than 4080 chars in buffer
|
cmpi.w #4080,d0
|
cmpi.w #4080,d0
|
blo sirqNxtByte
|
blo sirqNxtByte
|
move.b #XOFF,d1 ; send an XOFF
|
move.b #XOFF,d1 ; send an XOFF
|
clr.b SerRcvXon ; clear XON status
|
clr.b SerRcvXon ; clear XON status
|
move.b d1,SerRcvXoff ; set XOFF status
|
move.b d1,SerRcvXoff ; set XOFF status
|
bsr SerialPutChar ; send XOFF
|
bsr SerialPutChar ; send XOFF
|
bra sirqNxtByte ; check the status for another byte
|
bra sirqNxtByte ; check the status for another byte
|
sirqRxFull:
|
sirqRxFull:
|
notRxInt:
|
notRxInt:
|
movec coreno,d0
|
movec coreno,d0
|
swap d0
|
swap d0
|
moveq #SERIAL_SEMA,d1
|
moveq #SERIAL_SEMA,d1
|
bsr UnlockSemaphore
|
bsr UnlockSemaphore
|
movem.l (a7)+,d0/d1/d2/a0
|
movem.l (a7)+,d0/d1/d2/a0
|
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
|
|
|
bus_err:
|
bus_err:
|
.0001:
|
.0001:
|
nop
|
nop
|
bra .0001
|
bra .0001
|
|
|
trap3:
|
trap3:
|
; First save all registers
|
; First save all registers
|
movem.l d0/d1/d2/d3/d4/d5/d6/d7/a0/a1/a2/a3/a4/a5/a6/a7,Regsave
|
movem.l d0/d1/d2/d3/d4/d5/d6/d7/a0/a1/a2/a3/a4/a5/a6/a7,Regsave
|
move.w (a7)+,Regsave+$40
|
move.w (a7)+,Regsave+$40
|
move.l (a7)+,Regsave+$44
|
move.l (a7)+,Regsave+$44
|
move.l #$40FFC,a7 ; reset stack pointer
|
move.l #$40FFC,a7 ; reset stack pointer
|
move.w #$2500,sr ; enable interrupts
|
move.w #$2500,sr ; enable interrupts
|
move.w NumSetBreakpoints,d0
|
move.w NumSetBreakpoints,d0
|
subi.w #1,d0
|
subi.w #1,d0
|
lea Breakpoints,a0
|
lea Breakpoints,a0
|
move.l Regsave+$44,d1
|
move.l Regsave+$44,d1
|
.0001:
|
.0001:
|
cmp.l (a0)+,d1
|
cmp.l (a0)+,d1
|
beq.s ProcessBreakpoint
|
beq.s ProcessBreakpoint
|
dbra d0,.0001
|
dbra d0,.0001
|
bra Monitor ; not a breakpoint
|
bra Monitor ; not a breakpoint
|
ProcessBreakpoint:
|
ProcessBreakpoint:
|
bsr DisarmAllBreakpoints
|
bsr DisarmAllBreakpoints
|
bra cmdDumpRegs
|
bra cmdDumpRegs
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; DisarmAllBreakpoints, used when entering the monitor.
|
; DisarmAllBreakpoints, used when entering the monitor.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisarmAllBreakpoints:
|
DisarmAllBreakpoints:
|
movem.l d0/a0/a1/a2,-(a7) ; stack some regs
|
movem.l d0/a0/a1/a2,-(a7) ; stack some regs
|
move.w NumSetBreakpoints,d0 ; d0 = number of breakpoints that are set
|
move.w NumSetBreakpoints,d0 ; d0 = number of breakpoints that are set
|
cmpi.w #numBreakpoints,d0 ; check for valid number
|
cmpi.w #numBreakpoints,d0 ; check for valid number
|
bhs.s .0001
|
bhs.s .0001
|
lea Breakpoints,a2 ; a2 = pointer to breakpoint address table
|
lea Breakpoints,a2 ; a2 = pointer to breakpoint address table
|
lea BreakpointWords,a0 ; a0 = pointer to breakpoint instruction word table
|
lea BreakpointWords,a0 ; a0 = pointer to breakpoint instruction word table
|
bra.s .0003 ; enter loop at bottom
|
bra.s .0003 ; enter loop at bottom
|
.0002:
|
.0002:
|
move.l (a2)+,a1 ; a1 = address of breakpoint
|
move.l (a2)+,a1 ; a1 = address of breakpoint
|
move.w (a0)+,(a1) ; copy instruction word back to code
|
move.w (a0)+,(a1) ; copy instruction word back to code
|
.0003:
|
.0003:
|
dbra d0,.0002
|
dbra d0,.0002
|
movem.l (a7)+,d0/a0/a1/a2 ; restore regs
|
movem.l (a7)+,d0/a0/a1/a2 ; restore regs
|
.0001:
|
.0001:
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; ArmAllBreakpoints, used when entering the monitor.
|
; ArmAllBreakpoints, used when entering the monitor.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
ArmAllBreakpoints:
|
ArmAllBreakpoints:
|
movem.l d0/a0/a1/a2,-(a7) ; stack some regs
|
movem.l d0/a0/a1/a2,-(a7) ; stack some regs
|
move.w NumSetBreakpoints,d0 ; d0 = number of breakpoints
|
move.w NumSetBreakpoints,d0 ; d0 = number of breakpoints
|
cmpi.w #numBreakpoints,d0 ; is the number valid?
|
cmpi.w #numBreakpoints,d0 ; is the number valid?
|
bhs.s .0001
|
bhs.s .0001
|
lea Breakpoints,a2 ; a2 = pointer to breakpoint address table
|
lea Breakpoints,a2 ; a2 = pointer to breakpoint address table
|
lea BreakpointWords,a0 ; a0 = pointer to instruction word table
|
lea BreakpointWords,a0 ; a0 = pointer to instruction word table
|
bra.s .0003 ; enter loop at bottom
|
bra.s .0003 ; enter loop at bottom
|
.0002:
|
.0002:
|
move.l (a2)+,a1 ; a1 = address of breakpoint
|
move.l (a2)+,a1 ; a1 = address of breakpoint
|
move.w (a1),(a0) ; copy instruction word to table
|
move.w (a1),(a0) ; copy instruction word to table
|
move.w #$4E43,(a0)+ ; set instruction = TRAP3
|
move.w #$4E43,(a0)+ ; set instruction = TRAP3
|
.0003:
|
.0003:
|
dbra d0,.0002
|
dbra d0,.0002
|
movem.l (a7)+,d0/a0/a1/a2 ; restore regs
|
movem.l (a7)+,d0/a0/a1/a2 ; restore regs
|
.0001:
|
.0001:
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
ArmBreakpoint:
|
ArmBreakpoint:
|
movem.l d0/d1/d2/a0/a1/a2,-(a7)
|
movem.l d0/d1/d2/a0/a1/a2,-(a7)
|
move.w NumSetBreakpoints,d0 ; d0 = number of breakpoints
|
move.w NumSetBreakpoints,d0 ; d0 = number of breakpoints
|
cmpi.w #numBreakpoints,d0 ; check if too many
|
cmpi.w #numBreakpoints,d0 ; check if too many
|
bhs.s .0001
|
bhs.s .0001
|
addi.w #1,NumSetBreakpoints ; increment number of breakpoints
|
addi.w #1,NumSetBreakpoints ; increment number of breakpoints
|
move.l d0,d2
|
move.l d0,d2
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
beq.s .0001 ; was there an address?
|
beq.s .0001 ; was there an address?
|
btst #0,d1 ; address value must be even
|
btst #0,d1 ; address value must be even
|
bne.s .0001
|
bne.s .0001
|
; See if the breakpoint is in the table already
|
; See if the breakpoint is in the table already
|
lea Breakpoints,a1 ; a1 points to breakpoint table
|
lea Breakpoints,a1 ; a1 points to breakpoint table
|
move.w #numBreakpoints-1,d2
|
move.w #numBreakpoints-1,d2
|
.0002:
|
.0002:
|
cmp.l (a1)+,d1
|
cmp.l (a1)+,d1
|
beq.s .0003 ; breakpoint is in table already
|
beq.s .0003 ; breakpoint is in table already
|
dbra d2,.0002
|
dbra d2,.0002
|
; Add breakpoint to table
|
; Add breakpoint to table
|
; Search for empty entry
|
; Search for empty entry
|
lea Breakpoints,a1 ; a1 = pointer to breakpoint address table
|
lea Breakpoints,a1 ; a1 = pointer to breakpoint address table
|
clr.w d2 ; d2 = count
|
clr.w d2 ; d2 = count
|
.0006:
|
.0006:
|
tst.l (a1) ; is the entry empty?
|
tst.l (a1) ; is the entry empty?
|
beq.s .0005 ; branch if found empty entry
|
beq.s .0005 ; branch if found empty entry
|
lea 4(a1),a1 ; point to next entry
|
lea 4(a1),a1 ; point to next entry
|
addi.w #1,d2 ; increment count
|
addi.w #1,d2 ; increment count
|
cmpi.w #numBreakpoints,d2 ; safety: check against max number
|
cmpi.w #numBreakpoints,d2 ; safety: check against max number
|
blo.s .0006
|
blo.s .0006
|
bra.s .0001 ; what? no empty entries found, table corrupt?
|
bra.s .0001 ; what? no empty entries found, table corrupt?
|
.0005:
|
.0005:
|
asl.w #2,d2 ; d2 = long word index
|
asl.w #2,d2 ; d2 = long word index
|
move.l d1,(a1,d2.w) ; move breakpoint address to table
|
move.l d1,(a1,d2.w) ; move breakpoint address to table
|
move.l d1,a2
|
move.l d1,a2
|
lsr.w #1,d2 ; d2 = word index
|
lsr.w #1,d2 ; d2 = word index
|
.0004:
|
.0004:
|
lea BreakpointWords,a1
|
lea BreakpointWords,a1
|
move.w (a2),(a1,d2.w) ; copy instruction word to table
|
move.w (a2),(a1,d2.w) ; copy instruction word to table
|
move.w #$4E43,(a2) ; replace word with TRAP3
|
move.w #$4E43,(a2) ; replace word with TRAP3
|
.0001:
|
.0001:
|
movem.l (a7)+,d0/d1/d2/a0/a1/a2
|
movem.l (a7)+,d0/d1/d2/a0/a1/a2
|
rts
|
rts
|
.0003:
|
.0003:
|
move.l -4(a1),a2 ; a2 = pointer to breakpoint address from table
|
move.l -4(a1),a2 ; a2 = pointer to breakpoint address from table
|
cmpi.w #$4E43,(a2) ; see if breakpoint already armed
|
cmpi.w #$4E43,(a2) ; see if breakpoint already armed
|
beq.s .0001
|
beq.s .0001
|
asl.l #1,d2 ; d2 = word index
|
asl.l #1,d2 ; d2 = word index
|
bra.s .0004
|
bra.s .0004
|
|
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DisarmBreakpoint:
|
DisarmBreakpoint:
|
movem.l d0/d1/d2/a0/a1/a2,-(a7)
|
movem.l d0/d1/d2/a0/a1/a2,-(a7)
|
move.w NumSetBreakpoints,d0 ; d0 = number of breakpoints
|
move.w NumSetBreakpoints,d0 ; d0 = number of breakpoints
|
cmpi.w #numBreakpoints,d0 ; check if too many
|
cmpi.w #numBreakpoints,d0 ; check if too many
|
bhi.s .0001
|
bhi.s .0001
|
move.l d0,d2
|
move.l d0,d2
|
bsr ignBlanks
|
bsr ignBlanks
|
bsr GetHexNumber
|
bsr GetHexNumber
|
beq.s .0001 ; was there an address?
|
beq.s .0001 ; was there an address?
|
btst #0,d1 ; address value must be even
|
btst #0,d1 ; address value must be even
|
bne.s .0001
|
bne.s .0001
|
; See if the breakpoint is in the table already
|
; See if the breakpoint is in the table already
|
lea Breakpoints,a1 ; a1 points to breakpoint table
|
lea Breakpoints,a1 ; a1 points to breakpoint table
|
subi.w #1,d2
|
subi.w #1,d2
|
.0002:
|
.0002:
|
cmp.l (a1)+,d1
|
cmp.l (a1)+,d1
|
beq.s .0003 ; breakpoint is in table already
|
beq.s .0003 ; breakpoint is in table already
|
dbra d2,.0002
|
dbra d2,.0002
|
bra .0001 ; breakpoint was not in table
|
bra .0001 ; breakpoint was not in table
|
.0003:
|
.0003:
|
; Remove breakpoint from table
|
; Remove breakpoint from table
|
subi.w #1,NumSetBreakpoints ; decrement number of breakpoints
|
subi.w #1,NumSetBreakpoints ; decrement number of breakpoints
|
move.l -4(a1),a2 ; a2 = pointer to breakpoint address from table
|
move.l -4(a1),a2 ; a2 = pointer to breakpoint address from table
|
clr.l -4(a1) ; empty out breakpoint
|
clr.l -4(a1) ; empty out breakpoint
|
lea BreakpointWords,a1
|
lea BreakpointWords,a1
|
asl.l #1,d2 ; d2 = word index
|
asl.l #1,d2 ; d2 = word index
|
move.w (a1,d2.w),(a2) ; copy instruction from table back to code
|
move.w (a1,d2.w),(a2) ; copy instruction from table back to code
|
.0001:
|
.0001:
|
movem.l (a7)+,d0/d1/d2/a0/a1/a2
|
movem.l (a7)+,d0/d1/d2/a0/a1/a2
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
ListBreakpoints:
|
ListBreakpoints:
|
bsr CRLF
|
bsr CRLF
|
move.w #numBreakpoints,d2
|
move.w #numBreakpoints,d2
|
lea Breakpoints,a1
|
lea Breakpoints,a1
|
.0001:
|
.0001:
|
move.l (a1)+,d1
|
move.l (a1)+,d1
|
bsr DisplayTetra
|
bsr DisplayTetra
|
bsr CRLF
|
bsr CRLF
|
dbra d2,.0001
|
dbra d2,.0001
|
bra Monitor
|
bra Monitor
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
ClearBreakpointList:
|
ClearBreakpointList:
|
move.w #numBreakpoints,d2
|
move.w #numBreakpoints,d2
|
lea Breakpoints,a1
|
lea Breakpoints,a1
|
.0001:
|
.0001:
|
clr.l (a1)+
|
clr.l (a1)+
|
dbra d2,.0001
|
dbra d2,.0001
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; SendMsg
|
; SendMsg
|
; 00100xy0
|
; 00100xy0
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; d1 = target core number
|
; d1 = target core number
|
; d2 = argument 1
|
; d2 = argument 1
|
; d3 = argument 2
|
; d3 = argument 2
|
; d4 = argument 3
|
; d4 = argument 3
|
;
|
;
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SendMsg:
|
SendMsg:
|
movem.l d5/a1,-(a7)
|
movem.l d5/a1,-(a7)
|
lsl.w #8,d1
|
lsl.w #8,d1
|
movec coreno,d5
|
movec coreno,d5
|
lsl.w #4,d5
|
lsl.w #4,d5
|
or.w d5,d1
|
or.w d5,d1
|
lea $00100000,a1
|
lea $00100000,a1
|
tst.l 0(a1,d1.w)
|
tst.l 0(a1,d1.w)
|
bne .msgFull
|
bne .msgFull
|
movec coreno,d5
|
movec coreno,d5
|
move.l d5,0(a1,d1.w)
|
move.l d5,0(a1,d1.w)
|
move.l d2,4(a1,d1.w)
|
move.l d2,4(a1,d1.w)
|
move.l d3,8(a1,d1.w)
|
move.l d3,8(a1,d1.w)
|
move.l d4,12(a1,d1.w)
|
move.l d4,12(a1,d1.w)
|
movem.l (a7)+,d5/a1
|
movem.l (a7)+,d5/a1
|
moveq #0,d1
|
moveq #0,d1
|
rts
|
rts
|
.msgFull:
|
.msgFull:
|
movem.l (a7)+,d5/a1
|
movem.l (a7)+,d5/a1
|
moveq #-1,d1
|
moveq #-1,d1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; ReceiveMsg
|
; ReceiveMsg
|
; Scan the message table for messages and dispatch them.
|
; Scan the message table for messages and dispatch them.
|
; 00100xy0
|
; 00100xy0
|
;
|
;
|
; Parameters:
|
; Parameters:
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
ReceiveMsg:
|
ReceiveMsg:
|
movem.l d1/d2/d3/d4/d5/d6/d7/a1,-(a7)
|
movem.l d1/d2/d3/d4/d5/d6/d7/a1,-(a7)
|
lea $00100000,a1
|
lea $00100000,a1
|
movec coreno,d5
|
movec coreno,d5
|
lsl.w #8,d5
|
lsl.w #8,d5
|
moveq #2,d6
|
moveq #2,d6
|
.nextCore:
|
.nextCore:
|
move.w d6,d7
|
move.w d6,d7
|
lsl.w #4,d7
|
lsl.w #4,d7
|
add.w d5,d7
|
add.w d5,d7
|
tst.l 0(a1,d7.w) ; Is there a message from core d6?
|
tst.l 0(a1,d7.w) ; Is there a message from core d6?
|
beq .noMsg
|
beq .noMsg
|
move.l 0(a1,d7.w),d1
|
move.l 0(a1,d7.w),d1
|
move.l 4(a1,d7.w),d2
|
move.l 4(a1,d7.w),d2
|
move.l 8(a1,d7.w),d3
|
move.l 8(a1,d7.w),d3
|
move.l 12(a1,d7.w),d4
|
move.l 12(a1,d7.w),d4
|
clr.l 0(a1,d7.w) ; indicate message was received
|
clr.l 0(a1,d7.w) ; indicate message was received
|
bsr DispatchMsg
|
bsr DispatchMsg
|
.noMsg:
|
.noMsg:
|
addq #1,d6
|
addq #1,d6
|
cmp.w #9,d6
|
cmp.w #9,d6
|
bls .nextCore
|
bls .nextCore
|
movem.l (a7)+,d1/d2/d3/d4/d5/d6/d7/a1
|
movem.l (a7)+,d1/d2/d3/d4/d5/d6/d7/a1
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
DispatchMsg:
|
DispatchMsg:
|
rts
|
rts
|
|
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
InitIRQ:
|
InitIRQ:
|
moveq #6,d0
|
moveq #6,d0
|
lea KeybdIRQ,a0
|
lea KeybdIRQ,a0
|
bsr InstallIRQ
|
bsr InstallIRQ
|
lea TickIRQ,a0
|
lea TickIRQ,a0
|
bsr InstallIRQ
|
bsr InstallIRQ
|
moveq #3,d0
|
moveq #3,d0
|
lea SerialIRQ,a0
|
lea SerialIRQ,a0
|
; fall through
|
; fall through
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Install an IRQ handler.
|
; Install an IRQ handler.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; d0 = IRQ level
|
; d0 = IRQ level
|
; a0 = pointer to IRQ routine
|
; a0 = pointer to IRQ routine
|
; Returns:
|
; Returns:
|
; d1 = -1 if successfully added, 0 otherwise
|
; d1 = -1 if successfully added, 0 otherwise
|
; nf = 1, zf = 0 if successfully added, otherwise nf = 0, zf = 1
|
; nf = 1, zf = 0 if successfully added, otherwise nf = 0, zf = 1
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
InstallIRQ:
|
InstallIRQ:
|
move.l d0,-(a7) ; save working register
|
move.l d0,-(a7) ; save working register
|
lea InstalledIRQ,a1 ; a1 points to installed IRQ list
|
lea InstalledIRQ,a1 ; a1 points to installed IRQ list
|
lsl.w #5,d0 ; multiply by 8 long words per IRQ level
|
lsl.w #5,d0 ; multiply by 8 long words per IRQ level
|
.nextSpot:
|
.nextSpot:
|
cmpa.l (a1,d0.w),a0 ; Is the IRQ already installed?
|
cmpa.l (a1,d0.w),a0 ; Is the IRQ already installed?
|
beq.s .found
|
beq.s .found
|
tst.l (a1,d0.w) ; test for an empty spot
|
tst.l (a1,d0.w) ; test for an empty spot
|
beq.s .foundSpot
|
beq.s .foundSpot
|
addi.w #4,d0 ; increment to next slot
|
addi.w #4,d0 ; increment to next slot
|
move.w d0,d1
|
move.w d0,d1
|
andi.w #$1F,d1 ; check to see if spots exhausted
|
andi.w #$1F,d1 ; check to see if spots exhausted
|
beq.s .noEmpties
|
beq.s .noEmpties
|
bra.s .nextSpot
|
bra.s .nextSpot
|
.foundSpot:
|
.foundSpot:
|
move.l a0,(a1,d0.w) ; add IRQ routine to table
|
move.l a0,(a1,d0.w) ; add IRQ routine to table
|
.found:
|
.found:
|
move.l (a7)+,d0
|
move.l (a7)+,d0
|
moveq #-1,d1 ; return success
|
moveq #-1,d1 ; return success
|
rts
|
rts
|
.noEmpties:
|
.noEmpties:
|
move.l (a7)+,d0
|
move.l (a7)+,d0
|
moveq #0,d1 ; return failed to add
|
moveq #0,d1 ; return failed to add
|
rts
|
rts
|
|
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
TickIRQ:
|
TickIRQ:
|
move.w #$2600,sr ; disable lower level IRQs
|
move.w #$2600,sr ; disable lower level IRQs
|
movem.l d1/d2/a0,-(a7)
|
movem.l d1/d2/a0,-(a7)
|
; ToDo: detect a tick interrupt
|
; ToDo: detect a tick interrupt
|
; move.l PLIC+$00,d1
|
; move.l PLIC+$00,d1
|
; rol.l #8,d1
|
; rol.l #8,d1
|
; cmpi.b #29,d1
|
; cmpi.b #29,d1
|
; bne.s .notTick
|
; bne.s .notTick
|
movec coreno,d1 ; d1 = core number
|
movec coreno,d1 ; d1 = core number
|
cmpi.b #2,d1
|
cmpi.b #2,d1
|
bne.s .0001
|
bne.s .0001
|
move.l #$1D000000,PLIC+$14 ; reset edge sense circuit
|
move.l #$1D000000,PLIC+$14 ; reset edge sense circuit
|
.0001:
|
.0001:
|
move.l TextScr,a0 ; a0 = screen address
|
move.l TextScr,a0 ; a0 = screen address
|
move.l (a0),d2
|
move.l (a0),d2
|
rol.w #8,d2 ; reverse byte order of d2
|
rol.w #8,d2 ; reverse byte order of d2
|
swap d2
|
swap d2
|
rol.w #8,d2
|
rol.w #8,d2
|
addi.b #'0',d1 ; binary to ascii core number
|
addi.b #'0',d1 ; binary to ascii core number
|
add.b d2,d1
|
add.b d2,d1
|
rol.w #8,d1 ; put bytes back in order
|
rol.w #8,d1 ; put bytes back in order
|
swap d1
|
swap d1
|
rol.w #8,d1
|
rol.w #8,d1
|
move.l d1,4(a0) ; update onscreen IRQ flag
|
move.l d1,4(a0) ; update onscreen IRQ flag
|
addi.l #1,(a0) ; flashy colors
|
addi.l #1,(a0) ; flashy colors
|
; addi.l #1,40(a0) ; nice effect
|
; addi.l #1,40(a0) ; nice effect
|
bsr ReceiveMsg
|
bsr ReceiveMsg
|
movem.l (a7)+,d1/d2/a0
|
movem.l (a7)+,d1/d2/a0
|
rte
|
rte
|
;.notTick:
|
;.notTick:
|
; movem.l (a7)+,d1/a0
|
; movem.l (a7)+,d1/a0
|
; rte
|
; rte
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
irq3_rout:
|
irq3_rout:
|
movem.l d0/d1/a0/a1,-(a7)
|
movem.l d0/d1/a0/a1,-(a7)
|
lea InstalledIRQ+8*4*3,a0
|
lea InstalledIRQ+8*4*3,a0
|
bra irq_rout
|
bra irq_rout
|
|
|
irq6_rout:
|
irq6_rout:
|
movem.l d0/d1/a0/a1,-(a7)
|
movem.l d0/d1/a0/a1,-(a7)
|
lea InstalledIRQ+8*4*6,a0
|
lea InstalledIRQ+8*4*6,a0
|
irq_rout:
|
irq_rout:
|
moveq #7,d0
|
moveq #7,d0
|
.nextHandler:
|
.nextHandler:
|
move.l (a0)+,a1
|
move.l (a0)+,a1
|
beq.s .0003
|
beq.s .0003
|
jsr (a1)
|
jsr (a1)
|
tst.l d1 ; was IRQ handled?
|
tst.l d1 ; was IRQ handled?
|
bmi.s .0002 ; first one to return handled quits loop
|
bmi.s .0002 ; first one to return handled quits loop
|
.0003:
|
.0003:
|
dbra d0,.nextHandler
|
dbra d0,.nextHandler
|
.0002:
|
.0002:
|
movem.l (a7)+,d0/d1/a0/a1 ; return
|
movem.l (a7)+,d0/d1/a0/a1 ; return
|
|
|
SpuriousIRQ:
|
SpuriousIRQ:
|
rte
|
rte
|
|
|
; bsr KeybdIRQ
|
; bsr KeybdIRQ
|
; tst.l d1 ; handled by KeybdIRQ?
|
; tst.l d1 ; handled by KeybdIRQ?
|
; bmi.s .0002 ; if yes, go return
|
; bmi.s .0002 ; if yes, go return
|
;.0001:
|
;.0001:
|
; move.l #$1D000000,PLIC+$14 ; reset edge sense circuit
|
; move.l #$1D000000,PLIC+$14 ; reset edge sense circuit
|
; move.l TextScr,a0 ; a0 = screen address
|
; move.l TextScr,a0 ; a0 = screen address
|
; addi.l #1,40(a0) ; update onscreen IRQ flag
|
; addi.l #1,40(a0) ; update onscreen IRQ flag
|
;.0002:
|
;.0002:
|
; movem.l (a7)+,d0/d1/a0/a1 ; return
|
; movem.l (a7)+,d0/d1/a0/a1 ; return
|
; rte
|
; rte
|
|
|
nmi_rout:
|
nmi_rout:
|
movem.l d0/d1/a0,-(a7)
|
movem.l d0/d1/a0,-(a7)
|
move.b #'N',d1
|
move.b #'N',d1
|
bsr DisplayChar
|
bsr DisplayChar
|
movem.l (a7)+,d0/d1/a0 ; return
|
movem.l (a7)+,d0/d1/a0 ; return
|
rte
|
rte
|
|
|
brdisp_trap:
|
brdisp_trap:
|
movem.l d0/d1/d2/d3/d4/d5/d6/d7/a0/a1/a2/a3/a4/a5/a6/a7,Regsave
|
movem.l d0/d1/d2/d3/d4/d5/d6/d7/a0/a1/a2/a3/a4/a5/a6/a7,Regsave
|
move.w (a7)+,Regsave+$40
|
move.w (a7)+,Regsave+$40
|
move.l (a7)+,Regsave+$44
|
move.l (a7)+,Regsave+$44
|
move.l #$40FFC,a7 ; reset stack pointer
|
move.l #$40FFC,a7 ; reset stack pointer
|
move.w #$2500,sr ; enable interrupts
|
move.w #$2500,sr ; enable interrupts
|
lea msg_bad_branch_disp,a1
|
lea msg_bad_branch_disp,a1
|
bsr DisplayString
|
bsr DisplayString
|
bsr DisplaySpace
|
bsr DisplaySpace
|
move.l Regsave+$44,d1 ; exception address
|
move.l Regsave+$44,d1 ; exception address
|
bsr DisplayTetra ; and display it
|
bsr DisplayTetra ; and display it
|
; move.l (sp)+,d1 ; pop format word 68010 mode only
|
; move.l (sp)+,d1 ; pop format word 68010 mode only
|
bra cmdDumpRegs
|
bra cmdDumpRegs
|
|
|
illegal_trap:
|
illegal_trap:
|
addq #2,sp ; get rid of sr
|
addq #2,sp ; get rid of sr
|
move.l (sp)+,d1 ; pop exception address
|
move.l (sp)+,d1 ; pop exception address
|
bsr DisplayTetra ; and display it
|
bsr DisplayTetra ; and display it
|
lea msg_illegal,a1 ; followed by message
|
lea msg_illegal,a1 ; followed by message
|
bsr DisplayString
|
bsr DisplayString
|
.0001:
|
.0001:
|
bra .0001
|
bra .0001
|
bra Monitor
|
bra Monitor
|
|
|
io_irq:
|
io_irq:
|
addq #2,sp
|
addq #2,sp
|
move.l (sp)+,d1
|
move.l (sp)+,d1
|
bsr DisplayTetra
|
bsr DisplayTetra
|
lea msg_io_access,a1
|
lea msg_io_access,a1
|
bsr DisplayString
|
bsr DisplayString
|
bra cmdDumpRegs
|
bra cmdDumpRegs
|
|
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
|
|
msg_start:
|
msg_start:
|
dc.b "Femtiki rf68k Multi-core OS Starting",LF,CR,0
|
dc.b "Femtiki rf68k Multi-core OS Starting",LF,CR,0
|
; dc.b "rf68k System Starting",CR,LF,0
|
; dc.b "rf68k System Starting",CR,LF,0
|
msg_core_start:
|
msg_core_start:
|
dc.b " core starting",CR,LF,0
|
dc.b " core starting",CR,LF,0
|
msg_illegal:
|
msg_illegal:
|
dc.b " illegal opcode",CR,LF,0
|
dc.b " illegal opcode",CR,LF,0
|
msg_bad_branch_disp:
|
msg_bad_branch_disp:
|
dc.b " branch selfref: ",0
|
dc.b " branch selfref: ",0
|
msg_test_done:
|
msg_test_done:
|
dc.b " CPU test done.",0
|
dc.b " CPU test done.",0
|
msg_io_access
|
msg_io_access
|
dc.b " unpermitted access to I/O",0
|
dc.b " unpermitted access to I/O",0
|
|
|
|
|
|
|