URL
https://opencores.org/ocsvn/thor/thor/trunk
Subversion Repositories thor
Compare Revisions
- This comparison shows the changes necessary to convert path
/thor
- from Rev 11 to Rev 12
- ↔ Reverse comparison
Rev 11 → Rev 12
/trunk/software/boot_tb/DisplayChar.asm
23,21 → 23,15
; |
;------------------------------------------------------------------------------ |
; Display a character on the screen device |
; Expects the processor to be in 16 bit mode with 16 bit acc and 16 bit indexes |
;------------------------------------------------------------------------------ |
; |
public DisplayChar: |
; push c1 |
; push pregs |
; push r2 |
; push r3 |
; push r4 |
addui r27,r27,#-40 |
sws c1,[r27] |
sws pregs,8[r27] |
sw r2,16[r27] |
sw r3,24[r27] |
sw r4,32[r27] |
public VBDisplayChar: |
addui r31,r31,#-40 |
sws c1,zs:[r31] |
sws pregs,zs:8[r31] |
sw r2,zs:16[r31] |
sw r3,zs:24[r31] |
sw r4,zs:32[r31] |
ldi r2,#8 |
sc r2,$FFDC0600 |
zxb r1,r1 |
67,26 → 61,22
ldi r1,#1 |
sb r1,EscState |
exitDC: |
; pop r4 |
; pop r3 |
; pop r2 |
; pop pregs |
; pop c1 |
lws c1,[r27] |
lws pregs,8[r27] |
lw r2,16[r27] |
lw r3,24[r27] |
lw r4,32[r27] |
addui r27,r27,#40 |
lws c1,zs:[r31] |
lws pregs,zs:8[r31] |
lw r2,zs:16[r31] |
lw r3,zs:24[r31] |
lw r4,zs:32[r31] |
addui r31,r31,#40 |
rts |
_0003: |
bsr AsciiToScreen |
ldi r4,#10 |
sc r4,$FFDC0600 |
bsr VBAsciiToScreen |
lhu r2,NormAttr |
andi r2,r2,#-1024 |
or r1,r1,r2 |
lcu r3,VideoPos |
lhu r2,Vidptr |
ldi r4,#9 |
sc r4,$FFDC0600 |
sh r1,hs:[r2+r3*4] |
lcu r1,CursorX |
addui r1,r1,#1 |
125,6 → 115,8
br exitDC |
|
processEsc: |
ldi r4,#22 |
sc r4,$FFDC0600 |
lb r2,EscState |
cmpi p0,r2,#-1 |
p0.ne br .0006 |
219,6 → 211,8
br exitDC |
|
doBackSpace: |
ldi r4,#23 |
sc r4,$FFDC0600 |
lc r2,CursorX |
tst p0,r2 |
p0.eq br exitDC ; Can't backspace anymore |
/trunk/software/boot_tb/boot.asm
22,7 → 22,8
; |
; ============================================================================ |
; |
SCRSZ EQU 4096 |
|
SCRSZ EQU 2604 |
CR EQU 0x0D ;ASCII equates |
LF EQU 0x0A |
TAB EQU 0x09 |
51,6 → 52,14
SC_SCROLLLOCK EQU $7E |
SC_CAPSLOCK EQU $58 |
|
E_BadFuncno EQU 1 |
BIOS_E_Timeout EQU 2 |
E_Unsupported EQU 3 |
|
BIOS_STACKTOP EQU $3bf8 |
INT_STACK EQU $37f8 |
VIDEO_BIOS_STACKTOP EQU $3ff8 |
|
IOBASE_ADDR EQU 0xFFD00000 |
IOLMT EQU 0x100000 |
LEDS EQU 0xC0600 |
57,6 → 66,7
TEXTSCR EQU 0x00000 |
TEXTSCR2 EQU 0x10000 |
TEXTREG EQU 0xA0000 |
TEXTREG2 EQU 0xA0040 |
TEXT_COLS EQU 0x0 |
TEXT_ROWS EQU 0x2 |
TEXT_CURPOS EQU 0x16 |
81,7 → 91,30
Textrows EQU $204A |
Textcols EQU $204C |
|
code |
bss |
org $4000 |
|
Milliseconds dw 0 |
|
rxfull EQU 1 |
Uart_ms db 0 |
Uart_txxonoff db 0 |
Uart_rxhead dc 0 |
Uart_rxtail dc 0 |
Uart_rxflow db 0 |
Uart_rxrts db 0 |
Uart_rxdtr db 0 |
Uart_rxxon db 0 |
Uart_foff dc 0 |
Uart_fon dc 0 |
Uart_txrts db 0 |
Uart_txdtr db 0 |
Uart_txxon db 0 |
Uart_rxfifo fill.b 512,0 |
|
NUMWKA fill.b 64,0 |
|
code 17 bits |
org $FFFF8000 |
|
cold_start: |
105,7 → 138,8
; set SS:SP |
mtspr ss,r0 |
ldis ss.lmt,#$4000 |
ldi r27,#$03ff8 ; initialize SP |
ldi r31,#$03ef8 ; initialize kernel SP |
ldi r27,#$03bf8 ; initialize SP |
|
; switch processor to full speed |
stp #$FFFF |
114,14 → 148,14
ldis c12,#0 |
|
; set all vectors to the uninitialized interrupt vector |
mov r4,r0 |
ldis lc,#255 ; 256 vectors to set |
su1: |
ldi r1,#uii_jmp |
mov r2,r4 |
bsr set_vector ; trashes r2,r3 |
addui r4,r4,#1 |
loop su1 |
; mov r4,r0 |
; ldis lc,#255 ; 256 vectors to set |
;su1: |
; ldi r1,#uii_jmp |
; mov r2,r4 |
; bsr set_vector ; trashes r2,r3 |
; addui r4,r4,#1 |
; loop su1 |
|
; setup break vector |
ldi r1,#brk_jmp |
128,20 → 162,36
ldi r2,#0 |
bsr set_vector |
|
; setup Video BIOS vector |
ldi r1,#vb_jmp |
ldi r2,#10 |
bsr set_vector |
|
; setup NMI vector |
ldi r1,#nmi_jmp |
ldi r2,#254 |
bsr set_vector |
|
; setup MSI vector |
sh r0,Milliseconds |
ldi r1,#msi_jmp |
ldi r2,#193 |
bsr set_vector |
|
; setup IRQ vector |
ldi r1,#tms_jmp |
ldi r2,#194 |
bsr set_vector |
|
; setup data bus error vector |
ldi r1,#dbe_jmp |
ldi r2,#251 |
bsr set_vector |
|
; Initialize PIC |
ldi r1,#%00100 ; time slice interrupt is edge sensitive |
ldi r1,#%00111 ; time slice interrupt is edge sensitive |
sh r1,hs:PIC_ES |
ldi r1,#%00101 ; enable time slice interrupt, nmi |
ldi r1,#%00111 ; enable time slice interrupt, msi, nmi |
sh r1,hs:PIC_IE |
|
mov r1,r0 |
151,7 → 201,7
mov r5,r0 |
|
ldi r1,#1 |
sc r1,$FFDC0600 |
sc r1,hs:LEDS |
|
tlbwrreg DMA,r0 ; clear TLB miss registers |
tlbwrreg IMA,r0 |
193,32 → 243,49
; now globally enable interrupts using the RTI instruction, this will also |
; switch to core to application/user mode. |
ldis c14,#j1 ; c14 contains RTI return address |
rti |
sync |
; rti |
j1: |
ldi r1,#2 |
sc r1,$FFDC0600 |
; ldi r1,#$AAAAAAAA |
; sh r1,10 |
; mov r1,r0 |
; lh r1,10 |
; cmpi p0,r1,#$AAAAAAAA |
;p0.ne br bad_ram |
sc r1,hs:LEDS |
sb r0,EscState |
bsr SerialInit |
bsr Debugger |
ldi r2,#msgStartup |
ldis lc,#msgStartupEnd-msgStartup-1 |
j3: |
; lbu r1,[r2] |
; addui r2,r2,#1 |
; tst p0,r1 |
;p0.eq br j2 |
; bsr SerialPutChar |
; loop j3 |
j2: |
bsr VideoInit |
bsr ClearScreen |
bsr ClearScreen2 |
bsr VBClearScreen |
; bsr VBClearScreen2 |
ldi r1,#3 |
sc r1,$FFDC0600 |
bsr HomeCursor |
sc r1,hs:LEDS |
mov r1,r0 |
mov r2,r0 |
ldi r6,#2 ; Set Cursor Pos |
sys #10 |
ldi r1,#6 |
sc r1,$FFDC0600 |
ldi r2,#msgStartup |
bsr DisplayString |
sc r1,hs:LEDS |
bsr alphabet |
ldi r1,#msgStartup |
ldi r6,#$14 |
sys #10 |
; bsr VBDisplayString |
ldi r5,#TEXTSCR |
.0001: |
.0002: |
bsr KeybdGetCharWait |
bsr AsciiToScreen |
or r1,r1,#%000000111_111111111_00_00000000 |
bsr VBDisplayChar |
cmpi p0,r1,#CR |
p0.ne br .0002 |
bsr VBAsciiToScreen |
ori r1,r1,#%000000111_111111111_00_00000000 |
sh r1,hs:[r5] |
addui r5,r5,#4 |
br .0001 |
225,15 → 292,41
|
msgStartup: |
byte "Thor Test System Starting...",CR,LF,0 |
msgStartupEnd: |
|
bad_ram: |
ldi r1,#'B' |
bsr AsciiToScreen |
bsr VBAsciiToScreen |
ori r1,r1,#%011000000_111111111_00_00000000 |
sh r1,hs:TEXTSCR+16 |
.bram1: br .bram1 |
|
;------------------------------------------------------------------------------ |
; alphabet: |
; |
; Display the alphabet across the top of the screen. |
;------------------------------------------------------------------------------ |
|
alphabet: |
addui sp,sp,#-8 |
sws c1,[sp] ; store off return address |
ldi r5,#'A' ; the first char |
ldi r3,#TEXTSCR ; screen address |
ldis lc,#25 ; 25 chars |
.0001: |
mov r1,r5 ; r1 = ascii letter |
bsr VBAsciiToScreen ; r1 = screen char |
lhu r2,NormAttr ; r2 = attribute |
or r1,r1,r2 ; r1 = screen char + attribute |
sh r1,hs:[r3] ; store r1 to screen |
addui r5,r5,#1 ; increment to next char |
addui r3,r3,#4 ; increment to next screen loc |
loop .0001 ; loop back |
lws c1,[sp] ; restore return address |
addui sp,sp,#8 |
rts |
|
;------------------------------------------------------------------------------ |
; Set interrupt vector |
; |
; Parameters: |
255,747 → 348,128
sh r3,zs:12[r2] |
rts |
|
;------------------------------------------------------------------------------ |
;------------------------------------------------------------------------------ |
.include "video.asm" |
.include "keyboard.asm" |
.include "serial.asm" |
.include "debugger.asm" |
|
VideoInit: |
ldi r1,#84 |
sc r1,Textcols |
ldi r1,#31 |
sc r1,Textrows |
ldi r1,#%011000000_111111111_00_00000000 |
sh r1,NormAttr |
ldi r1,#TEXTREG |
sh r1,Vidregs |
ldi r1,#TEXTSCR |
sh r1,Vidptr |
|
ldi r2,#TC1InitData |
ldis lc,#10 ; initialize loop counter ( one less) |
lhu r3,Vidregs |
.0001: |
lvc r1,cs:[r2] |
; sh r1,hs:[r3] |
addui r2,r2,#2 |
addui r3,r3,#4 |
loop .0001 |
rts |
|
;------------------------------------------------------------------------------ |
; Uninitialized interrupt |
;------------------------------------------------------------------------------ |
|
ClearScreen: |
; push c1 |
addui r27,r27,#-8 |
sws c1,[r27] |
ldi r1,#' ' |
bsr AsciiToScreen |
lh r2,NormAttr |
or r2,r2,r1 |
ldis lc,#SCRSZ-1 |
lh r1,Vidptr |
.0001: |
; sh r2,hs:[r1] |
; addui r1,r1,#4 |
; loop .0001 |
ldi r1,#TEXTSCR |
uii_rout: |
sync |
stsh r2,hs:[r1] |
; pop c1 |
lws c1,[r27] |
addui r27,r27,#8 |
rts |
ldi r31,#INT_STACK-16 |
sw r1,[r31] |
sws hs,8[r31] |
|
ClearScreen2: |
ldis lc,#SCRSZ-1 |
ldi r2,#' '|%000011000_111111111_00_00000000; |
ldi r1,#TEXTSCR2 |
sync |
stsh r2,hs:[r1] |
rts |
; set I/O segment |
ldis hs,#$FFD00000 |
|
;------------------------------------------------------------------------------ |
; Scroll the screen upwards. |
;------------------------------------------------------------------------------ |
; update on-screen IRQ live indicator |
ldi r1,#'U'|%011000000_111111111_00_00000000 |
sh r1,hs:TEXTSCR+320 |
|
ScrollUp: |
ldi r3,#0 |
ldi r2,#4096 |
lh r4,Vidptr |
.0001: |
addui r27,r27,#-8 |
sw r2,[r27] |
lc r1,Textcols |
add r3,r3,r1 |
lh r1,[r4+r3*4] |
lw r3,[r27] ; pop r3 |
addui r27,r27,#8 |
sh r1,[r4+r3*4] |
addui r3,r3,#1 |
addui r2,r2,#-1 |
p0.ne br .0001 |
lc r1,Textrows |
addui r1,r1,#-1 |
; restore regs and return |
lw r1,[r31] |
lws hs,8[r31] |
sync |
rti |
|
;------------------------------------------------------------------------------ |
; Blank out a line on the screen. |
; Non-maskable interrupt routine. |
; |
; Parameters: |
; r1 = line number to blank |
; Trashes: |
; r2,r3,r4 |
;------------------------------------------------------------------------------ |
|
BlankLine: |
shli r1,r1,#1 |
lc r3,cs:LineTbl[r1] |
lc r2,Textcols |
lh r1,NormAttr |
ori r1,r1,#$20 |
lh r4,Vidptr |
.0001: |
sh r1,[r4+r3] |
addui r3,r3,#4 |
addui r2,r2,#-1 |
p0.ne br .0001 |
rts |
|
;------------------------------------------------------------------------------ |
; Turn cursor on or off. |
;------------------------------------------------------------------------------ |
|
CursorOn: |
addui r27,r27,#-16 |
sw r1,8[r27] |
sw r2,[r27] |
lh r2,Vidregs |
ldi r1,#$40 |
sh r1,hs:32[r2] |
ldi r1,#$1F |
sh r1,hs:36[r2] |
lw r2,[r27] |
lw r1,8[r27] |
rts |
|
CursorOff: |
addui r27,r27,#-16 |
sw r1,8[r27] |
sw r2,[r27] |
lh r2,Vidregs |
ldi r1,#$20 |
sh r1,hs:32[r2] |
mov r1,r0 |
sh r1,hs:36[r2] |
lw r2,[r27] |
lw r1,8[r27] |
rts |
|
;------------------------------------------------------------------------------ |
; Get the number of text rows and columns from the video controller. |
;------------------------------------------------------------------------------ |
|
GetTextRowscols: |
lh r2,Vidregs |
lvc r1,hs:0[r2] |
sc r1,Textcols |
lvc r1,hs:4[r2] |
sc r1,Textrows |
rts |
|
;------------------------------------------------------------------------------ |
; Set cursor to home position. |
;------------------------------------------------------------------------------ |
|
HomeCursor: |
sc r0,CursorX |
sc r0,CursorY |
sc r0,VideoPos |
ldi r1,#4 |
sc r1,$FFDC0600 |
|
;------------------------------------------------------------------------------ |
; Synchronize the absolute video position with the cursor co-ordinates. |
; Does not modify any predicates. |
;------------------------------------------------------------------------------ |
|
SyncVideoPos: |
addui r27,r27,#-24 |
sw r1,16[r27] ; save off some working regs |
sw r2,8[r27] |
sw r3,[r27] |
ldi r1,#5 |
sc r1,$FFDC0600 |
lc r2,CursorY |
shli r2,r2,#1 |
lcu r1,cs:LineTbl[r2] |
shrui r1,r1,#2 |
lc r2,CursorX |
addu r1,r1,r2 |
sc r1,VideoPos |
lh r3,Vidregs ; r3 = address of video registers |
sh r1,hs:44[r3] ; Update the position in the text controller |
lw r3,[r27] ; restore the regs |
lw r2,8[r27] |
lw r1,16[r27] |
addui r27,r27,#24 |
rts |
|
align 2 |
LineTbl: |
dc 0 |
dc TEXTCOLS*4 |
dc TEXTCOLS*8 |
dc TEXTCOLS*12 |
dc TEXTCOLS*16 |
dc TEXTCOLS*20 |
dc TEXTCOLS*24 |
dc TEXTCOLS*28 |
dc TEXTCOLS*32 |
dc TEXTCOLS*36 |
dc TEXTCOLS*40 |
dc TEXTCOLS*44 |
dc TEXTCOLS*48 |
dc TEXTCOLS*52 |
dc TEXTCOLS*56 |
dc TEXTCOLS*60 |
dc TEXTCOLS*64 |
dc TEXTCOLS*68 |
dc TEXTCOLS*72 |
dc TEXTCOLS*76 |
dc TEXTCOLS*80 |
dc TEXTCOLS*84 |
dc TEXTCOLS*88 |
dc TEXTCOLS*92 |
dc TEXTCOLS*96 |
dc TEXTCOLS*100 |
dc TEXTCOLS*104 |
dc TEXTCOLS*108 |
dc TEXTCOLS*112 |
dc TEXTCOLS*116 |
dc TEXTCOLS*120 |
dc TEXTCOLS*124 |
|
TC1InitData: |
dc 84 ; #columns |
dc 31 ; #rows |
dc 64 ; window left |
dc 17 ; window top |
dc 7 ; max scan line |
dc $21 ; pixel size (hhhhvvvv) |
dc $1FF ; transparent color |
dc $40 ; cursor blink, start line |
dc 31 ; cursor end |
dc 0 ; start address |
dc 0 ; cursor position |
TC2InitData: |
dc 40 |
dc 25 |
dc 376 |
dc 64 ; window top |
dc 7 |
dc $10 |
dc $1FF |
dc $40 |
dc 31 |
dc 0 |
dc 0 |
|
;------------------------------------------------------------------------------ |
; Convert Ascii character to screen character. |
;------------------------------------------------------------------------------ |
|
AsciiToScreen: |
zxb r1,r1 |
cmp p0,r1,#' ' |
p0.le ori r1,r1,#$100 |
p0.le br .0003 |
cmp p0,r1,#$5B ; special test for [ ] characters |
p0.ne br .0001 |
ldi r1,#$11B |
rts |
.0001: |
cmp p0,r1,#$5D |
p0.ne br .0002 |
ldi r1,#$11D |
rts |
.0002: |
ori r1,r1,#$100 |
biti p0,r1,#$20 ; if bit 5 isn't set |
p0.eq br .0003 |
biti p0,r1,#$40 ; or bit 6 isn't set |
p0.ne andi r1,r1,#$19F |
.0003: |
rts |
|
;------------------------------------------------------------------------------ |
; Convert screen character to ascii character |
;------------------------------------------------------------------------------ |
; |
ScreenToAscii: |
zxb r1,r1 |
cmpi p0,r1,#27 |
p0.le addi r1,r1,#$60 |
rts |
nmi_rout: |
sync |
ldi r31,#INT_STACK-16 |
sw r1,[r31] |
sws hs,8[r31] |
|
.include "DisplayChar.asm" |
; set I/O segment |
ldis hs,#$FFD00000 |
|
;------------------------------------------------------------------------------ |
; Display a string on the screen. |
;------------------------------------------------------------------------------ |
ldi r1,#16 |
sc r1,hs:LEDS |
|
DisplayString: |
ldi r1,#7 |
sc r1,$FFDC0600 |
ldis lc,#$FFF |
.0001: |
lbu r1,[r2] |
tst p2,r1 |
p2.eq br .0002 |
bsr DisplayChar |
addui r2,r2,#1 |
loop .0001 |
.0002: |
rts |
; reset the edge sense circuit to re-enable interrupts |
ldi r1,#0 |
sh r1,hs:PIC_ESR |
|
KeybdGetCharWait: |
ldi r1,#-1 |
sb r1,KeybdWaitFlag |
br KeybdGetChar |
; update on-screen IRQ live indicator |
lh r1,hs:TEXTSCR+324 |
addui r1,r1,#1 |
sh r1,hs:TEXTSCR+324 |
|
KeybdGetCharNoWait: |
sb r0,KeybdWaitFlag |
br KeybdGetChar |
; restore regs and return |
lw r1,[r31] |
lws hs,8[r31] |
sync |
rti |
|
; Wait for a keyboard character to be available |
; Returns (-1) if no key available |
; Return key >= 0 if key is available |
; |
; |
KeybdGetChar: |
KeybdGetChar1: |
addui r27,r27,#-16 |
sws c1,8[r27] ; save off link register |
sw r2,[r27] |
.0002: |
.0003: |
memsb |
lvb r1,hs:KEYBD+1 ; check MSB of keyboard status reg. |
biti p0,r1,#$80 |
p0.ne br .0006 |
lb r1,KeybdWaitFlag |
tst p0,r1 |
p0.lt br .0003 |
lw r2,[r27] |
lws c1,8[r27] |
addui r27,r27,#16 |
rts |
.0006: |
memsb |
lvb r1,hs:KEYBD ; get scan code value |
memdb |
zxb r1,r1 ; make unsigned |
sb r0,hs:KEYBD+1 ; clear read flag |
ldi r3,#3 |
sc r3,$FFDC0600 |
.0001: |
cmp p0,r1,#SC_KEYUP ; keyup scan code ? |
p0.eq br .doKeyup |
cmp p0,r1,#SC_EXTEND; extended scan code ? |
p0.eq br .doExtend |
cmp p0,r1,#$14 ; control ? |
p0.eq br .doCtrl |
cmp p0,r1,#$12 ; left shift |
p0.eq br .doShift |
cmp p0,r1,#$59 ; right shift |
p0.eq br .doShift |
cmp p0,r1,#SC_NUMLOCK |
p0.eq br .doNumLock |
cmp p0,r1,#SC_CAPSLOCK |
p0.eq br .doCapsLock |
cmp p0,r1,#SC_SCROLLLOCK |
p0.eq br .doScrollLock |
lb r2,KeyState1 |
andi r2,r2,#1 |
cmp p0,r2,#0 |
p0.ne br .0003 |
lb r2,KeyState2 ; Is extended code ? |
andi r2,r2,#$80 |
p0.eq br .0010 |
lb r2,KeyState2 |
andi r2,r2,#$7F |
sb r2,KeyState2 |
sb r0,KeyState1 ; clear keyup |
andi r1,r1,#$7F |
lbu r1,cs:keybdExtendedCodes[r1] |
br .0008 |
.0010: |
ldi r3,#4 |
sc r3,$FFDC0600 |
lb r2,KeyState2 |
biti p0,r2,#4 ; Is Cntrl down ? |
p0.eq br .0009 |
andi r1,r1,#$7F |
lbu r1,cs:keybdControlCodes[r1] |
br .0008 |
.0009: |
lb r2,KeyState2 |
biti p0,r2,#1 ; Is shift down ? |
p0.eq br .0007 |
andi r1,r1,#$FF |
lbu r1,cs:shiftedScanCodes[r1] |
br .0008 |
.0007: |
andi r1,r1,#$FF |
lbu r1,cs:unshiftedScanCodes[r1] |
.0008: |
ldi r3,#5 |
sc r3,$FFDC0600 |
lw r2,[r27] |
lws c1,8[r27] |
addui r27,r27,#16 |
rts |
|
.doKeyup: |
lb r2,KeyState1 |
ori r2,r2,#1 |
sb r2,KeyState1 |
br .0003 |
.doExtend: |
lb r2,KeyState2 |
ori r2,r2,#$80 |
sb r2,KeyState2 |
br .0003 |
.doCtrl: |
lb r2,KeyState1 |
biti p0,r2,#1 |
p0.eq br .0004 |
lbu r2,KeyState2 |
andi r2,r2,#~4 |
sb r2,KeyState2 |
br .0003 |
.0004: |
lbu r2,KeyState2 |
ori r2,r2,#4 |
sb r2,KeyState2 |
br .0003 |
.doShift: |
lb r2,KeyState1 |
biti p0,r2,#1 |
p0.eq br .0005 |
lbu r2,KeyState2 |
andi r2,r2,#~1 |
sb r2,KeyState2 |
br .0003 |
.0005: |
lbu r2,KeyState2 |
ori r2,r2,#1 |
sb r2,KeyState2 |
br .0003 |
.doNumLock: |
lbu r2,KeyState2 |
eori r2,r2,#16 |
sb r2,KeyState2 |
bsr KeybdSetLEDStatus |
br .0003 |
.doCapsLock: |
lbu r2,KeyState2 |
eori r2,r2,#32 |
sb r2,KeyState2 |
bsr KeybdSetLEDStatus |
br .0003 |
.doScrollLock: |
lbu r2,KeyState2 |
eori r2,r2,#64 |
sb r2,KeyState2 |
bsr KeybdSetLEDStatus |
br .0003 |
|
;------------------------------------------------------------------------------ |
; Set the keyboard LED status leds. |
; Trashes r1, p0 |
;------------------------------------------------------------------------------ |
|
KeybdSetLEDStatus: |
addui r27,r27,#-8 |
sws c1,[r27] |
sb r0,KeybdLEDs |
lb r1,KeyState2 |
biti p0,r1,#16 |
p0.ne lb r1,KeybdLEDs ; set bit 1 for Num lock, 0 for scrolllock , 2 for caps lock |
p0.ne ori r1,r1,#2 |
p0.ne sb r1,KeybdLEDs |
lb r1,KeyState2 |
biti p0,r1,#32 |
p0.ne lb r1,KeybdLEDs |
p0.ne ori r1,r1,#4 |
p0.ne sb r1,KeybdLEDs |
lb r1,KeyState2 |
biti p0,r1,#64 |
p0.ne lb r1,KeybdLEDs |
p0.ne ori r1,r1,#1 |
p0.ne sb r1,KeybdLEDs |
ldi r1,#$ED |
sb r1,hs:KEYBD ; set status LEDs command |
bsr KeybdWaitTx |
bsr KeybdRecvByte |
cmpi p0,r1,#$FA |
lb r1,KeybdLEDs |
sb r1,hs:KEYBD |
bsr KeybdWaitTx |
bsr KeybdRecvByte |
lws c1,[r27] |
addui r27,r27,#8 |
rts |
|
;------------------------------------------------------------------------------ |
; Receive a byte from the keyboard, used after a command is sent to the |
; keyboard in order to wait for a response. |
; Millisecond (1024 Hz) interrupt routine. |
; |
; Returns: |
; r1 >= 0 if a scancode is available |
; r1 = -1 on timeout |
;------------------------------------------------------------------------------ |
; |
KeybdRecvByte: |
addui r27,r27,#-16 |
sws c1,8[r27] |
sw r3,[r27] |
ldi r3,#20 ; wait up to .2s |
.0003: |
bsr KeybdWaitBusy |
lb r1,hs:KEYBD+1 ; wait for response from keyboard |
biti p0,r1,#$80 ; is input buffer full ? |
p0.ne br .0004 ; yes, branch |
bsr Wait10ms ; wait a bit |
addui r3,r3,#-1 |
tst p0,r3 |
p0.ne br .0003 ; go back and try again |
lw r3,[r27] ; timeout |
lws c1,8[r27] |
addui r27,r27,#16 |
ldi r1,#-1 |
rts |
.0004: |
lvb r1,hs:KEYBD ; get scancode |
zxb r1,r1 ; convert to unsigned char |
sb r0,hs:KEYBD+1 ; clear recieve state |
lw r3,[r27] |
lws c1,8[r27] |
addui r27,r27,#16 |
rts ; return char in r1 |
msi_rout: |
sync |
ldi r31,#INT_STACK-16 |
sw r1,[r31] |
sws hs,8[r31] |
|
;------------------------------------------------------------------------------ |
; Wait until the keyboard isn't busy anymore |
; Wait until the keyboard transmit is complete |
; Returns: |
; r1 >= 0 if successful |
; r1 < 0 if timed out |
;------------------------------------------------------------------------------ |
; |
KeybdWaitBusy: ; alias for KeybdWaitTx |
KeybdWaitTx: |
addui r27,r27,#-16 |
sws c1,8[r27] |
sw r3,[r27] |
ldi r3,#10 ; wait a max of .1s |
.0001: |
lvb r1,hs:KEYBD+1 |
biti p0,r1,#$40 ; check for transmit busy bit |
p0.eq br .0002 ; branch if bit clear |
bsr Wait10ms ; delay a little bit |
addui r3,r3,#-1 ; go back and try again |
tst p0,r3 |
p0.ne br .0001 |
lw r3,[r27] ; timed out |
lws c1,8[r27] |
addui r27,r27,#16 |
ldi r1,#-1 ; return -1 |
rts |
.0002: |
lw r3,[r27] ; wait complete, return |
lws c1,8[r27] ; restore return address |
ldi r1,#0 ; return 0 for okay |
addui r27,r27,#16 |
rts |
; set I/O segment |
ldis hs,#$FFD00000 |
|
;------------------------------------------------------------------------------ |
; Delay for about 10 ms. |
;------------------------------------------------------------------------------ |
ldi r1,#24 |
sc r1,hs:LEDS |
|
Wait10ms: |
addui r27,r27,#-16 |
sw r1,8[r27] |
sw r2,[r27] |
mfspr r1,tick |
addui r1,r1,#250000 ; 10ms at 25 MHz |
.0001: |
mfspr r2,tick |
cmp p0,r2,r1 |
p0.lt br .0001 |
lw r2,[r27] |
lw r1,8[r27] |
addui r27,r27,#16 |
rts |
; reset the edge sense circuit to re-enable interrupts |
ldi r1,#1 |
sh r1,hs:PIC_ESR |
|
;-------------------------------------------------------------------------- |
; PS2 scan codes to ascii conversion tables. |
;-------------------------------------------------------------------------- |
; |
unshiftedScanCodes: |
byte $2e,$a9,$2e,$a5,$a3,$a1,$a2,$ac |
byte $2e,$aa,$a8,$a6,$a4,$09,$60,$2e |
byte $2e,$2e,$2e,$2e,$2e,$71,$31,$2e |
byte $2e,$2e,$7a,$73,$61,$77,$32,$2e |
byte $2e,$63,$78,$64,$65,$34,$33,$2e |
byte $2e,$20,$76,$66,$74,$72,$35,$2e |
byte $2e,$6e,$62,$68,$67,$79,$36,$2e |
byte $2e,$2e,$6d,$6a,$75,$37,$38,$2e |
byte $2e,$2c,$6b,$69,$6f,$30,$39,$2e |
byte $2e,$2e,$2f,$6c,$3b,$70,$2d,$2e |
byte $2e,$2e,$27,$2e,$5b,$3d,$2e,$2e |
byte $ad,$2e,$0d,$5d,$2e,$5c,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e |
byte $2e,$95,$2e,$93,$94,$2e,$2e,$2e |
byte $98,$7f,$92,$2e,$91,$90,$1b,$af |
byte $ab,$2e,$97,$2e,$2e,$96,$ae,$2e |
; update milliseconds |
lh r1,Milliseconds |
addui r1,r1,#1 |
sh r1,Milliseconds |
|
byte $2e,$2e,$2e,$a7,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$fa,$2e,$2e,$2e,$2e,$2e |
|
shiftedScanCodes: |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$51,$21,$2e |
byte $2e,$2e,$5a,$53,$41,$57,$40,$2e |
byte $2e,$43,$58,$44,$45,$24,$23,$2e |
byte $2e,$20,$56,$46,$54,$52,$25,$2e |
byte $2e,$4e,$42,$48,$47,$59,$5e,$2e |
byte $2e,$2e,$4d,$4a,$55,$26,$2a,$2e |
byte $2e,$3c,$4b,$49,$4f,$29,$28,$2e |
byte $2e,$3e,$3f,$4c,$3a,$50,$5f,$2e |
byte $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e |
byte $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
|
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
|
; control |
keybdControlCodes: |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$11,$21,$2e |
byte $2e,$2e,$1a,$13,$01,$17,$40,$2e |
byte $2e,$03,$18,$04,$05,$24,$23,$2e |
byte $2e,$20,$16,$06,$14,$12,$25,$2e |
byte $2e,$0e,$02,$08,$07,$19,$5e,$2e |
byte $2e,$2e,$0d,$0a,$15,$26,$2a,$2e |
byte $2e,$3c,$0b,$09,$0f,$29,$28,$2e |
byte $2e,$3e,$3f,$0c,$3a,$10,$5f,$2e |
byte $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e |
byte $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
|
keybdExtendedCodes: |
byte $2e,$2e,$2e,$2e,$a3,$a1,$a2,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e |
byte $2e,$95,$2e,$93,$94,$2e,$2e,$2e |
byte $98,$99,$92,$2e,$91,$90,$2e,$2e |
byte $2e,$2e,$97,$2e,$2e,$96,$2e,$2e |
|
|
;------------------------------------------------------------------------------ |
; Uninitialized interrupt |
;------------------------------------------------------------------------------ |
uii_rout: |
addui r27,r27,#-16 |
sw r1,[r27] |
sws hs,8[r27] |
|
; set I/O segment |
ldis hs,#$FFD00000 |
|
; update on-screen IRQ live indicator |
ldi r1,#'U'|%011000000_111111111_00_00000000 |
sh r1,hs:TEXTSCR+320 |
|
; restore regs and return |
lw r1,[r27] |
lws hs,8[r27] |
addui r27,r27,#16 |
lw r1,[r31] |
lws hs,8[r31] |
sync |
rti |
|
;------------------------------------------------------------------------------ |
; Non-maskable interrupt routine. |
; Time Slice IRQ routine. |
; |
; |
;------------------------------------------------------------------------------ |
; |
nmi_rout: |
addui r27,r27,#-16 |
sw r1,[r27] |
sws hs,8[r27] |
tms_rout: |
sync |
ldi r31,#INT_STACK-16 |
sw r1,[r31] |
sws hs,8[r31] |
|
; set I/O segment |
ldis hs,#$FFD00000 |
|
ldi r1,#32 |
sc r1,hs:LEDS |
|
; reset the edge sense circuit to re-enable interrupts |
ldi r1,#0 |
ldi r1,#2 |
sh r1,hs:PIC_ESR |
|
; update on-screen IRQ live indicator |
lh r1,hs:TEXTSCR+324 |
lh r1,hs:TEXTSCR+328 |
addui r1,r1,#1 |
sh r1,hs:TEXTSCR+324 |
sh r1,hs:TEXTSCR+328 |
|
; restore regs and return |
lw r1,[r27] |
lws hs,8[r27] |
addui r27,r27,#16 |
lw r1,[r31] |
lws hs,8[r31] |
sync |
rti |
|
;------------------------------------------------------------------------------ |
1004,27 → 478,37
; |
;------------------------------------------------------------------------------ |
; |
tms_rout: |
addui r27,r27,#-16 |
sw r1,[r27] |
sws hs,8[r27] |
dbe_rout: |
sync |
ldi r31,#INT_STACK-24 |
sw r1,[r31] |
sws hs,8[r31] |
sw r5,16[r31] |
|
; set I/O segment |
ldis hs,#$FFD00000 |
|
; reset the edge sense circuit to re-enable interrupts |
ldi r1,#2 |
sh r1,hs:PIC_ESR |
ldi r1,#64 |
sc r1,hs:LEDS |
|
; update on-screen IRQ live indicator |
lh r1,hs:TEXTSCR+328 |
addui r1,r1,#1 |
sh r1,hs:TEXTSCR+328 |
; reset the bus error circuit to re-enable interrupts |
sh r0,hs:$CFFE0 |
|
; update on-screen DBE indicator |
ldi r1,'D'|%011000000_000000110_0000000000 |
sh r1,hs:TEXTSCR+320 |
|
; Advance the program to the next address |
mfspr r5,c14 |
bsr DBGGetInsnLength |
addu r1,r5,r1 |
mtspr c14,r1 |
|
; restore regs and return |
lw r1,[r27] |
lws hs,8[r27] |
addui r27,r27,#16 |
lw r1,[r31] |
lws hs,8[r31] |
lw r5,16[r31] |
sync |
rti |
|
;------------------------------------------------------------------------------ |
1035,18 → 519,23
;------------------------------------------------------------------------------ |
; |
brk_rout: |
sync |
ldi r1,#'B' |
bsr AsciiToScreen |
bsr VBAsciiToScreen |
ori r1,r1,#|%011000000_111111111_00_00000000 |
sh r1,$FFD00000 |
sh r1,zs:$FFD10140 |
ldi r1,#'R' |
bsr AsciiToScreen |
bsr VBAsciiToScreen |
ori r1,r1,#|%011000000_111111111_00_00000000 |
sh r1,$FFD00004 |
sh r1,zs:$FFD10144 |
ldi r1,#'K' |
bsr AsciiToScreen |
bsr VBAsciiToScreen |
ori r1,r1,#|%011000000_111111111_00_00000000 |
sh r1,$FFD00008 |
sh r1,zs:$FFD10148 |
ldi r2,#10 |
ldi r6,#0 |
mfspr r5,c13 |
bsr DisplayAddr |
brk_lockup: |
br brk_lockup[c0] |
|
1059,9 → 548,17
align 4 |
tms_jmp: jmp tms_rout[c0] |
align 4 |
msi_jmp: jmp msi_rout[c0] |
align 4 |
nmi_jmp: jmp nmi_rout[c0] |
align 4 |
uii_jmp: jmp uii_rout[c0] |
align 4 |
vb_jmp: jmp VideoBIOSCall[c0] |
align 4 |
ser_jmp: jmp SerialIRQ[c0] |
align 4 |
dbe_jmp: jmp dbe_rout[c0] |
|
;------------------------------------------------------------------------------ |
; Reset Point |
1070,3 → 567,5
org $FFFFEFF0 |
jmp cold_start[C15] |
|
extern my_main : 24 |
|
/trunk/software/a64/bin/a64.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream