URL
https://opencores.org/ocsvn/raptor64/raptor64/trunk
Subversion Repositories raptor64
[/] [raptor64/] [trunk/] [software/] [sample code/] [bootrom.s] - Rev 27
Go to most recent revision | Compare with Previous | Blame | View Log
; ============================================================================ ; (C) 2012 Robert Finch ; All Rights Reserved. ; robfinch<remove>@opencores.org ; ; This source file is free software: you can redistribute it and/or modify ; it under the terms of the GNU Lesser General Public License as published ; by the Free Software Foundation, either version 3 of the License, or ; (at your option) any later version. ; ; This source file is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program. If not, see <http://www.gnu.org/licenses/>. ; ; ============================================================================ ; CR EQU 0x0D ;ASCII equates LF EQU 0x0A TAB EQU 0x09 CTRLC EQU 0x03 CTRLH EQU 0x08 CTRLS EQU 0x13 CTRLX EQU 0x18 STACKTOP EQU 0xFFFF_FFFF_FFFE_FFF8 Milliseconds EQU 0x400 Lastloc EQU 0x408 ScreenColor EQU 0x414 CursorRow EQU 0x416 CursorCol EQU 0x418 KeybdEcho EQU 0x41A KeybdBuffer EQU 0x440 KeybdHead EQU 0x450 KeybdTail EQU 0x451 TEXTSCR EQU 0xFFFF_FFFF_FFD0_0000 COLORSCR EQU 0xFFFF_FFFF_FFD1_0000 TEXTREG EQU 0xFFFFFFFF_FFDA0000 TEXT_COLS EQU 0x0 TEXT_ROWS EQU 0x2 TEXT_CURPOS EQU 0x16 KEYBD EQU 0xFFFF_FFFF_FFDC_0000 KEYBDCLR EQU 0xFFFF_FFFF_FFDC_0002 UART EQU 0xFFFF_FFFF_FFDC_0A00 UART_LS EQU 0xFFFF_FFFF_FFDC_0A01 PIC EQU 0xFFFF_FFFF_FFDC_0FF0 PSG EQU 0xFFFF_FFFF_FFD5_0000 AC97 EQU 0xFFFF_FFFF_FFDC_1000 BOOT_STACK EQU 0xFFFF_FFFF_FFFE_FFF8 BITMAPSCR EQU 0x00000001_00200000 txempty EQU 0x40 rxfull EQU 0x01 ; org 0x070 ; iret ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; code org 0xFFFF_FFFF_FFFF_E800 ; jump table ; jmp SerialGetChar jmp SerialPutChar jmp SetKeyboardEcho jmp KeybdCheckForKey jmp KeybdGetChar jmp DisplayChar jmp DisplayString start: ; lea MSGRAM,a1 ; jsr DisplayString ColdStart: icache_on ; turn on the ICache dcache_on ; turn on the DCache setlo sp,#STACKTOP ; top of stack call KeybdInit call PICInit cli ; enable interrupts setlo r3,#0xCE ; blue on blue sc r3,ScreenColor lc r3,0x414 setlo r3,#32 sc r3,0x416 ; we do a store, then a load through the dcache lc r2,0x416 ; lc r2,0x416 ; beq r2,r3,dcokay dcache_off ; data cache failed dcokay: lc r3,ScreenColor call ClearScreen call ClearBmpScreen sc r0,CursorRow sc r0,CursorCol setlo r1,#<MSGSTART sethi r1,#>MSGSTART call DisplayString ; call SetupAC97 ; and Beep ; Allow some other contexts to start up ; equal processing time for sixteen contexts ; mfspr r1,AXC ; which context am I bne r1,r0,j4 setlo r1,#0x76543210 mtspr EP0,r1 mtspr EP2,r1 setlo r1,#0xFEDCBA98 mtspr EP1,r1 mtspr EP3,r1 j4: jmp Monitor bra j4 ; call ramtest ;----------------------------------------- ; Hello World! ;----------------------------------------- HelloWorld: subui r30,r30,#24 sm [r30],r1/r2/r31 setlo r2,#MSG j3: lb r1,[r2] beq r1,r0,j2 call SerialPutChar addui r2,r2,#1 bra j3 j2: lm [r30],r1/r2/r31 ret #24 align 16 MSG: DB "Hello World!",0,0,0,0 align 16 MSGSTART: db "Raptor64 system starting....",CR,LF,0,0 align 16 ;---------------------------------------------------------- ; Initialize programmable interrupt controller (PIC) ; 0 = nmi ; 1 = keyboard reset ; 2 = 1000Hz pulse (cursor flash) ; 15 = keyboard char ;---------------------------------------------------------- PICInit: setlo r1,#0x8007 ; enable nmi,kbd_rst,and kbd_irq outc r1,PIC+2 ret ;----------------------------------------- ; Get character from serial port ;----------------------------------------- SerialGetChar: subui r30,r30,#8 sw r3,[r30] setlo r1,#UART sgc1: inb r3,1[r1] ; uart status andi r3,r3,#rxfull ; is there a char available ? beq r3,r0,sgc1 lw r3,[r30] inb r1,[r1] ret #8 ;----------------------------------------- ; Put character to serial port ;----------------------------------------- SerialPutChar: subui r30,r30,#16 sw r2,8[r30] sw r3,[r30] setlo r3,#UART spc1: inb r2,1[r3] ; uart status andi r2,r2,#txempty ; is there a char available ? beq r2,r0,spc1 outb r1,[r3] lw r3,[r30] lw r2,8[r30] ret #16 ;============================================================================== ; Keyboard ;============================================================================== ;------------------------------------------------------------------------------ ; Initialize keyboard ;------------------------------------------------------------------------------ KeybdInit: sb r0,KeybdHead sb r0,KeybdTail setlo r1,#1 ; turn on keyboard echo sb r1,KeybdEcho ret ;------------------------------------------------------------------------------ ; Normal keyboard interrupt, the lowest priority interrupt in the system. ; Grab the character from the keyboard device and store it in a buffer. ;------------------------------------------------------------------------------ ; KeybdIRQ: subui sp,sp,#24 sm [sp],r1/r2/r3 lbu r1,KeybdHead andi r1,r1,#0x0f ; r1 = index into buffer setlo r3,#<KeybdBuffer sethi r3,#>KeybdBuffer KeybdIRQa: inch r2,KEYBD ; get keyboard character outc r0,KEYBD+2 ; clear keyboard strobe (turns off the IRQ) sb r2,[r3+r1] ; store character in buffer addui r1,r1,#1 ; increment head index andi r1,r1,#0x0f sb r1,KeybdHead KeybdIRQb: lbu r2,KeybdTail ; check to see if we've collided bne r1,r2,KeybdIRQc ; with the tail addui r2,r2,#1 ; if so, increment the tail index andi r2,r2,#0x0f ; the oldest character will be lost sb r2,KeybdTail KeybdIRQc: lm [sp],r1/r2/r3 addui sp,sp,#24 ret ;------------------------------------------------------------------------------ ; r1 0=echo off, non-zero = echo on ;------------------------------------------------------------------------------ SetKeyboardEcho: sb r1,KeybdEcho ret ;----------------------------------------- ; Get character from keyboard buffer ;----------------------------------------- KeybdGetChar: subui sp,sp,#16 sm [sp],r2/r3 lbu r2,KeybdTail lbu r1,KeybdHead beq r1,r2,nochar setlo r3,#KeybdBuffer lbu r1,[r3+r2] addui r2,r2,#1 andi r2,r2,#0x0f sb r2,KeybdTail lm [sp],r2/r3 ret #16 nochar: setlo r1,#-1 lm [sp],r2/r3 ret #16 ;------------------------------------------------------------------------------ ; Check if there is a keyboard character available in the keyboard buffer. ;------------------------------------------------------------------------------ ; KeybdCheckForKey: lbu r1,KeybdTail lbu r2,KeybdHead beq r1,r2,kck1 setlo r1,#1 ret kck1: xor r1,r1,r1 ; return zero ret ;------------------------------------------------------------------------------ ; Check if there is a keyboard character available. If so return true (1) ; otherwise return false (0) in r1. ;------------------------------------------------------------------------------ ; KeybdCheckForKeyDirect: inch r1,KEYBD bge r1,r0,cfkd1 setlo r1,#1 ret cfkd1: xor r1,r1,r1 ; return 0 in r1 ret ;------------------------------------------------------------------------------ ; Get character directly from keyboard. This routine blocks until a key is ; available. ;------------------------------------------------------------------------------ ; KeybdGetCharDirect: subui sp,sp,#16 sm [sp],r2/r31 setlo r2,KEYBD kgc1: inch r1,KEYBD bge r1,r0,kgc1 outc r0,KEYBD+2 ; clear keyboard strobe andi r1,r1,#0xff ; remove strobe bit lb r2,KeybdEcho ; is keyboard echo on ? beq r2,r0,gk1 bnei r1,#'\r',gk2 ; convert CR keystroke into CRLF call CRLF bra gk1 gk2: call DisplayChar gk1: lm [sp],r2/r31 ret #16 ;============================================================================== ;============================================================================== ;------------------------------------------------------------------------------ ; 1000 Hz interrupt ; - takes care of "flashing" the cursor ;------------------------------------------------------------------------------ ; Pulse1000: subui sp,sp,#24 sm [sp],r1/r2/lr lw r1,Milliseconds addui r1,r1,#1 sw r1,Milliseconds setlo r2,TEXTSCR lc r1,222[r2] addui r1,r1,#1 sc r1,222[r2] lc r0,0xFFFF_FFFF_FFFF_0000 ; clear interrupt lw r1,Milliseconds andi r1,r1,#0x7f bnei r1,#64,p10001 call FlashCursor p10001: lm [sp],r1/r2/lr ret #24 ;------------------------------------------------------------------------------ ; Flash Cursor ;------------------------------------------------------------------------------ ; FlashCursor: subui sp,sp,#32 sm [sp],r1/r2/r3/r31 call CalcScreenLoc addui r1,r1,#0x10000 ; causes screen colors to flip around lc r2,[r1] addui r2,r2,#1 sc r2,[r1] lw r2,Lastloc beq r1,r2,flshcrsr1 ; restore the screen colors of the previous cursor location lc r3,ScreenColor sc r3,[r2] sw r1,Lastloc flshcrsr1: lm [sp],r1/r2/r3/r31 ret #32 ;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------ ClearBmpScreen: subui sp,sp,#40 sm [sp],r1/r2/r3/r4/r31 setlo r1,#1364 ; calc number to clear setlo r2,#768 mulu r2,r1,r2 ; r2 = # pixels to clear or r4,r0,r2 ; r4 = # pixels to clear setlo r1,#0x29292929 ; setlo r3,#<BITMAPSCR ; screen address sethi r3,#>BITMAPSCR csj4: sh r1,[r3] addui r3,r3,#4 loop r2,csj4 lm [sp],r1/r2/r3/r4/r31 ret #40 ;------------------------------------------------------------------------------ ; Clear the screen and the screen color memory ; We clear the screen to give a visual indication that the system ; is working at all. ;------------------------------------------------------------------------------ ; ClearScreen: subui sp,sp,#40 sm [sp],r1/r2/r3/r4/r31 setlo r3,#TEXTREG lc r1,TEXT_COLS[r3] ; calc number to clear lc r2,TEXT_ROWS[r3] mulu r2,r1,r2 ; r2 = # chars to clear setlo r1,#32 ; space char lc r4,ScreenColor call AsciiToScreen setlo r3,#TEXTSCR ; text screen address csj4: sc r1,[r3] sc r4,0x10000[r3] ; color screen is 0x10000 higher addu r3,r3,#2 loop r2,csj4 lm [sp],r1/r2/r3/r4/r31 ret #40 ;------------------------------------------------------------------------------ ; Scroll text on the screen upwards ;------------------------------------------------------------------------------ ; ScrollUp: subui sp,sp,#40 sm [sp],r1/r2/r3/r4/r31 setlo r3,#TEXTREG lc r1,TEXT_COLS[r3] ; r1 = # text columns lc r2,TEXT_ROWS[r3] mulu r2,r1,r2 ; calc number of chars to scroll subu r2,r2,r1 ; one less row setlo r3,#TEXTSCR scrup1: lc r4,[r3+r1] ; indexed addressing example sc r4,[r3] addui r3,r3,#2 loop r2,scrup1 setlo r3,#TEXTREG lc r1,TEXT_ROWS[r3] subui r1,r1,#1 call BlankLine lm [sp],r1/r2/r3/r4/r31 ret #40 ;------------------------------------------------------------------------------ ; Blank out a line on the display ; line number to blank is in r1 ;------------------------------------------------------------------------------ ; BlankLine: subui sp,sp,#24 sm [sp],r1/r2/r3 setlo r3,TEXTREG ; r3 = text register address lc r2,TEXT_COLS[r3] ; r2 = # chars to blank out mulu r3,r2,r1 shli r3,r3,#1 addui r3,r3,#TEXTSCR ; r3 = screen address setlo r1,#' ' blnkln1: sc r1,[r3] addui r3,r3,#2 loop r2,blnkln1 lm [sp],r1/r2/r3 ret #24 ;------------------------------------------------------------------------------ ; Convert ASCII character to screen display character. ;------------------------------------------------------------------------------ ; AsciiToScreen: andi r1,r1,#0x00ff bltui r1,#'A',atoscr1 bleui r1,#'Z',atoscr1 bgtui r1,#'z',atoscr1 bltui r1,#'a',atoscr1 subi r1,r1,#0x60 atoscr1: ori r1,r1,#0x100 ret ;------------------------------------------------------------------------------ ; Convert screen character to ascii character ;------------------------------------------------------------------------------ ; ScreenToAscii: andi r1,r1,#0xff bgtui r1,#26,stasc1 addui r1,r1,#60 stasc1: ret ;------------------------------------------------------------------------------ ; Calculate screen memory location from CursorRow,CursorCol. ; Also refreshes the cursor location. ; Destroys r1,r2,r3 ; r1 = screen location ;------------------------------------------------------------------------------ ; CalcScreenLoc: lc r1,CursorRow andi r1,r1,#0x7f setlo r3,TEXTREG inch r2,TEXT_COLS[r3] mulu r2,r2,r1 lc r1,CursorCol andi r1,r1,#0x7f addu r2,r2,r1 outc r2,TEXT_CURPOS[r3] shli r2,r2,#1 addui r1,r2,#TEXTSCR ; r1 = screen location ret ;------------------------------------------------------------------------------ ; Display a character on the screen ; d1.b = char to display ;------------------------------------------------------------------------------ ; DisplayChar: bnei r1,#'\r',dccr ; carriage return ? subui sp,sp,#32 sm [sp],r1/r2/r3/lr sc r0,CursorCol ; just set cursor column to zero on a CR bra dcx7 dccr: bnei r1,#0x91,dcx6 ; cursor right ? subui sp,sp,#32 sm [sp],r1/r2/r3/lr lc r2,CursorCol beqi r2,#56,dcx7 addui r2,r2,#1 sc r2,CursorCol dcx7: call CalcScreenLoc lm [sp],r1/r2/r3/lr ret #32 dcx6: bnei r1,#0x90,dcx8 ; cursor up ? subui sp,sp,#32 sm [sp],r1/r2/r3/lr lc r2,CursorRow beqi r2,#0,dcx7 subui r2,r2,#1 sc r2,CursorRow bra dcx7 dcx8: bnei r1,#0x93,dcx9 ; cursor left ? subui sp,sp,#32 sm [sp],r1/r2/r3/lr lc r2,CursorCol beqi r2,#0,dcx7 subui r2,r2,#1 sc r2,CursorCol bra dcx7 dcx9: bnei r1,#0x92,dcx10 ; cursor down ? subui sp,sp,#32 sm [sp],r1/r2/r3/lr lc r2,CursorRow beqi r2,#30,dcx7 addui r2,r2,#1 sc r2,CursorRow bra dcx7 dcx10: bnei r1,#0x94,dcx11 ; cursor home ? subui sp,sp,#32 sm [sp],r1/r2/r3/lr lc r2,CursorCol beq r2,r0,dcx12 sc r0,CursorCol bra dcx7 dcx12: sc r0,CursorRow bra dcx7 dcx11: subui sp,sp,#48 sm [sp],r1/r2/r3/r4/r5/r31 bnei r1,#0x99,dcx13 ; delete ? call CalcScreenLoc or r3,r0,r1 ; r3 = screen location lc r1,CursorCol ; r1 = cursor column bra dcx5 dcx13: bnei r1,#CTRLH,dcx3 ; backspace ? lc r2,CursorCol beq r2,r0,dcx4 subui r2,r2,#1 sc r2,CursorCol call CalcScreenLoc ; a0 = screen location or r3,r0,r1 ; r3 = screen location lc r1,CursorCol dcx5: lc r2,2[r3] sc r2,[r3] addui r3,r3,#2 addui r1,r1,#1 setlo r4,#TEXTREG inch r5,TEXT_COLS[r4] bltu r1,r5,dcx5 setlo r2,#' ' sc r2,-2[r3] bra dcx4 dcx3: beqi r1,#'\n',dclf ; linefeed ? or r4,r0,r1 ; save r1 in r4 call CalcScreenLoc ; r1 = screen location or r3,r0,r1 ; r3 = screen location or r1,r0,r4 ; restore r1 call AsciiToScreen ; convert ascii char to screen char sc r1,[r3] call IncCursorPos lm [sp],r1/r2/r3/r4/r5/r31 ret #48 dclf: call IncCursorRow dcx4: lm [sp],r1/r2/r3/r4/r5/r31 ret #48 ;------------------------------------------------------------------------------ ; Increment the cursor position, scroll the screen if needed. ;------------------------------------------------------------------------------ ; IncCursorPos: subui sp,sp,#32 sm [r30],r1/r2/r3/r31 lc r1,CursorCol addui r1,r1,#1 sc r1,CursorCol inch r2,TEXTREG+TEXT_COLS bleu r1,r2,icc1 sc r0,CursorCol ; column = 0 bra icr1 IncCursorRow: subui sp,sp,#32 sm [sp],r1/r2/r3/r31 icr1: lc r1,CursorRow addui r1,r1,#1 sc r1,CursorRow inch r2,TEXTREG+TEXT_ROWS bleu r1,r2,icc1 subui r2,r2,#1 ; backup the cursor row, we are scrolling up sc r2,CursorRow call ScrollUp icc1: call CalcScreenLoc lm [sp],r1/r2/r3/r31 ret #32 ;------------------------------------------------------------------------------ ; Display a string on the screen. ;------------------------------------------------------------------------------ ; DisplayString: subi sp,sp,#24 sm [sp],r1/r2/r31 or r2,r1,r0 ; r2 = pointer to string dspj1: lbu r1,[r2] ; move string char into r1 addui r2,r2,#1 ; increment pointer beq r1,r0,dsret ; is it end of string ? call DisplayChar ; display character bra dspj1 ; go back for next character dsret: lm [r30],r1/r2/r31 ret #24 DisplayStringCRLF: subui r30,r30,#8 sw r31,[r30] call DisplayString lw r31,[r30] addui r30,r30,#8 CRLF: subui r30,r30,#16 sw r1,[r30] sw r31,8[r30] setlo r1,#'\r' call DisplayChar setlo r1,#'\n' call DisplayChar lw r1,[r30] lw r31,8[r30] ret #16 ;------------------------------------------------------------------------------ ; Display nybble in r1 ;------------------------------------------------------------------------------ ; DisplayNybble: subui r30,r30,#16 sw r31,8[r30] sw r1,[r30] andi r1,r1,#0x0F addui r1,r1,#'0' bleui r1,#'9',dispnyb1 addui r1,r1,#7 dispnyb1: call DisplayChar lw r1,[r30] lw r31,8[r30] ret #16 ;------------------------------------------------------------------------------ ; Display the byte in r1 ;------------------------------------------------------------------------------ ; DisplayByte: subui sp,sp,#16 sm [sp],r1/r31 rori r1,r1,#4 call DisplayNybble roli r1,r1,#4 call DisplayNybble lm [sp],r1/r31 ret #16 ;------------------------------------------------------------------------------ ; Display the 64 bit word in r1 ;------------------------------------------------------------------------------ ; DisplayWord: subui sp,sp,#24 sm [sp],r1/r3/r31 setlo r3,#7 dspwd1: roli r1,r1,#8 call DisplayByte loop r3,dspwd1 lm [sp],r1/r3/r31 ret #24 ;------------------------------------------------------------------------------ ; Display memory pointed to by r2. ; destroys r1,r3 ;------------------------------------------------------------------------------ ; DisplayMem: subui sp,sp,#8 sw lr,[sp] setlo r1,#':' call DisplayChar or r1,r2,r0 call DisplayWord setlo r3,#7 dspmem1: setlo r1,#' ' call DisplayChar lb r1,[r2] call DisplayByte addui r2,r2,#1 loop r3,dspmem1 call CRLF lw lr,[sp] ret #8 ;------------------------------------------------------------------------------ ; Converts binary number in r1 into BCD number in r2 and r1. ;------------------------------------------------------------------------------ ; BinToBCD: subui sp,sp,#48 sm [sp],r3/r4/r5/r6/r7/r8 setlo r2,#10 setlo r8,#19 ; number of digits to produce - 1 bta1: mod r3,r1,r2 shli r3,r3,#60 ; shift result to uppermost bits shli r7,r5,#60 ; copy low order nybble of r5 to r4 topmost nybble shrui r4,r4,#4 or r4,r4,r7 shrui r5,r5,#4 or r5,r5,r3 ; copy new bcd digit into uppermost bits of r5 divui r1,r1,r2 ; r1=r1/10 loop r8,bta1 shrui r4,r4,#48 ; right align number in register shli r6,r5,#16 or r4,r4,r6 ; copy bits into r4 shrui r5,r5,#48 or r1,r0,r4 or r2,r0,r5 lm [sp],r3/r4/r5/r6/r7/r8 ret #48 ;------------------------------------------------------------------------------ ; Converts BCD number in r1 into Ascii number in r2 and r1. ;------------------------------------------------------------------------------ ; BCDToAscii: subui sp,sp,#32 sm [sp],r3/r4/r5/r8 setlo r8,#15 bta2: andi r2,r1,#0x0F ori r2,r2,#0x30 shli r2,r2,#56 shrui r4,r4,#8 shli r5,r3,#56 or r4,r4,r5 shrui r3,r3,#8 or r3,r3,r2 shrui r1,r1,#4 loop r8,bta2 or r1,r0,r4 or r2,r0,r3 lm [sp],r3/r4/r5/r8 ret #32 ;------------------------------------------------------------------------------ ; Convert a binary number into a 20 character ascii string. ; r1 = number to convert ; r2 = address of string buffer ;------------------------------------------------------------------------------ ; BinToStr: subui sp,sp,#56 sm [sp],r3/r7/r8/r9/r10/r11/r31 or r11,r0,r2 call BinToBCD or r10,r0,r2 ; save off r2 call BCDToAscii setlo r9,#1 btos3: setlo r8,#7 btos1: shli r7,r9,#3 addui r7,r7,r8 addui r7,r7,#4 andi r3,r1,#0xff sb r3,[r7+r11] shrui r1,r1,#8 loop r8,btos1 or r1,r0,r2 loop r9,btos3 ; the last four digits or r1,r0,r10 ; get back r2 call BCDToAscii setlo r8,#3 btos2: andi r3,r1,#0xff sb r3,[r8+r11] shrui r1,r1,#8 loop r8,btos2 sb r0,20[r11] ; null terminate lm [sp],r3/r7/r8/r9/r10/r11/r31 ret #56 ;============================================================================== ;============================================================================== Monitor: setlo sp,#STACKTOP ; top of stack; reset the stack pointer sb r0,KeybdEcho ; turn off keyboard echo PromptLn: call CRLF setlo r1,#'$' call DisplayChar ; Get characters until a CR is keyed ; Prompt3: call KeybdGetChar beqi r1,#-1,Prompt3 ; wait for a character beqi r1,#CR,Prompt1 call DisplayChar bra Prompt3 ; Process the screen line that the CR was keyed on ; Prompt1: sc r0,CursorCol ; go back to the start of the line call CalcScreenLoc ; r1 = screen memory location or r3,r1,r0 lc r1,[r3] addui r3,r3,#2 call ScreenToAscii bnei r1,#'$',Prompt2 ; skip over '$' prompt character lc r1,[r3] addui r3,r3,#2 call ScreenToAscii ; Dispatch based on command character ; Prompt2: beqi r1,#':',Editmem ; $: - edit memory beqi r1,#'D',Dumpmem ; $D - dump memory beqi r1,#'B',START ; $B - start tiny basic beqi r1,#'J',ExecuteCode ; $J - execute code beqi r1,#'L',LoadS19 ; $L - load S19 file beqi r1,#'?',DisplayHelp ; $? - display help beqi r1,#'C',TestCLS ; $C - clear screen bra Monitor TestCLS: lc r1,[r3] addui r3,r3,#2 call ScreenToAscii bnei r1,#'L',Monitor lc r1,[r3] addui r3,r3,#2 call ScreenToAscii bnei r1,#'S',Monitor call ClearScreen sb r0,CursorCol sb r0,CursorRow call CalcScreenLoc bra Monitor DisplayHelp: setlo r1,HelpMsg call DisplayString bra Monitor align 16 HelpMsg: db "? = Display help",CR,LF db "CLS = clear screen",CR,LF db ": = Edit memory bytes",CR,LF db "L = Load S19 file",CR,LF db "D = Dump memory",CR,LF db "B = start tiny basic",CR,LF db "J = Jump to code",CR,LF,0 align 16 ;------------------------------------------------------------------------------ ; Ignore blanks in the input ; r3 = text pointer ; r1 destroyed ;------------------------------------------------------------------------------ ; ignBlanks: subui sp,sp,#8 sw r31,[sp] ignBlanks1: lc r1,[r3] addui r3,r3,#2 call ScreenToAscii beqi r1,#' ',ignBlanks1 subui r3,r3,#2 lw r31,[sp] ret #8 ;------------------------------------------------------------------------------ ; Edit memory byte(s). ;------------------------------------------------------------------------------ ; EditMem: call ignBlanks call GetHexNumber or r5,r1,r0 setlo r4,#7 edtmem1: call ignBlanks call GetHexNumber sb r1,[r5] addui r5,r5,#1 loop r4,edtmem1 bra Monitor ;------------------------------------------------------------------------------ ; Execute code at the specified address. ;------------------------------------------------------------------------------ ; ExecuteCode: call ignBlanks call GetHexNumber or r3,r1,r0 jal r31,[r3] bra Monitor ;------------------------------------------------------------------------------ ; Do a memory dump of the requested location. ;------------------------------------------------------------------------------ ; DumpMem: call ignBlanks call GetHexNumber or r2,r1,r0 call CRLF call DisplayMem call DisplayMem call DisplayMem call DisplayMem call DisplayMem call DisplayMem call DisplayMem call DisplayMem bra Monitor ;------------------------------------------------------------------------------ ; Get a hexidecimal number. Maximum of sixteen digits. ; R3 = text pointer (updated) ;------------------------------------------------------------------------------ ; GetHexNumber: subui sp,sp,#24 sm [sp],r2/r4/r31 setlo r2,#0 setlo r4,#15 gthxn2: lc r1,[r3] addui r3,r3,#2 call ScreenToAscii call AsciiToHexNybble beqi r1,#-1,gthxn1 shli r2,r2,#4 andi r1,r1,#0x0f or r2,r2,r1 loop r4,gthxn2 gthxn1: or r1,r2,r0 lm [sp],r2/r4/r31 ret #24 ;------------------------------------------------------------------------------ ; Convert ASCII character in the range '0' to '9', 'a' to 'f' or 'A' to 'F' ; to a hex nybble. ;------------------------------------------------------------------------------ ; AsciiToHexNybble: bltui r1,#'0',gthx3 bgtui r1,#'9',gthx5 subui r1,r1,#'0' ret gthx5: bltui r1,#'A',gthx3 bgtui r1,#'F',gthx6 subui r1,r1,#'A' addui r1,r1,#10 ret gthx6: bltui r1,#'a',gthx3 bgtui r1,#'f',gthx3 subui r1,r1,#'a' addui r1,r1,#10 ret gthx3: setlo r1,#-1 ; not a hex number ret ;============================================================================== ; Load an S19 format file ;============================================================================== ; LoadS19: bra ProcessRec NextRec: call sGetChar bne r1,#LF,NextRec ProcessRec: call sGetChar beqi r1,#26,Monitor ; CTRL-Z ? bnei r1,#'S',NextRec call sGetChar blt r1,#'0',NextRec bgt r1,#'9',NextRec or r4,r1,r0 ; r4 = record type call sGetChar call AsciiToHexNybble or r2,r1,r0 call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r2,r1 ; r2 = byte count or r3,r2,r1 ; r3 = byte count beqi r4,#'0',NextRec ; manufacturer ID record, ignore beqi r4,#'1',ProcessS1 beqi r4,#'2',ProcessS2 beqi r4,#'3',ProcessS3 beqi r4,#'5',NextRec ; record count record, ignore beqi r4,#'7',ProcessS7 beqi r4,#'8',ProcessS8 beqi r4,#'9',ProcessS9 bra NextRec pcssxa: andi r3,r3,#0xff subui r3,r3,#1 ; one less for loop pcss1a: call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r2,r1 call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r2,r1 sb r2,[r5] addui r5,r5,#1 loop r3,pcss1a ; Get the checksum byte call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r2,r1 call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r2,r1 bra NextRec ProcessS1: call S19Get16BitAddress bra pcssxa ProcessS2: call S19Get24BitAddress bra pcssxa ProcessS3: call S19Get32BitAddress bra pcssxa ProcessS7: call S19Get32BitAddress sw r5,S19StartAddress bra Monitor ProcessS8: call S19Get24BitAddress sw r5,S19StartAddress bra Monitor ProcessS9: call S19Get16BitAddress sw r5,S19StartAddress bra Monitor S19Get16BitAddress: subui sp,sp,#8 sw r31,[sp] call sGetChar call AsciiToHexNybble or r2,r1,r0 bra S1932b S19Get24BitAddress: subui sp,sp,#8 sw r31,[sp] call sGetChar call AsciiToHexNybble or r2,r1,r0 bra S1932a S19Get32BitAddress: subui sp,sp,#8 sw r31,[sp] call sGetChar call AsciiToHexNybble or r2,r1,r0 call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r1,r2 call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r2,r1 S1932a: call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r2,r1 call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r2,r1 S1932b: call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r2,r1 call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r2,r1 call sGetChar call AsciiToHexNybble shli r2,r2,#4 or r2,r2,r1 xor r4,r4,r4 or r5,r2,r0 lw r31,[sp] addui sp,sp,#8 ret ;------------------------------------------------------------------------------ ; Get a character from auxillary input, checking the keyboard status for a ; CTRL-C ;------------------------------------------------------------------------------ ; sGetChar: subui sp,sp,#8 sw r31,[sp] sgc2: call KeybdCheckForKey beq r1,r0,sgc1 call KeybdGetchar beqi r1,#CRTLC,Monitor sgc1: call AUXIN beq r1,r0,sgc2 lw r31,[sp] addui sp,sp,#8 ret ;-------------------------------------------------------------------------- ; Sound a 800 Hz beep ;-------------------------------------------------------------------------- ; SetupAC97: ori r1,r0,#0 ; trigger a read of register 26 sc r1,AC97+0x26 sac971: ; wait for status to register 0xF (all ready) lc r1,AC97+0x26 bnei r1,#0x0F,sac971 ori r1,r0,#0 ; master volume, 0db attenuation, mute off sc r1,AC97+2 sc r1,AC97+4 ; headphone volume, 0db attenuation, mute off ori r1,r0,#8000 ; wait a while for the settings to take effect sac972: loop r1,sac972 Beep: ori r1,r0,#15 ; master volume to max sc r1,PSG+128 ori r1,r0,#13422 ; 800Hz sc r1,PSG ori r1,r0,#32 ; attack (8.192 ms) sc r1,PSG+8 ori r1,r0,#64 ; decay (16.384 ms) sc r1,PSG+10 ori r1,r0,#0xC0 ; sustain level sc r1,PSG+12 ori r1,r0,#4000 ; release (1.024 s) sc r1,PSG+14 ori r1,r0,#0x1104 ; gate, output enable, triangle waveform sc r1,PSG+4 ori r1,r0,#25000000 ; delay about 1s beep1: loop r1,beep1 ori r1,r0,#0x0000 ; gate off, output enable off, no waveform ret ;* ;* ===== Input a character from the host into register D0 (or ;* return Zero status if there's no character available). ;* AUXIN: inb r1,UART_LS ; is character ready ? andi r1,r1,#rxfull beq r1,r0,AXIRET ;if not, return Zero status inb r1,UART ; else get the character andi r1,r1,#0x7f ;zero out the high bit AXIRET: ret ;* ;* ===== Return to the resident monitor, operating system, etc. ;* BYEBYE: jmp Monitor ; MOVE.B #228,D7 ;return to Tutor ; TRAP #14 align 16 msgInit db CR,LF,"Raptor64 Tiny BASIC v1.0",CR,LF,"(C) 2012 Robert Finch",CR,LF,LF,0 OKMSG db CR,LF,"OK",CR,LF,0 msgWhat db "What?",CR,LF,0 SRYMSG db "Sorry." CLMSG db CR,LF,0 msgReadError db "Compact FLASH read error",CR,LF,0 msgNumTooBig db "Number is too big",CR,LF,0 msgDivZero db "Division by zero",CR,LF,0 msgVarSpace db "Out of variable space",CR,LF,0 msgBytesFree db " bytes free",CR,LF,0 msgReady db CR,LF,"Ready",CR,LF,0 msgComma db "Expecting a comma",CR,LF,0 msgLineRange db "Line number too big",CR,LF,0 msgVar db "Expecting a variable",CR,LF,0 msgRNDBad db "RND bad parameter",CR,LF,0 msgSYSBad db "SYS bad address",CR,LF,0 msgInputVar db "INPUT expecting a variable",CR,LF,0 msgNextFor db "NEXT without FOR",CR,LF,0 msgNextVar db "NEXT expecting a defined variable",CR,LF,0 msgBadGotoGosub db "GOTO/GOSUB bad line number",CR,LF,0 msgRetWoGosub db "RETURN without GOSUB",CR,LF,0 msgTooBig db "Program is too big",CR,LF,0 msgExtraChars db "Extra characters on line ignored",CR,LF,0 INITMSG: db CR,LF,'Raptor64 Tiny BASIC, v1.0',CR,LF,LF,0 OKMSG: db CR,LF,'OK',CR,LF,0 HOWMSG: db 'How?',CR,LF,0 WHTMSG: db 'What?',CR,LF,0 SRYMSG: db 'Sorry.' CLMSG: db CR,LF,0 ; DC.B 0 ;<- for aligning on a word boundary align 16 LSTROM EQU $ ; end of possible ROM area bss align 16 org 0x0080 typef db 0 ; variable / expression type align 8 OSSP dw 1 ; OS value of sp CURRNT dw 1 ; Current line pointer STKGOS dw 1 ; Saves stack pointer in 'GOSUB' STKINP dw 1 ; Saves stack pointer during 'INPUT' LOPVAR dw 1 ; 'FOR' loop save area LOPINC dw 1 ; increment LOPLMT dw 1 ; limit LOPLN dw 1 ; line number LOPPT dw 1 ; text pointer TXTUNF dw 1 ; points to unfilled text area VARBGN dw 1 ; points to variable area IVARBGN dw 1 ; points to integer variable area SVARBGN dw 1 ; points to string variable area FVARBGN dw 1 ; points to float variable area STKBOT dw 1 ; holds lower limit for stack growth NUMWKA fill.b 12,0 ; numeric work area BUFFER fill.b BUFLEN,0x00 ; Keyboard input buffer ;============================================================================== ; Checkerboard RAM tester ;============================================================================== ; code align 16 ramtest: or r8,r0,r0 ; r8 = 0 ori r1,r0,#0xAAAA5555AAAA5555 ; checkerboard pattern ramtest2: sw r1,[r8] ; save the checkerboard to memory lw r2,[r8] ; read it back cmp r3,r1,r2 ; is it the same ? bne r3,r0,ramtest1 addui r8,r8,#8 ; increment RAM pointer cmpi r3,r8,#0x0000_0000_0400_0000 blt r3,r0,ramtest2 ramtest1: or r10,r8,r0 ; r10 = max ram address ; readback the checkerboard pattern or r8,r0,r0 ; r8 = 0 ramtest4: lw r2,[r8] cmpi r3,r2,#0xAAAA5555AAAA5555 bne r3,r0,ramtest3 addi r8,r8,#8 cmpi r3,r8,#0x0000_0000_0100_0000 blt r3,r0,ramtest4 ramtest3: bne r8,r10,ramtest8 ; check for equal maximum address ; perform ramtest again with inverted checkerboard or r8,r0,r0 ; r8 = 0 ori r1,r0,#0x5555AAAA5555AAAA ramtest5: sw r1,[r8] lw r2,[r8] cmp r3,r1,r2 bne r3,r0,ramtest6 addi r8,r8,#8 cmpi r3,r8,#0x0000_0000_0100_0000 blt r3,r0,ramtest5 ramtest6: or r11,r8,r0 ; r11 = max ram address ; readback checkerboard or r8,r0,r0 ramtest7: lw r2,[r8] cmpi r3,r2,#0x5555AAAA5555AAAA bne r3,r0,ramtest8 addi r8,r8,#8 cmpi r3,r8,#0x0000_0000_0100_0000 blt r3,r0,ramtest7 ramtest8: beq r8,r11,ramtest9 min r8,r8,r11 ramtest9: beq r8,r10,ramtest10 min r8,r8,r10 ramtest10: sw r8,0x00000400 ;memend ret ;------------------------------------------- ; IRQ routine ;------------------------------------------- irqrout: subui sp,sp,#16 sm [sp],r1/lr inch r1,PIC beqi r1,#1,ColdStart irqrout3: bnei r1,#2,irqrout2 call Pulse1000 bra irqrout1 irqrout2: bnei r1,#15,irqrout1 call KeybdIRQ irqrout1: lm [sp],r1/lr addui sp,sp,#16 iret ;------------------------------------------- ; NMI routine ;------------------------------------------- nmirout: iret ;------------------------------------------- ; Handle miss on Data TLB ;------------------------------------------- DTLBHandler: sw r1,0xFFFF_FFFF_FFFF_0000 sw r2,0xFFFF_FFFF_FFFF_0008 dh1: omgi r1,#0 ; try open mutex gate #0 (TLB protector) bne r1,r0,dh1 ; spinlock if gate is closed mfspr r1,PTA ; get the page table address mfspr r2,BadVAddr ; get the bad virtual address mtspr TLBVirtPage,r2 ; which virtual address to update shrui r2,r2,#13 ; turn va into index addu r1,r1,r2 lw r2,[r1] ; get the physical address from the table and r2,r2,#FFFF_FFFF_FFFF_E000 ; mask off lower bits mtspr TLBPhysPage0,r2 ; lw r2,8[r1] ; get the physical address from the table and r2,r2,#FFFF_FFFF_FFFF_E000 ; mask off lower bits mtspr TLBPhysPage1,r2 ; tlbwr ; update a random entry in the TLB cmgi #0 ; close the mutex gate lw r1,0xFFFF_FFFF_FFFF_0000 lw r2,0xFFFF_FFFF_FFFF_0008 iret nop nop org 0xFFFF_FFFF_FFFF_FFB0 jmp DTLBHandler nop nop org 0xFFFF_FFFF_FFFF_FFC0 jmp DTLBHandler nop nop org 0xFFFF_FFFF_FFFF_FFD0 jmp irqrout nop nop org 0xFFFF_FFFF_FFFF_FFE0 jmp nmirout nop nop org 0xFFFF_FFFF_FFFF_FFF0 jmp start nop nop
Go to most recent revision | Compare with Previous | Blame | View Log