URL
https://opencores.org/ocsvn/rf6809/rf6809/trunk
Subversion Repositories rf6809
[/] [rf6809/] [trunk/] [software/] [boot/] [boot_rom.asm] - Rev 4
Go to most recent revision | Compare with Previous | Blame | View Log
; ============================================================================; __; \\__/ o\ (C) 2013-2022 Robert Finch, Stratford; \ __ / 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 $0D ;ASCII equatesLF EQU $0ATAB EQU $09CTRLC EQU $03CTRLH EQU $08CTRLI EQU $09CTRLJ EQU $0ACTRLK EQU $0BCTRLM EQU $0DCTRLS EQU $13CTRLX EQU $18XON EQU $11XOFF EQU $13FIRST_CORE EQU 1MAX_TASKNO EQU 63DRAM_BASE EQU $10000000ScreenLocation EQU $10ColorCodeLocation EQU $14ScreenLocation2 EQU $18BlkcpySrc EQU $1CBlkcpyDst EQU $20Strptr EQU $24PICptr EQU $28; Forth Area; 0x30-0x60RunningID EQU $800000; Task control blocks, room for 256 tasksTCB_NxtRdy EQU $00 ; next task on ready / timeout listTCB_PrvRdy EQU $04 ; previous task on ready / timeout listTCB_NxtTCB EQU $08TCB_Timeout EQU $0CTCB_Priority EQU $10TCB_MSGPTR_D1 EQU $14TCB_MSGPTR_D2 EQU $18TCB_hJCB EQU $1CTCB_Status EQU $1ETCB_CursorRow EQU $20TCB_CursorCol EQU $21TCB_hWaitMbx EQU $22 ; handle of mailbox task is waiting atTCB_mbq_next EQU $24 ; mailbox queue nextTCB_mbq_prev EQU $28 ; mailbox queue previousTCB_iof_next EQU $2CTCB_iof_prev EQU $30TCB_SPSave EQU $34 ; TCB_SPSave areaTCB_mmu_map EQU $38KeybdHead EQU $FFFFFC800KeybdTail EQU $FFFFFC900KeybdEcho EQU $FFFFFCA00KeybdBad EQU $FFFFFCB00KeybdAck EQU $FFFFFCC00KeybdLocks EQU $FFFFFCD00KeybdBuffer EQU $FFFFFC000 ; buffer is 16 charsCOREID EQU $FFFFFFFE0MSCOUNT EQU $FFFFFFFE4LEDS EQU $FFFE60000TEXTSCR EQU $FFFE00000TEXTREG EQU $FFFE0DF00TEXT_COLS EQU 0TEXT_ROWS EQU 1TEXT_CURPOS EQU 34KEYBD EQU $FFFE30400KEYBDCLR EQU $FFFE30402PIC EQU $FFFE3F000SPRITE_CTRL EQU $FFFE10000SPRITE_EN EQU $3C0BIOS_SCREENS EQU $17000000 ; $17000000 to $171FFFFF; EhBASIC vars:;NmiBase EQU $DCIrqBase EQU $DF; The IO focus list is a doubly linked list formed into a ring.;IOFocusNdx EQU $100IOFocusID EQU $100; These variables use direct page accessCursorRow EQU $110CursorCol EQU $111CharColor EQU $112ScreenColor EQU $113CursorFlash EQU $114KeyState1 EQU $120KeyState2 EQU $121KeyLED EQU $122KeybdID EQU $124QNdx0 EQU $780QNdx1 EQU QNdx0+2QNdx2 EQU QNdx1+2QNdx3 EQU QNdx2+2QNdx4 EQU QNdx3+2FreeTCB EQU QNdx4+2TimeoutList EQU FreeTCB+2FreeMbx EQU RunningTCB + 2nMailbox EQU FreeMbx + 2FreeMsg EQU nMailbox + 2nMsgBlk EQU FreeMsg + 2IrqSource EQU $79AIRQFlag EQU $7C6CharOutVec EQU $800CharInVec EQU $804; Register save area for monitormon_DSAVE EQU $900mon_XSAVE EQU $902mon_YSAVE EQU $904mon_USAVE EQU $906mon_SSAVE EQU $908mon_PCSAVE EQU $90Amon_DPRSAVE EQU $90Emon_CCRSAVE EQU $90Fmon_numwka EQU $910mon_r1 EQU $920mon_r2 EQU $922; The ORG directive must set an address a multiple of 4 in order for the Verilog; output to work correctly.org $FFD0ACnopnopnopXBLANKldb #' 'lbsr OUTCHrtsorg $FFD0D0nopnopCRLFCRLF1:ldb #CRlbsr OUTCHldb #LFlbsr OUTCHrtsorg $FFD0F0nopbra CRLF1org $FFD1DCONEKEYjmp [CharInVec]org $FFD2C0nopLETTERlbsr OUTCHrtsorg $FFD2CCnopnopHEX2lbsr DispByteAsHexrtsHEX4lbsr DispWordAsHexrtsorg $FFD300ClearScreenJmplbra ClearScreenorg $FFD308HomeCursorJmplbra HomeCursororg $FFE000; Local RAM test routine; Checkerboard testing.; There is 70kB of local RAM; Does not use any RAM including no stackramtest:ldy #0lda #1sta LEDSldd #$AAA555ramtest1:std ,y++cmpy #$C00000blo ramtest1; now readback values and compareldy #0ramtest3:ldd ,y++cmpd #$AAA555bne ramerrcmpy #$C00000blo ramtest3lda #2sta LEDSjmp ,uramerr:lda #$80sta LEDSldx #TEXTSCRldb COREIDabxlda #'F'sta ,xsyncjmp ,uorg $FFF000FDB MonitorFDB DumRts ; NEXTCMDFDB INCHFDB INCHEFDB INCHEKFDB OUTCHFDB PDATAFDB PCRLFFDB PSTRNGFDB DumRts ; LRAFDB DumRtsFDB DumRtsFDB DumRtsFDB DumRts ; VINIZFDB DisplayChar ; VOUTCHFDB DumRts ; ACINIZFDB DumRts ; AOUTCHDumRts:rts;------------------------------------------------------------------------------;------------------------------------------------------------------------------start:lda #$55 ; see if we can at least set LEDssta LEDSldu #st6 ; U = return addressjmp ramtest ; JMP dont JSRst6:lds #$3FFF ; boot up stack arealda COREIDcmpa #FIRST_CORE; beq st8; sync ; halt cores other than 2st8:; bne skip_init; bsr romToRam; ldd #st7 & $FFFF; tfr d,x; jmp ,x ; jump to the BIOS now in local RAMst7:bsr Delay3s ; give some time for devices to resetlda #$AAsta LEDSlda #2sta IOFocusID ; core #2 has focussta RunningIDlda #$0CEsta ScreenColorsta CharColorbsr ClearScreenldd #DisplayCharstd CharOutVecldd #DBGGetKeystd CharInVecldb COREIDcmpb #FIRST_COREbeq initbra skip_initbra multi_sievest3:lda #$FFsta LEDSbra st3; initialize interrupt controller; first, zero out all the vectorsinit:ldx #128lda #1 ; set irq(bit0), clear firq (bit1), disable int (bit 6), clear edge sense(bit 7)ldb #FIRST_CORE ; serving core idst1:clr PIC,x ; cause codesta PIC+1,xstb PIC+2,xleax 4,xcmpx #256blo st1; lda #4 ; make the timer interrupt edge sensitive; sta PIC+4 ; reg #4 is the edge sensitivity setting; sta PIC ; reg #0 is interrupt enableskip_init:andcc #$EF ; unmask irqlda #56sta TEXTREG+TEXT_COLSlda #29sta TEXTREG+TEXT_ROWSbsr ClearScreenbsr HomeCursorlda #5sta LEDSldd #msgStartupbsr DisplayStringldx #0ldd #0lbsr ShowSpriteslbsr KeybdInitldd KeybdIDbsr DispWordAsHexjmp MonitorStartmsgStartupfcb "rf6809 12-bit System Starting.",CR,LF,0;------------------------------------------------------------------------------; The checkpoint register must be cleared within 1 second or a NMI interrupt; will occur. checkpoint should be called with a JSR so that the global ROM; routine is called.;; Modifies:; none;------------------------------------------------------------------------------checkpoint:clr $FFFFFFFE1 ; writing any value will dorts;------------------------------------------------------------------------------; Copy the system ROM to local RAM; Running the code from local RAM is probably an order of magnitude faster; then running from the global ROM. It also reduces the network traffic to; run from local RAM.;; Modifies:; d,x,y;------------------------------------------------------------------------------romToRam:ldx #$FFC000ldy #$00C000romToRam1:ldd ,x++std ,y++cmpx #0bne romToRam1rts;------------------------------------------------------------------------------; Multi-core sieve program.;------------------------------------------------------------------------------; First fill screen chars with 'P' indicating prime positions; Each core is responsible for the Nth position where N is the; core number minus two.;multi_sieve:lda #'P' ; indicate primeldb COREID ; find out which core we aresubb #FIRST_COREldx #0 ; start at first char of screenabxmulti_sieve3:sta TEXTSCR,x ; store 'P'leax 8,x ; advance to next positioncmpx #4095blo multi_sieve3jsr checkpointaddb #2 ; start sieve at 2 (core id)lda #'N' ; flag position value of 'N' for non-primemulti_sieve2:ldx #0abx ; skip the first position - might be primemulti_sieve1:abx ; incrementsta TEXTSCR,xcmpx #4095blo multi_sieve1jsr checkpointaddb #8 ; number of cores working on itcmpb #4080blo multi_sieve2multi_sieve4: ; hang machinesynclbra Monitorsieve:lda #'P' ; indicate primeldx #0 ; start at first char of screensieve3:sta TEXTSCR,x ; store 'P'inx ; advance to next positioncmpx #4095blo sieve3ldb #2 ; start sieve at 2lda #'N' ; flag position value of 'N' for non-primesieve2:ldx #0abx ; skip the first position - might be primesieve1:abx ; incrementsta TEXTSCR,xcmpx #4095blo multi_sieve1incb ; number of cores working on itcmpb #4080blo sieve2sieve4: ; hang machinesynclbra MonitorStart;------------------------------------------------------------------------------; Three second delay for user convenience and to allow some devices time to; reset.;------------------------------------------------------------------------------Delay3s:ldd #9000000dly3s1:cmpb #$FFbne dly3s2dly3s2:sta LEDSsubd #1bne dly3s1rts;------------------------------------------------------------------------------;------------------------------------------------------------------------------ShiftLeft5:aslbrolaaslbrolaaslbrolaaslbrolaaslbrolarts;------------------------------------------------------------------------------;------------------------------------------------------------------------------;CopyVirtualScreenToScreen:pshs d,x,y,ubsr GetScreenLocationtfr d,xldy #TEXTSCRldu #56*29/2cv2s1:ldd ,x++std ,y++leau -1,ucmpu #0bne cv2s1; reset the cursor position in the text controllerldb CursorRowlda #56multfr d,xldb CursorColabxstx TEXTREG+TEXT_CURPOSpuls d,x,y,u,pc;------------------------------------------------------------------------------;------------------------------------------------------------------------------;CopyScreenToVirtualScreen:pshs d,x,y,ubsr GetScreenLocationtfr d,yldx #TEXTSCRldu #56*29/2cs2v1:ldd ,x++std ,y++leau -1,ucmpu #0bne cs2v1puls d,x,y,u,pc;------------------------------------------------------------------------------;------------------------------------------------------------------------------fcb "TEXTSCR "fcw TextOpenfcw TextClosefcw TextReadfcw TextWritefcw TextSeekTextOpen:rtsTextClose:rtsTextRead:rtsTextWrite:rtsTextSeek:rts;------------------------------------------------------------------------------; Clear the screen and the screen color memory; We clear the screen to give a visual indication that the system; is working at all.;; Modifies:; none;------------------------------------------------------------------------------ClearScreen:pshs d,x,y,uldx #56*29tfr x,ubsr GetScreenLocationtfr d,yldb #' ' ; space charcs1:stb ,y+ ; set text to spaceleax -1,x ; decrement xbne cs1ldb COREID ; update colors only if we have focuscmpb IOFocusIDbra cs3ldy #TEXTSCR+$2000; lda CharColorlda #$0CEtfr u,x ; get back countcs2:sta ,y+leax -1,x ; decrement xbne cs2cs3:puls d,x,y,u,pc;------------------------------------------------------------------------------; Scroll text on the screen upwards;; Modifies:; none;------------------------------------------------------------------------------ScrollUp:pshs d,x,y,uldy #(56*29-1)/2 ; y = num chars/2 to movebsr GetScreenLocationtfr d,xtfr d,uleax 56,x ; x = index to source rowscrup1:ldd ,x++ ; move 2 charactersstd ,u++leay -1,ybne scrup1lda #30bsr BlankLinepuls d,x,y,u,pc;------------------------------------------------------------------------------; Blank out a line on the display;; Modifies:; none; Parameters:; acca = line number to blank;------------------------------------------------------------------------------BlankLine:pshs d,xpshs absr GetScreenLocationtfr d,xpuls aldb #56 ; b = # chars to blank out from video controllermul ; d = screen index (row# * #cols)leax d,xlda #' 'ldb #56 ; b = # chars to blank out from video controllerblnkln1:sta ,x+decbbne blnkln1puls d,x,pc;------------------------------------------------------------------------------; Get the location of the screen memory. The location; depends on whether or not the task has the output focus.;; Modifies:; d; Retuns:; d = screen location;------------------------------------------------------------------------------GetScreenLocation:lda COREID ; which core are we?cmpa IOFocusID ; do we have the IO focusbne gsl1 ; no, go pick virtual screen addressldd #TEXTSCR ; yes, we update the real screenrtsgsl1:ldd #$7800rts;------------------------------------------------------------------------------; HomeCursor; Set the cursor location to the top left of the screen.;; Modifies:; none;------------------------------------------------------------------------------HomeCursor:pshs d,xclr CursorRowclr CursorColldb COREIDcmpb IOFocusIDbne hc1clrasta TEXTREG+TEXT_CURPOShc1:puls d,x,pc;------------------------------------------------------------------------------; Update the cursor position in the text controller based on the; CursorRow,CursorCol.;; Modifies:; none;------------------------------------------------------------------------------;UpdateCursorPos:pshs d,xldb COREID ; update cursor position in text controllercmpb IOFocusID ; only for the task with the output focusbne ucp1lda CursorRowanda #$3F ; limit of 63 rowsldb TEXTREG+TEXT_COLSmultfr d,xldb CursorColabxstx TEXTREG+TEXT_CURPOSucp1:puls d,x,pc;------------------------------------------------------------------------------; Calculate screen memory location from CursorRow,CursorCol.; Also refreshes the cursor location.;; Modifies:; d; Returns:; d = screen location;------------------------------------------------------------------------------;CalcScreenLoc:pshs xlda CursorRowldb #56multfr d,xldb CursorColabxldb COREID ; update cursor position in text controllercmpb IOFocusID ; only for the task with the output focusbne csl1stx TEXTREG+TEXT_CURPOScsl1:bsr GetScreenLocationleax d,xtfr x,dpuls x,pc;------------------------------------------------------------------------------; Display a character on the screen.; If the task doesn't have the I/O focus then the character is written to; the virtual screen.;; Modifies:; none; Parameters:; accb = char to display;------------------------------------------------------------------------------;DisplayChar:pshs d,xcmpb #CR ; carriage return ?bne dccrclr CursorCol ; just set cursor column to zero on a CRbsr UpdateCursorPosdcx14:puls d,x,pcdccr:cmpb #$91 ; cursor right ?bne dcx6lda CursorColcmpa #56bhs dcx7incasta CursorColdcx7:bsr UpdateCursorPospuls d,x,pcdcx6:cmpb #$90 ; cursor up ?bne dcx8lda CursorRowbeq dcx7decasta CursorRowbra dcx7dcx8:cmpb #$93 ; cursor left ?bne dcx9lda CursorColbeq dcx7decasta CursorColbra dcx7dcx9:cmpb #$92 ; cursor down ?bne dcx10lda CursorRowcmpa #29beq dcx7incasta CursorRowbra dcx7dcx10:cmpb #$94 ; cursor home ?bne dcx11lda CursorColbeq dcx12clr CursorColbra dcx7dcx12:clr CursorRowbra dcx7dcx11:cmpb #$99 ; delete ?bne dcx13bsr CalcScreenLoctfr d,xlda CursorCol ; acc = cursor columnbra dcx5dcx13cmpb #CTRLH ; backspace ?bne dcx3lda CursorColbeq dcx4decasta CursorColbsr CalcScreenLocdcx5:ldb 1,xstb ,x++incacmpa #56blo dcx5ldb #' 'leax -1,xstb ,xpuls d,x,dp,pcdcx3:cmpb #LF ; linefeed ?beq dclfpshs bbsr CalcScreenLoctfr d,xpuls bstb ,x; ToDo character color; lda CharColor; sta $2000,xbsr IncCursorPospuls d,x,pcdclf:bsr IncCursorRowdcx4:puls d,x,pc;------------------------------------------------------------------------------; Increment the cursor position, scroll the screen if needed.;; Modifies:; none;------------------------------------------------------------------------------IncCursorPos:pshs d,xlda CursorColincasta CursorColcmpa #56blo icc1clr CursorCol ; column = 0bra icr1IncCursorRow:pshs d,xicr1:lda CursorRowincasta CursorRowcmpa #29blo icc1deca ; backup the cursor row, we are scrolling upsta CursorRowbsr ScrollUpicc1:bsr UpdateCursorPosicc2:puls d,x,pc;------------------------------------------------------------------------------; Display a string on the screen.;; Modifies:; none; Parameters:; d = pointer to string;------------------------------------------------------------------------------;DisplayString:pshs d,xtfr d,xdspj1B:ldb ,x+ ; move string char into accbeq dsretB ; is it end of string ?bsr OUTCH ; display characterbra dspj1BdsretB:puls d,x,pcDisplayStringCRLF:pshs dbsr DisplayStringldb #CRbsr OUTCHldb #LFbsr OUTCHpuls d,pc;; PRINT CR, LF, STRING;PSTRNGBSR PCRLFBRA PDATAPCRLFPSHS XLDX #CRLFSTBSR PDATAPULS XRTSJSR OUTCHPDATALDB ,X+CMPB #$04BNE PRINTRTSCRLFSTfcb CR,LF,4DispDWordAsHex:bsr DispWordAsHexexg d,xbsr DispWordAsHexexg d,xrtsDispWordAsHex:exg a,bbsr DispByteAsHexexg a,bbsr DispByteAsHexrtsDispByteAsHex:pshs blsrblsrblsrblsrblsrblsrblsrblsrbbsr DispNybpuls bpshs blsrblsrblsrblsrbbsr DispNybpuls bDispNybpshs bandb #$0Fcmpb #10blo DispNyb1addb #'A'-10bsr OUTCHpuls b,pcDispNyb1addb #'0'bsr OUTCHpuls b,pc;==============================================================================; Keyboard I/O;==============================================================================OPT INCLUDE "d:\cores2022\rf6809\software\boot\scancodes.asm"OPT INCLUDE "d:\cores2022\rf6809\software\boot\keyboard.asm"fcb "KEYBOARD"fcw KeybdOpenfcw KeybdClosefcw KeybdReadfcw KeybdWritefcw KeybdSeek; Keyboard Open:; Initialize the keyboard buffer head and tail indexes;KeybdOpen:rts; Keyboard Close:; Nothing to do except maybe clear the keyboard buffer;KeybdClose:rts;KeybdRead:rts;KeybdWrite:rtsKeybdSeek:rts;------------------------------------------------------------------------------; Check if there is a keyboard character available. If so return true (<0); otherwise return false (0) in accb.;------------------------------------------------------------------------------;KeybdCheckForKeyDirect:bra DBGCheckForKey;------------------------------------------------------------------------------;------------------------------------------------------------------------------INCH:ldd #-1 ; block if no key availablebra DBGGetKeyINCHE:bsr INCHbra INCHEK3INCHEK:bsr INCHtst KeybdEchobeq INCHEK1INCHEK3:cmpa #CRbne INCHEK2lbsr CRLFbra INCHEK1INCHEK2:bsr DisplayCharINCHEK1:rtsOUTCH:jmp [CharOutVec];------------------------------------------------------------------------------; r1 0=echo off, non-zero = echo on;------------------------------------------------------------------------------;SetKeyboardEcho:stb KeybdEchorts;------------------------------------------------------------------------------; Parameters:; x,d bitmap of sprites to enable;------------------------------------------------------------------------------ShowSprites:stx SPRITE_CTRL+SPRITE_ENstd SPRITE_CTRL+SPRITE_EN+2rts;==============================================================================; System Monitor;==============================================================================;MonitorStart:ldd #HelpMsgbsr DisplayStringMonitor:leas $3FFF ; reset stack pointerclrb ; turn off keyboard echobsr SetKeyboardEcho; jsr RequestIOFocusPromptLn:lbsr CRLFldb #'$'bsr OUTCH; Get characters until a CR is keyedPrompt3:ldd #-1 ; block until key presentbsr DBGGetKeycmpb #CRbeq Prompt1bsr OUTCHbra Prompt3; Process the screen line that the CR was keyed on;Prompt1:ldd #$5050std LEDSldb RunningIDcmpb #61bhi Prompt3ldd #$5151std LEDSclr CursorCol ; go back to the start of the linebsr CalcScreenLoc ; calc screen memory locationtfr d,yldd #$5252std LEDSbsr MonGetNonSpacecmpb #'$'bne Prompt2 ; skip over '$' prompt characterlda #$5353std LEDSbsr MonGetNonSpace; Dispatch based on command character;Prompt2:cmpb #'?' ; $? - display helpbne PromptCldd #HelpMsgbsr DisplayStringbra MonitorPromptC:cmpb #'C'bne PromptDlbsr ClearScreenbsr HomeCursorbra MonitorPromptD:cmpb #'D'bne PromptFbsr MonGetchcmpb #'R'bne Prompt3bra DumpRegsPromptF:cmpb #'F'bne PromptJbsr MonGetchcmpb #'I'bne Monitorbsr MonGetchcmpb #'G'bne Monitorjmp $FE0000PromptJ:cmpb #'J'lbeq jump_to_codePromptR:cmpb #'R'bne Monitorlbsr ramtestbra MonitorMonGetch:ldb ,yleay 1,yrtsMonGetNonSpace:bsr MonGetChcmpb #' 'beq MonGetNonSpacecmpb #9 ; tabbeq MonGetNonSpacerts;------------------------------------------------------------------------------; Ignore blanks in the input; Y = text pointer; D destroyed;------------------------------------------------------------------------------;ignBlanks:ignBlanks1:bsr MonGetchcmpb #' 'beq ignBlanks1leay -1,yrts;------------------------------------------------------------------------------;------------------------------------------------------------------------------GetTwoParams:bsr ignBlanksbsr GetHexNumber ; get start address of dumpldd mon_numwkastd mon_r1ldd mon_numwka+2std mon_r1+2bsr ignBlanksbsr GetHexNumber ; get end address of dumpldd mon_numwkastd mon_r2ldd mon_numwka+2std mon_r2+2rts;------------------------------------------------------------------------------; Get a range, the end must be greater or equal to the start.;------------------------------------------------------------------------------GetRange:bsr GetTwoParamsldd mon_r2+2subd mon_r1+2ldd mon_r2sbcb mon_r1+1sbca mon_r1lbcs DisplayErrrtsshl_numwka:asl mon_numwka+3rol mon_numwka+2rol mon_numwka+1rol mon_numwkarts;------------------------------------------------------------------------------; Get a hexidecimal number. Maximum of nine digits.; Y = text pointer (updated); D = number of digits; mon_numwka contains number;------------------------------------------------------------------------------;GetHexNumber:clrdstd mon_numwkastd mon_numwka+2pshs xldx #0 ; max 9 eight digitsgthxn2:bsr MonGetchbsr AsciiToHexNybblecmpb #-1beq gthxn1bsr shl_numwkabsr shl_numwkabsr shl_numwkabsr shl_numwkaandb #$0forb mon_numwka+3stb mon_numwka+3inxcmpx #9blo gthxn2gthxn1:tfr x,dpuls x,pc;GetDecNumber:; phx; push r4; push r5; ldx #0; ld r4,#10; ld r5,#10;gtdcn2:; jsr MonGetch; jsr AsciiToDecNybble; cmp #-1; beq gtdcn1; mul r2,r2,r5; add r2,r1; dec r4; bne gtdcn2;gtdcn1:; txa; pop r5; pop r4; plx; rts;------------------------------------------------------------------------------; Convert ASCII character in the range '0' to '9', 'a' to 'f' or 'A' to 'F'; to a hex nybble.;------------------------------------------------------------------------------;AsciiToHexNybble:cmpb #'0'bcc gthx3cmpb #'9'+1bcs gthx5subb #'0'rtsgthx5:cmpb #'A'bcc gthx3cmpb #'F'+1bcs gthx6subb #'A'addb #10rtsgthx6:cmpb #'a'bcc gthx3cmpb #'z'+1bcs gthx3subb #'a'addb #10rtsgthx3:ldb #-1 ; not a hex numberrtsAsciiToDecNybble:cmpb #'0'bcc gtdc3cmpb #'9'+1bcs gtdc3subb #'0'rtsgtdc3:ldb #-1rtsDisplayErr:ldx #msgErrclrdbsr DisplayStringDXjmp MonitorDisplayStringDXstd Strptrstx Strptr+2jsr DisplayStringrtsmsgErr:fcb "**Err",CR,LF,0HelpMsg:fcb "? = Display help",CR,LFfcb "CLS = clear screen",CR,LF; db "S = Boot from SD Card",CR,LF; db ": = Edit memory bytes",CR,LF; db "L = Load sector",CR,LF; db "W = Write sector",CR,LFfcb "DR = Dump registers",CR,LF; db "D = Dump memory",CR,LF; db "F = Fill memory",CR,LF; db "FL = Dump I/O Focus List",CR,LFfcb "FIG = start FIG Forth",CR,LF; db "KILL n = kill task #n",CR,LF; db "B = start tiny basic",CR,LF; db "b = start EhBasic 6502",CR,LFfcb "J = Jump to code",CR,LFfcb "RAM = test RAM",CR,LF; db "R[n] = Set register value",CR,LF; db "r = random lines - test bitmap",CR,LF; db "e = ethernet test",CR,LF; db "T = Dump task list",CR,LF; db "TO = Dump timeout list",CR,LF; db "TI = display date/time",CR,LF; db "TEMP = display temperature",CR,LF; db "P = Piano",CR,LF,0fcb 0msgRegHeadingsfcb CR,LF," D/AB X Y U S PC DP CCR",CR,LF,0nHEX4:jsr HEX4rtsnXBLANK:ldb #' 'bra OUTCHDumpRegsldx #msgRegHeadingsldd #msgRegHeadings>>16jsr DisplayStringDXbsr nXBLANKldd mon_DSAVEbsr nHEX4bsr nXBLANKldd mon_XSAVEbsr nHEX4bsr nXBLANKldd mon_YSAVEbsr nHEX4bsr nXBLANKldd mon_USAVEbsr nHEX4bsr nXBLANKldd mon_SSAVEbsr nHEX4bsr nXBLANKldd mon_PCSAVEbsr nHEX4ldd mon_PCSAVE+2bsr nHEX4bsr nXBLANKldd mon_DPRSAVEjsr HEX2bsr nXBLANKlda mon_CCRSAVEjsr HEX2bsr nXBLANKjmp Monitor; Jump to codejump_to_code:bsr GetHexNumberseilds mon_SSAVEldd #<jtc_exitpshs dldd #>jtc_exitpshs bldd mon_numwka+2pshs dldd mon_numwkapshs dldd mon_USAVEpshs dldd mon_YSAVEpshs dldd mon_XSAVEpshs dlda mon_DPRSavepshs aldd mon_DSAVEpshs dlda mon_CCRSAVEpshs apuls far ccr,d,dpr,x,y,u,pcjtc_exit:pshs ccrstd mon_DSAVEstx mon_XSAVEsty mon_YSAVEstu mon_USAVEtfr dpr,asta mon_DPRSAVEpuls asta mon_CCRSAVEsts mon_SSAVElds #$3FFF; todo set according to coreidjmp DumpRegs;------------------------------------------------------------------------------;------------------------------------------------------------------------------swi3_rout:seipuls asta mon_CCRSAVEpuls D,DPR,X,Y,Ustd mon_DSAVEstx mon_XSAVEsty mon_YSAVEstu mon_USAVEtfr dpr,asta mon_DPRSAVEpuls Dstd mon_PCSAVEpuls Dstd mon_PCSAVE+2sts mon_SSAVElds #$3FFFclijmp DumpRegsswi3_exit:seilds mon_SSAVEldd mon_PCSAVE+2pshs dldd mon_PCSAVEpshs dldu mon_USAVEldy mon_YSAVEldx mon_XSAVEpshs x,y,ulda mon_DPRSAVEpshs aldd mon_DSAVEpshs dlda mon_CCRSAVEpshs atfr a,ccrclirti;------------------------------------------------------------------------------;------------------------------------------------------------------------------irq_rout:; Reset the edge sense circuit in the PIClda #2 ; Timer is IRQ #2sta PIC+6 ; register 6 is edge sense reset regsta IrqSource ; stuff a byte indicating the IRQ source for PEEK()lda IrqBase ; get the IRQ flag bytelsraora IrqBaseanda #$E0sta IrqBaseinc TEXTSCR+110 ; update IRQ live indicator on screen; flash the cursor; only bother to flash the cursor for the task with the IO focus.lda COREIDcmpa IOFocusIDbne tr1alda CursorFlash ; test if we want a flashing cursorbeq tr1albsr CalcScreenLoc ; compute cursor location in memorytfr d,ylda $2000,y ; get color code $2000 higher in memoryldb IRQFlag ; get counterlsrblsralsralsralsralsrbrolalsrbrolalsrbrolalsrbrolasta $E00000,y ; store the color code back to memorytr1arti;------------------------------------------------------------------------------;------------------------------------------------------------------------------nmi_rout:ldb COREIDlda #'I'ldx #TEXTSCR+40abxsta ,xrtiorg $FFFFF0nopnopfcw swi3_routorg $FFFFF8fcw irq_routfcw start ; SWIfcw nmi_rout ; NMIfcw start ; RST
Go to most recent revision | Compare with Previous | Blame | View Log
