OpenCores
URL https://opencores.org/ocsvn/raptor64/raptor64/trunk

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [software/] [sample code/] [bootrom.s] - Diff between revs 43 and 46

Show entire file | Details | Blame | View Log

Rev 43 Rev 46
Line 1... Line 1...
; ============================================================================
; ============================================================================
; (C) 2012,2013 Robert Finch, Stratford
;        __
; All Rights Reserved.
;   \\__/ o\    (C) 2012-2013  Robert Finch, Stratford
; robfinch<remove>@opencores.org
;    \  __ /    All rights reserved.
 
;     \/_//     robfinch<remove>@opencores.org
 
;       ||
 
;  
;
;
; This source file is free software: you can redistribute it and/or modify 
; 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 
; 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     
; by the Free Software Foundation, either version 3 of the License, or     
; (at your option) any later version.                                      
; (at your option) any later version.                                      
Line 21... Line 24...
CR      EQU     0x0D            ;ASCII equates
CR      EQU     0x0D            ;ASCII equates
LF      EQU     0x0A
LF      EQU     0x0A
TAB     EQU     0x09
TAB     EQU     0x09
CTRLC   EQU     0x03
CTRLC   EQU     0x03
CTRLH   EQU     0x08
CTRLH   EQU     0x08
 
CTRLI   EQU     0x09
 
CTRLJ   EQU     0x0A
 
CTRLK   EQU     0x0B
 
CTRLM   EQU 0x0D
CTRLS   EQU     0x13
CTRLS   EQU     0x13
CTRLX   EQU     0x18
CTRLX   EQU     0x18
XON             EQU     0x11
XON             EQU     0x11
XOFF    EQU     0x13
XOFF    EQU     0x13
 
 
 
EX_IRQ  EQU     449
 
 
DATA_PRESENT    EQU     0x01            ; there is data preset at the serial port bc_uart3
DATA_PRESENT    EQU     0x01            ; there is data preset at the serial port bc_uart3
XMIT_NOT_FULL   EQU     0x20
XMIT_NOT_FULL   EQU     0x20
 
 
BUFLEN  EQU     80      ;       length of keyboard input buffer
BUFLEN  EQU     80      ;       length of keyboard input buffer
 
 
Line 88... Line 97...
TCBr28          EQU             0xD8
TCBr28          EQU             0xD8
TCBr29          EQU             0xE0
TCBr29          EQU             0xE0
TCBr30          EQU             0xE8
TCBr30          EQU             0xE8
TCBr31          EQU             0xF0
TCBr31          EQU             0xF0
 
 
 
SCREENGATE      EQU             0x00
 
KEYBDGATE       EQU             0x01
 
VIDEOGATE       EQU             0x02
 
CARDGATE        EQU             0x03
warmStart   EQU     0x1020
warmStart   EQU     0x1020
usrJmp      EQU     0x1028
usrJmp      EQU     0x1028
TickIRQAddr             EQU             0x1030
TickIRQAddr             EQU             0x1030
TaskBlock               EQU             0x1038
TaskBlock               EQU             0x1038
tencount                EQU             0x13F8
 
Milliseconds    EQU             0x1400
Milliseconds    EQU             0x1400
Lastloc                 EQU             0x1408
Lastloc                 EQU             0x1408
 
CharColor       EQU             0x1410
ScreenColor     EQU             0x1414
ScreenColor     EQU             0x1414
CursorRow       EQU             0x1416
CursorRow       EQU             0x1417
CursorCol       EQU             0x1418
CursorCol       EQU             0x1418
CursorFlash     EQU             0x141A
CursorFlash     EQU             0x141A
KeybdEcho       EQU             0x141C
KeybdEcho       EQU             0x141C
KeybdBuffer     EQU             0x1440
KeybdBuffer     EQU             0x1440
KeybdHead       EQU             0x1450
KeybdHead       EQU             0x1450
KeybdTail       EQU             0x1451
KeybdTail       EQU             0x1451
 
sp_save         EQU             0x1460
 
lr_save         EQU             0x1468
 
r1_save         EQU             0x1470
 
r2_save         EQU             0x1478
 
r26_save        EQU             0x1480
Score           EQU             0x1500
Score           EQU             0x1500
Manpos          EQU             0x1508
Manpos          EQU             0x1508
MissileActive   EQU             0x1510
MissileActive   EQU             0x1510
MissileX        EQU             0x1512
MissileX        EQU             0x1512
MissileY        EQU             0x1514
MissileY        EQU             0x1514
Line 146... Line 164...
NextToRunTCB    EQU             0x20A8
NextToRunTCB    EQU             0x20A8
r1save                  EQU             0x20B0
r1save                  EQU             0x20B0
r2save                  EQU             0x20B8
r2save                  EQU             0x20B8
AXCstart                EQU             0x20C0
AXCstart                EQU             0x20C0
 
 
 
; Context startup address table
 
;
 
ctx0start               EQU             0x20D0
 
ctx1start               EQU             0x20D8
 
ctx2start               EQU             0x20E0
 
ctx3start               EQU             0x20E8
 
ctx4start               EQU             0x20F0
 
ctx5start               EQU             0x20F8
 
ctx6start               EQU             0x2100
 
ctx7start               EQU             0x2108
 
ctx8start               EQU             0x2110
 
ctx9start               EQU             0x2118
 
ctx10start              EQU             0x2120
 
ctx11start              EQU             0x2128
 
ctx12start              EQU             0x2130
 
ctx13start              EQU             0x2138
 
ctx14start              EQU             0x2140
 
ctx15start              EQU             0x2148
 
sp_saves                EQU             0x2200
 
sp_saves_end    EQU             0x2280
p100IRQvec              EQU             0x3000
p100IRQvec              EQU             0x3000
keybdIRQvec             EQU             0x3008
keybdIRQvec             EQU             0x3008
serialIRQvec    EQU             0x3010
serialIRQvec    EQU             0x3010
rasterIRQvec    EQU             0x3018
rasterIRQvec    EQU             0x3018
 
 
 
startSector     EQU             0x30F8
 
BPB                     EQU             0x3100
 
 
TEXTSCR         EQU             0xD0_0000
TEXTSCR         EQU             0xD0_0000
COLORSCR        EQU             0xD1_0000
COLORSCR        EQU             0xD1_0000
TEXTREG         EQU             0xDA_0000
TEXTREG         EQU             0xDA_0000
TEXT_COLS       EQU             0x0
TEXT_COLS       EQU             0x0
TEXT_ROWS       EQU             0x2
TEXT_ROWS       EQU             0x2
Line 167... Line 208...
UART_MS         EQU             0xDC_0A02
UART_MS         EQU             0xDC_0A02
UART_IS         EQU             0xDC_0A03
UART_IS         EQU             0xDC_0A03
UART_IE         EQU             0xDC_0A04
UART_IE         EQU             0xDC_0A04
UART_MC         EQU             0xDC_0A06
UART_MC         EQU             0xDC_0A06
DATETIME        EQU             0xDC_0400
DATETIME        EQU             0xDC_0400
 
 
 
SPIMASTER       EQU             0xDC_0500
 
SPI_MASTER_VERSION_REG  EQU     0x00
 
SPI_MASTER_CONTROL_REG  EQU     0x01
 
SPI_TRANS_TYPE_REG      EQU             0x02
 
SPI_TRANS_CTRL_REG      EQU             0x03
 
SPI_TRANS_STATUS_REG    EQU     0x04
 
SPI_TRANS_ERROR_REG             EQU     0x05
 
SPI_DIRECT_ACCESS_DATA_REG              EQU     0x06
 
SPI_SD_ADDR_7_0_REG             EQU     0x07
 
SPI_SD_ADDR_15_8_REG    EQU     0x08
 
SPI_SD_ADDR_23_16_REG   EQU     0x09
 
SPI_SD_ADDR_31_24_REG   EQU     0x0a
 
SPI_RX_FIFO_DATA_REG    EQU     0x10
 
SPI_RX_FIFO_DATA_COUNT_MSB      EQU     0x12
 
SPI_RX_FIFO_DATA_COUNT_LSB  EQU 0x13
 
SPI_RX_FIFO_CTRL_REG            EQU     0x14
 
SPI_TX_FIFO_DATA_REG    EQU     0x20
 
SPI_TX_FIFO_CTRL_REG    EQU     0x24
 
SPI_INIT_SD                     EQU             0x01
 
SPI_TRANS_START         EQU             0x01
 
SPI_TRANS_BUSY          EQU             0x01
 
SPI_INIT_NO_ERROR       EQU             0x00
 
SPI_READ_NO_ERROR       EQU             0x00
 
RW_READ_SD_BLOCK        EQU             0x02
 
RW_WRITE_SD_BLOCK       EQU             0x03
 
 
 
 
PIC                     EQU             0xDC_0FF0
PIC                     EQU             0xDC_0FF0
PIC_IE          EQU             0xDC_0FF2
PIC_IE          EQU             0xDC_0FF2
 
 
PSG                     EQU             0xD5_0000
PSG                     EQU             0xD5_0000
PSGFREQ0        EQU             0xD5_0000
PSGFREQ0        EQU             0xD5_0000
Line 178... Line 247...
PSGCTRL0        EQU             0xD5_0004
PSGCTRL0        EQU             0xD5_0004
PSGADSR0        EQU             0xD5_0006
PSGADSR0        EQU             0xD5_0006
 
 
SPRRAM          EQU             0xD8_0000
SPRRAM          EQU             0xD8_0000
AC97            EQU             0xDC_1000
AC97            EQU             0xDC_1000
 
TMP                     EQU             0xDC_0300
LED                     EQU             0xDC_0600
LED                     EQU             0xDC_0600
 
ETHMAC          EQU             0xDC_2000
 
CONFIGREC       EQU             0xDC_FFFF
 
MIIMODER        EQU             0x28
 
MIIADDRESS      EQU             0x30
GACCEL          EQU             0xDA_E000
GACCEL          EQU             0xDA_E000
RASTERIRQ       EQU             0xDA_0100
RASTERIRQ       EQU             0xDA_0100
BOOT_STACK      EQU             0xFFFF_FFFF_FFFE_FFF8
BOOT_STACK      EQU             0xFFFF_FFFF_FFFE_FFF8
SPRITEREGS      EQU             0xDA_D000
SPRITEREGS      EQU             0xDA_D000
BITMAPSCR       EQU             0x00000001_00200000
BITMAPSCR       EQU             0x00000001_00200000
 
 
 
BOOTJMP         EQU             0x100800204
 
 
txempty EQU             0x40
txempty EQU             0x40
rxfull  EQU             0x01
rxfull  EQU             0x01
 
 
;
;
; Internal variables follow:
; Internal variables follow:
;
;
                bss
                bss
                org             0x1038
                org             0x1048
txtWidth        db      0                ; BIOS var =56
txtWidth        db      0                ; BIOS var =56
txtHeight       db      0                ; BIOS var =31
txtHeight       db      0                ; BIOS var =31
cursx   db              0                ; cursor x position
cursx   db              0                ; cursor x position
cursy   db              0                ; cursor y position
cursy   db              0                ; cursor y position
pos             dh              0                ; text screen position
pos             dh              0                ; text screen position
                org             0x1040
 
charToPrint             dc              0
charToPrint             dc              0
fgColor                 db              0
fgColor                 db              0
bkColor                 db              0
bkColor                 db              0
cursFlash               db              0        ; flash the cursor ?
cursFlash               db              0        ; flash the cursor ?
 
 
lineLinkTbl             fill.b  25,0     ; screen line link table
lineLinkTbl             fill.b  47,0     ; screen line link table
                align 8
 
 
 
                org             0x1080
 
typef   db      0   ; variable / expression type
typef   db      0   ; variable / expression type
        align   8
        align   8
OSSP    dw      1       ; OS value of sp
OSSP    dw      1       ; OS value of sp
CURRNT  dw      1       ;       Current line pointer
CURRNT  dw      1       ;       Current line pointer
STKGOS  dw      1       ;       Saves stack pointer in 'GOSUB'
STKGOS  dw      1       ;       Saves stack pointer in 'GOSUB'
Line 254... Line 326...
        jmp             SetKeyboardEcho
        jmp             SetKeyboardEcho
        jmp             KeybdCheckForKey
        jmp             KeybdCheckForKey
        jmp             KeybdGetChar
        jmp             KeybdGetChar
        jmp             DisplayChar
        jmp             DisplayChar
        jmp             DisplayString
        jmp             DisplayString
 
        jmp             DisplayNum
 
        jmp             CalcScreenLoc
 
        jmp             ClearScreen
 
        jmp             DisplayWord
 
 
start:
start:
;       lea             MSGRAM,a1
;       lea             MSGRAM,a1
;       jsr             DisplayString
;       jsr             DisplayString
 
 
ColdStart:
ColdStart:
        icache_on                               ; turn on the ICache
        icache_off                              ; turn on the ICache
        dcache_off                              ; turn on the DCache
        dcache_off                              ; turn on the DCache
 
 
 
; Make sure semaphores are available by closing the gates.
 
; We don't know what power up state is.
 
 
 
        cmgi    #KEYBDGATE
 
        cmgi    #VIDEOGATE
 
 
 
; Initialize the context startup address table with NULL
 
 
 
        xor             r1,r1,r1
 
        sw              r1,ctx0start
 
        sw              r1,ctx1start
 
        sw              r1,ctx2start
 
        sw              r1,ctx3start
 
        sw              r1,ctx4start
 
        sw              r1,ctx5start
 
        sw              r1,ctx6start
 
        sw              r1,ctx7start
 
        sw              r1,ctx8start
 
        sw              r1,ctx9start
 
        sw              r1,ctx10start
 
        sw              r1,ctx11start
 
        sw              r1,ctx12start
 
        sw              r1,ctx13start
 
        sw              r1,ctx14start
 
        sw              r1,ctx15start
 
 
; Initialize the context schedule with all contexts treated equally
; Initialize the context schedule with all contexts treated equally
; There are only 16 contexts, but 256 schedule slots. Each context is
; There are only 16 contexts, but 256 schedule slots. Each context is
; given 16 slots distributed evenly throughout the execution pattern
; given 16 slots distributed evenly throughout the execution pattern
; table.
; table.
;
;
Line 282... Line 384...
; occurs.
; occurs.
;
;
; We cannot use a loop for this. Fortunately there's only 16 contexts.
; We cannot use a loop for this. Fortunately there's only 16 contexts.
;
;
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP0
        lea             r30,STACKTOP0
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP1
        lea             r30,STACKTOP1
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP2
        lea             r30,STACKTOP2
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP3
        lea             r30,STACKTOP3
        iepp
        iepp
        nop
 
        nop
 
 
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP4
        lea             r30,STACKTOP4
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP5
        lea             r30,STACKTOP5
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP6
        lea             r30,STACKTOP6
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP7
        lea             r30,STACKTOP7
        iepp
        iepp
        nop
 
        nop
 
 
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP8
        lea             r30,STACKTOP8
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP9
        lea             r30,STACKTOP9
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP10
        lea             r30,STACKTOP10
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP11
        lea             r30,STACKTOP11
        iepp
        iepp
        nop
 
        nop
 
 
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP12
        lea             r30,STACKTOP12
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP13
        lea             r30,STACKTOP13
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP14
        lea             r30,STACKTOP14
        iepp
        iepp
        nop
 
        nop
 
        lea             r25,ctxstart
        lea             r25,ctxstart
 
        mtspr   IPC,r25
        lea             r30,STACKTOP15
        lea             r30,STACKTOP15
        iepp
        iepp
        nop
 
        nop
 
 
 
; Ensure that context zero is the active context
; Ensure that context zero is the active context
;
;
ctxstart3:
ctxstart3:
        mfspr   r1,AXC
        mfspr   r1,AXC
        beq             r1,r0,ctxstart2
        beq             r1,r0,ctxstart2
        iepp
        iepp
        nop
 
        nop
 
        bra             ctxstart3
        bra             ctxstart3
ctxstart2:
ctxstart2:
        sb              r1,AXCstart             ; save off the startup context which should be context zero
        sb              r1,AXCstart             ; save off the startup context which should be context zero
 
 
; Entry point for context startup
; Entry point for context startup
Line 398... Line 482...
        lea             r1,nmirout
        lea             r1,nmirout
csj5:
csj5:
        sw              r1,[r3]
        sw              r1,[r3]
        addui   r3,r3,#8
        addui   r3,r3,#8
        loop    r2,csj5
        loop    r2,csj5
 
        lea             r1,VideoSC              ; Video BIOS vector
 
        sw              r1,0xCD0
 
        lea             r1,SCCARDSC             ; SD Card BIOS vector
 
        sw              r1,0xCE8
 
        lea             r1,RTCSC                ; Real time clock vector
 
        sw              r1,0xD00
        lea             r1,KeybdSC              ; keyboard BIOS vector
        lea             r1,KeybdSC              ; keyboard BIOS vector
        sw              r1,0xD08
        sw              r1,0xD08
        lea             r1,irqrout
        lea             r1,irqrout
        sw              r1,0xE08                ; set IRQ vector
        sw              r1,0xE08                ; set IRQ vector
 
        lea             r1,ui_irout
 
        sw              r1,0xF78                ; set unimplemented instruction vector
        lea             r1,dberr_rout
        lea             r1,dberr_rout
        sw              r1,0xFE0                ; set Bus error vector
        sw              r1,0xFE0                ; set Bus error vector
        lea             r1,iberr_rout
        lea             r1,iberr_rout
        sw              r1,0xFE8                ; set Bus error vector
        sw              r1,0xFE8                ; set Bus error vector
        lea             r1,nmirout
        lea             r1,nmirout
        sw              r1,0xFF0                ; set NMI vector
        sw              r1,0xFF0                ; set NMI vector
 
 
 
; set system interrupt hook vectors
 
 
        lea             r1,KeybdIRQ
        lea             r1,KeybdIRQ
        sw              r1,keybdIRQvec
        sw              r1,keybdIRQvec
        lea             r1,Pulse100
        lea             r1,Pulse100
        sw              r1,p100IRQvec
        sw              r1,p100IRQvec
        lea             r1,SerialIRQ
        lea             r1,SerialIRQ
Line 421... Line 515...
        sw              r1,rasterIRQvec
        sw              r1,rasterIRQvec
 
 
        ;-------------------------------
        ;-------------------------------
        ; Initialize I/O devices
        ; Initialize I/O devices
        ;-------------------------------
        ;-------------------------------
 
        inbu    r1,CONFIGREC
 
        bfext   r1,r1,#4,#4
 
        beq             r1,r0,skip5
 
        call    tmp_init
 
skip5:
 
        inbu    r1,CONFIGREC
 
        bfext   r1,r1,#5,#5
 
        beq             r1,r0,skip4
        call    SerialInit
        call    SerialInit
 
skip4:
        call    KeybdInit
        call    KeybdInit
        call    PICInit
        call    PICInit
        call    SetupRasterIRQ
        call    SetupRasterIRQ
        cli                                             ; enable interrupts
        cli                                             ; enable interrupts
;       call    HelloWorld
;       call    HelloWorld
        setlo   r3,#0xCE                ; blue on blue
        setlo   r3,#0xCE                ; blue on blue
        sc              r3,ScreenColor
        sc              r3,ScreenColor
 
        sc              r3,CharColor
        lc              r3,0x1414
        lc              r3,0x1414
        setlo   r3,#32
        setlo   r3,#32
        sc              r3,0x1416               ; we do a store, then a load through the dcache
        sc              r3,0x1416               ; we do a store, then a load through the dcache
        lc              r2,0x1416               ;
        lc              r2,0x1416               ;
        beq             r2,r3,dcokay
        beq             r2,r3,dcokay
        dcache_off                              ; data cache failed
        dcache_off                              ; data cache failed
dcokay:
dcokay:
        sc              r0,NextToRunTCB
        sc              r0,NextToRunTCB
        sc              r0,RunningTCB
        sc              r0,RunningTCB
 
        lw              r1,#2                   ; get rid of startup keyboard glitchs by trying to get a character
 
        syscall #417
 
        lw              r1,#2                   ; get rid of startup keyboard glitchs by trying to get a character
 
        syscall #417
 
 
 
        ; wait for screen to be available
        call    ClearScreen
        call    ClearScreen
        call    ClearBmpScreen
        call    ClearBmpScreen
 
 
 
; Test whether or not the sprite controller is present. Skip
 
; Initialization if it isn't.
 
 
 
        inb             r1,CONFIGREC
 
        bfext   r1,r1,#0,#0
 
        beq             r1,r0,skip1
        call    RandomizeSprram
        call    RandomizeSprram
        sc              r0,CursorRow
skip1:
        sc              r0,CursorCol
 
        setlo   r1,#1
        sb              r0,CursorRow
 
        sb              r0,CursorCol
 
        lw              r1,#1
        sb              r1,CursorFlash
        sb              r1,CursorFlash
        lea             r1,MSGSTART
        lea             r1,MSGSTART
        call    DisplayStringCRLF
        call    DisplayStringCRLF
        jmp             Monitor
 
 
; Test whether or not sound generator is present
 
; skip initialization and beep if not present
 
 
 
        inb             r1,CONFIGREC
 
        bfext   r1,r1,#2,#2
 
        beq             r1,r0,skip2
        call    SetupAC97               ; and Beep
        call    SetupAC97               ; and Beep
        setlo   r3,#4
        lw              r1,#4
        outb    r3,LED
        outb    r1,LED
        call    Beep
        call    Beep
 
skip2:
 
 
 
        lea             r1,context1disp ; start a display
 
        sw              r1,ctx1start
 
 
 
; Startup Ethernet access ?
 
;
 
        inb             r1,CONFIGREC
 
        bfext   r1,r1,#1,#1
 
        beq             r1,r0,skip3
 
        lea             r1,eth_main
 
        sw              r1,ctx2start
 
skip3:
 
 
 
        lea             r1,RandomLines
 
        sw              r1,ctx3start
 
        call    spi_init
 
        bne             r1,r0,skip_spi_read
 
        call    spi_read_boot
 
        call    loadBootFile
 
skip_spi_read:
 
        jmp             Monitor
 
 
j4:
j4:
        jmp             Monitor
        jmp             Monitor
        bra             j4
        bra             j4
 
 
; for now hang the contexts
; The contexts wait for a context startup address to be placed in the
 
; startup table. Once an address is in the table, a call to the context
 
; code will be made. The default is a NULL pointer, which
 
; causes the context to loop around back to here while waiting for a
 
; code to run.
;
;
ctxstart1:
ctxstart1:
 
        lea             r1,ctx0start    ; r1 = context start table base
 
        mfspr   r2,AXC                  ; r2 = index into start table
 
        lw              r1,[r1+r2*8]    ; r1 = context start address
 
        beq             r1,r0,ctx12
 
        jal             lr,[r1]                 ; perform a call to the context code
 
 
 
; We might as well move to the next context, since there's nothing
 
; to do. This can be accomplished by tirggering a IRQ interrupt.
 
; We can't just increment the excution pattern pointer, because that
 
; would only switch the register set and not the program counter.
 
; An interrupt saves the program counter, and restores it from the
 
; IPC context register.
 
;
 
ctx12:
 
        sei                                     ; causes a priv violation. don't allow interrupts during syscall
 
        nop                                     ; wait for sei to take effect
 
        nop
 
        nop
 
        syscall #EX_IRQ
        bra             ctxstart1
        bra             ctxstart1
 
 
;       call    ramtest
;       call    ramtest
 
 
 
context1disp:
 
 
 
; once we've started, clear the start vector so that the context
 
; isn't continuously restarted.
 
;
 
        sw              r0,ctx1start
 
        lea             r3,TEXTSCR
 
        lw              r1,#'V'
 
        lw              r2,#330
 
        lw              r4,#47
 
        call    AsciiToScreen
 
ctx11:
 
        inch    r1,[r3+r2]
 
        addui   r1,r1,#1
 
        outc    r1,[r3+r2]
 
        addui   r2,r2,#168
 
        loop    r4,ctx11
 
        bra             context1disp
 
 
;-----------------------------------------
;-----------------------------------------
; Hello World!
; Hello World!
;-----------------------------------------
;-----------------------------------------
HelloWorld:
HelloWorld:
        subui   r30,r30,#24
        subui   r30,r30,#24
Line 496... Line 685...
 
 
        align 16
        align 16
 
 
;----------------------------------------------------------
;----------------------------------------------------------
; Initialize programmable interrupt controller (PIC)
; Initialize programmable interrupt controller (PIC)
;  0 = nmi
;  0 = nmi (parity error)
;  1 = keyboard reset
;  1 = keyboard reset
;  2 = 1000Hz pulse (context switcher)
;  2 = 1000Hz pulse (context switcher)
;  3 = 100Hz pulse (cursor flash)
;  3 = 100Hz pulse (cursor flash)
 
;  4 = ethmac
;  8 = uart
;  8 = uart
; 13 = raster interrupt
; 13 = raster interrupt
; 15 = keyboard char
; 15 = keyboard char
;----------------------------------------------------------
;----------------------------------------------------------
PICInit:
PICInit:
        lea             r1,PICret
        lea             r1,PICret
        sw              r1,TickIRQAddr
        sw              r1,TickIRQAddr
        ; enable: raster irq,
        ; enable: raster irq,
        setlo   r1,#0xA00F      ; enable nmi,kbd_rst,and kbd_irq
        setlo   r1,#0x800F      ; enable nmi,kbd_rst,and kbd_irq
        ; A10F enable serial IRQ
        ; A10F enable serial IRQ
        outc    r1,PIC_IE
        outc    r1,PIC_IE
PICret:
PICret:
        ret
        ret
 
 
Line 791... Line 981...
        outb    r1,UART
        outb    r1,UART
srxirq8:
srxirq8:
        bra             sirq1
        bra             sirq1
 
 
;==============================================================================
;==============================================================================
 
; Video BIOS
 
; Video interrupt #410
 
;
 
; Function in R1
 
; 0x02 = Set Cursor Position    r2 = row, r3 = col 
 
; 0x03 = Get Cursor position    returns r1 = row, r2 = col
 
; 0x06 = Scroll screen up
 
; 0x09 = Display character+attribute, r2=char, r3=attrib, r4=#times
 
; 0x0A = Display character, r2 = char, r3 = # times
 
; 0x0C = Display Pixel r2 = x, r3 = y, r4 = color
 
; 0x0D = Get pixel  r2 = x, r3 = y
 
; 0x14 = Display String r2 = pointer to string
 
; 0x15 = Display number r2 = number, r3 = # digits
 
; 0x16 = Display String + CRLF   r2 = pointer to string
 
; 0x17 = Display Word r2 as hex = word
 
; 0x18 = Display Half word as hex r2 = half word
 
; 0x19 = Display Charr char in hex r2 = char
 
; 0x1A = Display Byte in hex r2 = byte
 
;==============================================================================
 
;
 
VideoSC:
 
        mfspr   r26,AXC                         ; get context
 
        shlui   r26,r26,#3                      ; *8
 
        sw              sp,sp_saves[r26]        ; save sp in save area
 
        shlui   r26,r26,#8                      ; 2k for stack
 
        mov             sp,r26
 
        addui   sp,sp,#0x100008000      ; base stacks address
 
        subui   sp,sp,#8
 
        sw              lr,[sp]
 
Video1:
 
        omgi    lr,#VIDEOGATE
 
        bne             lr,r0,Video1
 
        beqi    r1,#0x02,Video_x02
 
        beqi    r1,#0x03,Video_x03
 
        beqi    r1,#0x06,Video_x06
 
        beqi    r1,#0x09,Video_x09
 
        beqi    r1,#0x0A,Video_x0A
 
        beqi    r1,#0x0C,Video_x0C
 
        beqi    r1,#0x0C,Video_x0D
 
        beqi    r1,#0x14,Video_x14
 
        beqi    r1,#0x15,Video_x15
 
        beqi    r1,#0x16,Video_x16
 
        beqi    r1,#0x17,Video_x17
 
        beqi    r1,#0x1A,Video_x1A
 
        bra             VideoRet
 
 
 
Video_x02:
 
        sb              r2,CursorRow
 
        sb              r3,CursorCol
 
        call    CalcScreenLoc
 
        bra             VideoRet
 
 
 
Video_x03:
 
        lbu             r1,CursorRow
 
        lbu             r2,CursorCol
 
        bra             VideoRet
 
 
 
Video_x06:
 
        call    ScrollUp
 
        bra             VideoRet
 
 
 
Video_x09:
 
        sc              r3,CharColor
 
        mov             r1,r2
 
Video_x09a:
 
        call    DisplayChar
 
        loop    r4,Video_x09a
 
        bra             VideoRet
 
 
 
Video_x0A:
 
        mov             r1,r2
 
Video_x0Aa:
 
        call    DisplayChar
 
        loop    r3,Video_x0Aa
 
        bra             VideoRet
 
 
 
Video_x0C:
 
        sh              r2,GACCEL+8             ; x0
 
        sh              r3,GACCEL+12    ; y0
 
        sh              r4,GACCEL+0              ; color
 
        lw              r1,#1
 
        sh              r1,GACCEL+60    ; DRAW PIXEL command
 
        bra             VideoRet
 
 
 
Video_x0D:
 
        sh              r2,GACCEL+8             ; x0
 
        sh              r3,GACCEL+12    ; y0
 
        lw              r1,#8
 
        sh              r1,GACCEL+60    ; GET PIXEL command
 
        nop                                             ; let command start
 
        nop
 
        nop
 
vxd1:
 
        lhu             r1,GACCEL+56    ; wait for state = IDLE
 
        bne             r1,r0,vxd1
 
        lhu             r1,GACCEL+52
 
        bra             VideoRet
 
 
 
Video_x14:
 
        mov             r1,r2
 
        call    DisplayString
 
        bra             VideoRet
 
 
 
Video_x15:
 
        mov             r1,r2
 
        mov             r2,r3
 
        call    DisplayNum
 
        bra             VideoRet
 
 
 
Video_x16:
 
        mov             r1,r2
 
        call    DisplayStringCRLF
 
        bra             VideoRet
 
 
 
Video_x17:
 
        mov             r1,r2
 
        call    DisplayWord
 
        bra             VideoRet
 
 
 
Video_x1A:
 
        mov             r1,r2
 
        call    DisplayByte
 
        bra             VideoRet
 
 
 
VideoRet:
 
        cmgi    #VIDEOGATE
 
        lw              lr,[sp]
 
        mfspr   r26,AXC                         ; get context
 
        shlui   r26,r26,#3                      ; *8
 
        lw              sp,sp_saves[r26]        ; get back the stack
 
        eret
 
 
 
;==============================================================================
 
; BIOS interrupt #413
 
; 0x00  initialize
 
; 0x01  read sector             r2 = sector #, r3 = pointer to buffer
 
; 0x02  write sector
 
;==============================================================================
 
;
 
SDCARDSC:
 
        mfspr   r26,AXC                         ; get context
 
        shlui   r26,r26,#3                      ; *8
 
        sw              sp,sp_saves[r26]        ; save sp in save area
 
        shlui   r26,r26,#8                      ; 2k for stack
 
        mov             sp,r26
 
        addui   sp,sp,#0x100008000      ; base stacks address
 
        subui   sp,sp,#8
 
        sw              lr,[sp]
 
SDC_1:
 
        omgi    lr,#CARDGATE
 
        bne             lr,r0,SDC_1
 
        beqi    r1,#0,SDC_x00
 
        beqi    r1,#1,SDC_x01
 
        beqi    r1,#2,SDC_x02
 
        bra             SDCRet
 
SDC_x00:
 
        call    spi_init
 
        bra             SDCRet
 
SDC_x01:
 
        mov             r1,r2
 
        mov             r2,r3
 
        call    spi_read_sector
 
        bra             SDCRet
 
SDC_x02:
 
SDCRet:
 
        cmgi    #CARDGATE
 
        lw              lr,[sp]
 
        mfspr   r26,AXC                         ; get context
 
        shlui   r26,r26,#3                      ; *8
 
        lw              sp,sp_saves[r26]        ; get back the stack
 
        eret
 
 
 
;==============================================================================
 
; Real time clock BIOS
 
; BIOS interrupt #416
 
;
 
; Function
 
; 0x00 = get system tick
 
; 0x01 = get date/time
 
; 0x02 = set date/time
 
;==============================================================================
 
;
 
RTCSC:
 
        mfspr   r26,AXC                         ; get context
 
        shlui   r26,r26,#3                      ; *8
 
        sw              sp,sp_saves[r26]        ; save sp in save area
 
        shlui   r26,r26,#8                      ; 2k for stack
 
        mov             sp,r26
 
        addui   sp,sp,#0x100008000      ; base stacks address
 
        subui   sp,sp,#8
 
        sw              lr,[sp]
 
        ;
 
        beqi    r1,#0x00,RTC_x00
 
        beqi    r1,#0x01,RTC_x01
 
RTC_x00:
 
        mfspr   r1,TICK
 
        bra             RTCRet
 
RTC_x01:
 
        outw    r0,DATETIME+24          ; trigger a snapshot
 
        nop
 
        inw             r1,DATETIME                     ; get the snapshotted date and time
 
        bra             RTCRet
 
RTCRet:
 
        lw              lr,[sp]
 
        mfspr   r26,AXC                         ; get context
 
        shlui   r26,r26,#3                      ; *8
 
        lw              sp,sp_saves[r26]        ; get back the stack
 
        eret
 
 
 
;==============================================================================
; Keyboard BIOS
; Keyboard BIOS
; BIOS interrupt #417
; BIOS interrupt #417
;
;
; Function in R1
; Function in R1
; 0 = initialize keyboard
; 0x00 = initialize keyboard
; 1 = set keyboard echo
; 0x01 = set keyboard echo
; 2 = get keyboard character
; 0x02 = get keyboard character from buffer
; 3 = check for key available
; 0x03 = check for key available in buffer
 
; 0x04 = check for key directly at keyboard port
 
; 0x05 = get keyboard character directly from keyboard port (blocks)
;==============================================================================
;==============================================================================
;
;
KeybdSC:
KeybdSC:
 
        mfspr   r26,AXC                         ; get context
 
        shlui   r26,r26,#3                      ; *8
 
        sw              sp,sp_saves[r26]        ; save sp in save area
 
        shlui   r26,r26,#8                      ; 2k for stack
 
        mov             sp,r26
 
        addui   sp,sp,#0x100008000      ; base stacks address
        subui   sp,sp,#8
        subui   sp,sp,#8
        sw              lr,[sp]
        sw              lr,[sp]
        bnei    r1,#0,kbdsc1
kbdsc5:
 
        omgi    lr,#KEYBDGATE
 
        bne             lr,r0,kbdsc5
 
        beqi    r1,#0,kbd_x00
 
        beqi    r1,#1,kbd_x01
 
        beqi    r1,#2,kbd_x02
 
        beqi    r1,#3,kbd_x03
 
        beqi    r1,#4,kbd_x04
 
        beqi    r1,#5,kbd_x05
 
        bra             kbdscRet
 
kbd_x00:
        call    KeybdInit
        call    KeybdInit
        bra             kbdscRet
        bra             kbdscRet
kbdsc1:
kbd_x01:
        bnei    r1,#1,kbdsc2
 
        mov             r1,r2
        mov             r1,r2
        call    SetKeyboardEcho
        call    SetKeyboardEcho
        bra             kbdscRet
        bra             kbdscRet
kbdsc2:
kbd_x02:
        bnei    r1,#2,kbdsc3
 
        call    KeybdGetChar
        call    KeybdGetChar
        bra             kbdscRet
        bra             kbdscRet
kbdsc3:
kbd_x03:
        bnei    r1,#3,kbdsc4
 
        call    KeybdCheckForKey
        call    KeybdCheckForKey
        bra             kbdscRet
        bra             kbdscRet
kbdsc4:
kbd_x04:
 
        call    KeybdCheckForKeyDirect
 
        bra             kbdscRet
 
kbd_x05:
 
        call    KeybdGetCharDirect
 
        bra             kbdscRet
kbdscRet:
kbdscRet:
 
        cmgi    #KEYBDGATE
        lw              lr,[sp]
        lw              lr,[sp]
        addui   sp,sp,#8
        mfspr   r26,AXC                         ; get context
 
        shlui   r26,r26,#3                      ; *8
 
        lw              sp,sp_saves[r26]        ; get back the stack
        eret
        eret
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Initialize keyboard
; Initialize keyboard
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
Line 948... Line 1371...
        lw              lr,8[sp]
        lw              lr,8[sp]
        ret             #16
        ret             #16
 
 
;==============================================================================
;==============================================================================
;==============================================================================
;==============================================================================
 
tmp_init:
 
        ; wait for the rst1626 to go low
 
        lw              r2,#10000000    ; retry for up to several seconds
 
tmp_init4:
 
        beq             r2,r0,tmp_init5
 
        subui   r2,r2,#1
 
        inch    r1,TMP+2        ; read the status reg
 
        blt             r1,r0,tmp_init4
 
tmp_init5:
 
 
 
        lw              r1,#0x51        ; Start temperature conversion
 
        outc    r1,TMP
 
 
 
        ; wait a bit for the trigger to take effect
 
        lw              r1,#2500
 
tmp_init1:
 
        loop    r1,tmp_init1
 
 
 
        ; wait for the rst1626 to go low
 
        lw              r2,#10000000    ; retry for up to several seconds
 
tmp_init2:
 
        beq             r2,r0,tmp_init3
 
        subui   r2,r2,#1
 
        inch    r1,TMP+2        ; read the status reg
 
        blt             r1,r0,tmp_init2
 
tmp_init3:
 
        ret
 
 
 
tmp_read:
 
        subui   sp,sp,#24
 
        sw              lr,[sp]
 
        sw              r1,8[sp]
 
        sw              r2,16[sp]
 
 
 
        lw              r1,#25000000    ; wait about 1 second or so
 
tmp_read1:
 
        loop    r1,tmp_read1
 
        lw              r1,#0xAC        ; issue read temperature conversion
 
        outc    r1,TMP
 
 
 
        ; wait a bit for the trigger to take effect
 
        lw              r1,#2500
 
tmp_read3:
 
        loop    r1,tmp_read3
 
 
 
        ; wait for the rst1626 to go low
 
        lw              r2,#10000000
 
tmp_read2:
 
        inch    r1,TMP+2        ; read the status reg
 
        beq             r2,r0,tmp_read4
 
        subui   r2,r2,#1
 
        blt             r1,r0,tmp_read2
 
tmp_read4:
 
        inch    r1,TMP+2                ; read the temperature
 
        lw              r2,#5                   ; five digits
 
        call    DisplayNum
 
        lw              lr,[sp]
 
        lw              r1,8[sp]
 
        lw              r2,16[sp]
 
        ret             #24
 
 
 
;==============================================================================
 
;==============================================================================
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; 100 Hz interrupt
; 100 Hz interrupt
; - takes care of "flashing" the cursor
; - takes care of "flashing" the cursor
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
;
Line 960... Line 1446...
        sw              lr,[sp]
        sw              lr,[sp]
        lea             r2,TEXTSCR
        lea             r2,TEXTSCR
        inch    r1,334[r2]
        inch    r1,334[r2]
        addui   r1,r1,#1
        addui   r1,r1,#1
        outc    r1,334[r2]
        outc    r1,334[r2]
        call    DisplayDatetime
;       call    DisplayDatetime
        call    SelectNextToRunTCB
        call    SelectNextToRunTCB
        call    SwitchTask
        call    SwitchTask
        sb              r0,0xFFFF_FFFF_FFFF_0010        ; clear interrupt
        outb    r0,0xDCFFFC             ; clear interrupt
;       lw              r1,TickIRQAddr
;       lw              r1,TickIRQAddr
;       jal             r31,[r1]
;       jal             r31,[r1]
;       lw              r1,Milliseconds
;       lw              r1,Milliseconds
;       andi    r1,r1,#0x0f
;       andi    r1,r1,#0x0f
;       bnei    r1,#5,p1001
;       bnei    r1,#5,p1001
Line 1184... Line 1670...
        inch    r2,TEXT_ROWS[r3]
        inch    r2,TEXT_ROWS[r3]
        mulu    r2,r1,r2                        ; calc number of chars to scroll
        mulu    r2,r1,r2                        ; calc number of chars to scroll
        subu    r2,r2,r1                        ; one less row
        subu    r2,r2,r1                        ; one less row
        lea             r3,TEXTSCR
        lea             r3,TEXTSCR
scrup1:
scrup1:
        inch    r4,[r3+r1]                      ; indexed addressing example
        inch    r4,[r3+r1*2]            ; indexed addressing example
        outc    r4,[r3]
        outc    r4,[r3]
        addui   r3,r3,#2
        addui   r3,r3,#2
        loop    r2,scrup1
        loop    r2,scrup1
 
 
        lea             r3,TEXTREG
        lea             r3,TEXTREG
Line 1235... Line 1721...
        andi    r1,r1,#0x00ff
        andi    r1,r1,#0x00ff
        bltui   r1,#'A',atoscr1
        bltui   r1,#'A',atoscr1
        bleui   r1,#'Z',atoscr1
        bleui   r1,#'Z',atoscr1
        bgtui   r1,#'z',atoscr1
        bgtui   r1,#'z',atoscr1
        bltui   r1,#'a',atoscr1
        bltui   r1,#'a',atoscr1
        subi    r1,r1,#0x60
        subui   r1,r1,#0x60
atoscr1:
atoscr1:
        ori             r1,r1,#0x100
        ori             r1,r1,#0x100
        ret
        ret
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
Line 1259... Line 1745...
; Destroys r1,r2,r3
; Destroys r1,r2,r3
; r1 = screen location
; r1 = screen location
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
;
CalcScreenLoc:
CalcScreenLoc:
        lc              r1,CursorRow
        lbu             r1,CursorRow
        andi    r1,r1,#0x7f
        andi    r1,r1,#0x7f
        lea             r3,TEXTREG
        lea             r3,TEXTREG
        inch    r2,TEXT_COLS[r3]
        inch    r2,TEXT_COLS[r3]
        mulu    r2,r2,r1
        mulu    r2,r2,r1
        lc              r1,CursorCol
        lbu             r1,CursorCol
        andi    r1,r1,#0x7f
        andi    r1,r1,#0x7f
        addu    r2,r2,r1
        addu    r2,r2,r1
        outc    r2,TEXT_CURPOS[r3]
        outc    r2,TEXT_CURPOS[r3]
        shli    r2,r2,#1
        shlui   r2,r2,#1
        addui   r1,r2,#TEXTSCR                  ; r1 = screen location
        addui   r1,r2,#TEXTSCR                  ; r1 = screen location
        ret
        ret
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Display a character on the screen
; Display a character on the screen
Line 1284... Line 1770...
        subui   sp,sp,#32
        subui   sp,sp,#32
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r2,8[sp]
        sw              r2,8[sp]
        sw              r3,16[sp]
        sw              r3,16[sp]
        sw              lr,24[sp]
        sw              lr,24[sp]
        sc              r0,CursorCol            ; just set cursor column to zero on a CR
        sb              r0,CursorCol            ; just set cursor column to zero on a CR
        bra             dcx7
        bra             dcx7
dccr:
dccr:
 
;       beqi    r1,#CTRLK,dccr1
        bnei    r1,#0x91,dcx6           ; cursor right ?
        bnei    r1,#0x91,dcx6           ; cursor right ?
 
dccr1:
        subui   sp,sp,#32
        subui   sp,sp,#32
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r2,8[sp]
        sw              r2,8[sp]
        sw              r3,16[sp]
        sw              r3,16[sp]
        sw              lr,24[sp]
        sw              lr,24[sp]
        lc              r2,CursorCol
        lbu             r2,CursorCol
        beqi    r2,#56,dcx7
        beqi    r2,#56,dcx7
        addui   r2,r2,#1
        addui   r2,r2,#1
        sc              r2,CursorCol
        sb              r2,CursorCol
dcx7:
dcx7:
        call    CalcScreenLoc
        call    CalcScreenLoc
        lw              lr,24[sp]
        lw              lr,24[sp]
        lw              r3,16[sp]
        lw              r3,16[sp]
        lw              r2,8[sp]
        lw              r2,8[sp]
        lw              r1,[sp]
        lw              r1,[sp]
        ret             #32
        ret             #32
dcx6:
dcx6:
 
;       beqi    r1,#CTRLI,dccu1
        bnei    r1,#0x90,dcx8           ; cursor up ?
        bnei    r1,#0x90,dcx8           ; cursor up ?
 
dccu1:
        subui   sp,sp,#32
        subui   sp,sp,#32
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r2,8[sp]
        sw              r2,8[sp]
        sw              r3,16[sp]
        sw              r3,16[sp]
        sw              lr,24[sp]
        sw              lr,24[sp]
        lc              r2,CursorRow
        lbu             r2,CursorRow
        beqi    r2,#0,dcx7
        beqi    r2,#0,dcx7
        subui   r2,r2,#1
        subui   r2,r2,#1
        sc              r2,CursorRow
        sb              r2,CursorRow
        bra             dcx7
        bra             dcx7
dcx8:
dcx8:
 
;       beqi    r1,#CTRLJ,dccl1
        bnei    r1,#0x93,dcx9           ; cursor left ?
        bnei    r1,#0x93,dcx9           ; cursor left ?
 
dccl1:
        subui   sp,sp,#32
        subui   sp,sp,#32
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r2,8[sp]
        sw              r2,8[sp]
        sw              r3,16[sp]
        sw              r3,16[sp]
        sw              lr,24[sp]
        sw              lr,24[sp]
        lc              r2,CursorCol
        lbu             r2,CursorCol
        beqi    r2,#0,dcx7
        beqi    r2,#0,dcx7
        subui   r2,r2,#1
        subui   r2,r2,#1
        sc              r2,CursorCol
        sb              r2,CursorCol
        bra             dcx7
        bra             dcx7
dcx9:
dcx9:
 
;       beqi    r1,#CTRLM,dccd1
        bnei    r1,#0x92,dcx10          ; cursor down ?
        bnei    r1,#0x92,dcx10          ; cursor down ?
 
dccd1:
        subui   sp,sp,#32
        subui   sp,sp,#32
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r2,8[sp]
        sw              r2,8[sp]
        sw              r3,16[sp]
        sw              r3,16[sp]
        sw              lr,24[sp]
        sw              lr,24[sp]
        lc              r2,CursorRow
        lbu             r2,CursorRow
        beqi    r2,#30,dcx7
        beqi    r2,#30,dcx7
        addui   r2,r2,#1
        addui   r2,r2,#1
        sc              r2,CursorRow
        sb              r2,CursorRow
        bra             dcx7
        bra             dcx7
dcx10:
dcx10:
        bnei    r1,#0x94,dcx11                  ; cursor home ?
        bnei    r1,#0x94,dcx11                  ; cursor home ?
        subui   sp,sp,#32
        subui   sp,sp,#32
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r2,8[sp]
        sw              r2,8[sp]
        sw              r3,16[sp]
        sw              r3,16[sp]
        sw              lr,24[sp]
        sw              lr,24[sp]
        lc              r2,CursorCol
        lbu             r2,CursorCol
        beq             r2,r0,dcx12
        beq             r2,r0,dcx12
        sc              r0,CursorCol
        sb              r0,CursorCol
        bra             dcx7
        bra             dcx7
dcx12:
dcx12:
        sc              r0,CursorRow
        sb              r0,CursorRow
        bra             dcx7
        bra             dcx7
dcx11:
dcx11:
        subui   sp,sp,#48
        subui   sp,sp,#48
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r2,8[sp]
        sw              r2,8[sp]
Line 1364... Line 1858...
        sw              r4,24[sp]
        sw              r4,24[sp]
        sw              r5,32[sp]
        sw              r5,32[sp]
        sw              lr,40[sp]
        sw              lr,40[sp]
        bnei    r1,#0x99,dcx13          ; delete ?
        bnei    r1,#0x99,dcx13          ; delete ?
        call    CalcScreenLoc
        call    CalcScreenLoc
        or              r3,r0,r1                        ; r3 = screen location
        mov             r3,r1                           ; r3 = screen location
        lc              r1,CursorCol            ; r1 = cursor column
        lbu             r1,CursorCol            ; r1 = cursor column
        bra             dcx5
        bra             dcx5
dcx13:
dcx13:
        bnei    r1,#CTRLH,dcx3          ; backspace ?
        bnei    r1,#CTRLH,dcx3          ; backspace ?
        lc              r2,CursorCol
        lbu             r2,CursorCol
        beq             r2,r0,dcx4
        beq             r2,r0,dcx4
        subui   r2,r2,#1
        subui   r2,r2,#1
        sc              r2,CursorCol
        sb              r2,CursorCol
        call    CalcScreenLoc           ; a0 = screen location
        call    CalcScreenLoc           ; a0 = screen location
        or              r3,r0,r1                        ; r3 = screen location
        mov             r3,r1                           ; r3 = screen location
        lc              r1,CursorCol
        lbu             r1,CursorCol
dcx5:
dcx5:
        inch    r2,2[r3]
        inch    r2,2[r3]
        outc    r2,[r3]
        outc    r2,[r3]
        addui   r3,r3,#2
        addui   r3,r3,#2
        addui   r1,r1,#1
        addui   r1,r1,#1
Line 1390... Line 1884...
        call    AsciiToScreen
        call    AsciiToScreen
        outc    r1,-2[r3]
        outc    r1,-2[r3]
        bra             dcx4
        bra             dcx4
dcx3:
dcx3:
        beqi    r1,#'\n',dclf   ; linefeed ?
        beqi    r1,#'\n',dclf   ; linefeed ?
        or              r4,r0,r1                ; save r1 in r4
        mov             r4,r1                   ; save r1 in r4
        call    CalcScreenLoc   ; r1 = screen location
        call    CalcScreenLoc   ; r1 = screen location
        or              r3,r0,r1                ; r3 = screen location
        mov             r3,r1                   ; r3 = screen location
        or              r1,r0,r4                ; restore r1
        mov             r1,r4                   ; restore r1
        call    AsciiToScreen   ; convert ascii char to screen char
        call    AsciiToScreen   ; convert ascii char to screen char
        outc    r1,[r3]
        outc    r1,[r3]
 
        lc              r1,CharColor
 
        outc    r1,0x10000[r3]
        call    IncCursorPos
        call    IncCursorPos
        bra             dcx4
        bra             dcx4
dclf:
dclf:
        call    IncCursorRow
        call    IncCursorRow
dcx4:
dcx4:
Line 1420... Line 1916...
        subui   sp,sp,#32
        subui   sp,sp,#32
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r2,8[sp]
        sw              r2,8[sp]
        sw              r3,16[sp]
        sw              r3,16[sp]
        sw              lr,24[sp]
        sw              lr,24[sp]
        lc              r1,CursorCol
        lbu             r1,CursorCol
        addui   r1,r1,#1
        addui   r1,r1,#1
        sc              r1,CursorCol
        sb              r1,CursorCol
        inch    r2,TEXTREG+TEXT_COLS
        inch    r2,TEXTREG+TEXT_COLS
        bleu    r1,r2,icc1
        bleu    r1,r2,icc1
        sc              r0,CursorCol            ; column = 0
        sb              r0,CursorCol            ; column = 0
        bra             icr1
        bra             icr1
IncCursorRow:
IncCursorRow:
        subui   sp,sp,#32
        subui   sp,sp,#32
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r2,8[sp]
        sw              r2,8[sp]
        sw              r3,16[sp]
        sw              r3,16[sp]
        sw              lr,24[sp]
        sw              lr,24[sp]
icr1:
icr1:
        lc              r1,CursorRow
        lbu             r1,CursorRow
        addui   r1,r1,#1
        addui   r1,r1,#1
        sc              r1,CursorRow
        sb              r1,CursorRow
        inch    r2,TEXTREG+TEXT_ROWS
        inch    r2,TEXTREG+TEXT_ROWS
        bleu    r1,r2,icc1
        bleu    r1,r2,icc1
        subui   r2,r2,#1                        ; backup the cursor row, we are scrolling up
        subui   r2,r2,#1                        ; backup the cursor row, we are scrolling up
        sc              r2,CursorRow
        sb              r2,CursorRow
        call    ScrollUp
        call    ScrollUp
icc1:
icc1:
        call    CalcScreenLoc
        call    CalcScreenLoc
        lw              lr,24[sp]
        lw              lr,24[sp]
        lw              r3,16[sp]
        lw              r3,16[sp]
Line 1455... Line 1951...
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Display a string on the screen.
; Display a string on the screen.
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
;
DisplayString:
DisplayString:
        subi    sp,sp,#24
        subui   sp,sp,#24
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r2,8[sp]
        sw              r2,8[sp]
        sw              lr,16[sp]
        sw              lr,16[sp]
        mov             r2,r1                   ; r2 = pointer to string
        mov             r2,r1                   ; r2 = pointer to string
dspj1:
dspj1:
Line 1480... Line 1976...
        call    DisplayString
        call    DisplayString
        lw              r31,[r30]
        lw              r31,[r30]
        addui   r30,r30,#8
        addui   r30,r30,#8
 
 
CRLF:
CRLF:
        subui   r30,r30,#16
        subui   sp,sp,#16
        sw              r1,[sp]
        sw              r1,[sp]
        sw              lr,8[sp]
        sw              lr,8[sp]
        setlo   r1,#'\r'
        setlo   r1,#'\r'
        call    DisplayChar
        call    DisplayChar
        setlo   r1,#'\n'
        setlo   r1,#'\n'
        call    DisplayChar
        call    DisplayChar
        lw              lr,8[sp]
        lw              lr,8[sp]
        lw              r1,[sp]
        lw              r1,[sp]
        ret             #16
        ret             #16
 
 
 
; Call the Tiny BASIC routine to display a number
 
;
 
DisplayNum:
 
        jmp             PRTNUM
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Display nybble in r1
; Display nybble in r1
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
;
DisplayNybble:
DisplayNybble:
Line 1526... Line 2027...
        lw              lr,8[sp]
        lw              lr,8[sp]
        lw              r1,[sp]
        lw              r1,[sp]
        ret             #16
        ret             #16
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
; Display the char in r1
 
;------------------------------------------------------------------------------
 
;
 
DisplayCharr:
 
        subui   sp,sp,#16
 
        sw              r1,[sp]
 
        sw              lr,8[sp]
 
        rori    r1,r1,#8
 
        call    DisplayByte
 
        roli    r1,r1,#8
 
        call    DisplayByte
 
        lw              lr,8[sp]
 
        lw              r1,[sp]
 
        ret             #16
 
 
 
;------------------------------------------------------------------------------
 
; Display the half-word in r1
 
;------------------------------------------------------------------------------
 
;
 
DisplayHalf:
 
        subui   sp,sp,#16
 
        sw              r1,[sp]
 
        sw              lr,8[sp]
 
        rori    r1,r1,#16
 
        call    DisplayCharr
 
        roli    r1,r1,#16
 
        call    DisplayCharr
 
        lw              lr,8[sp]
 
        lw              r1,[sp]
 
        ret             #16
 
 
 
;------------------------------------------------------------------------------
; Display the 64 bit word in r1
; Display the 64 bit word in r1
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
;
DisplayWord:
DisplayWord:
        subui   sp,sp,#24
        subui   sp,sp,#24
Line 1549... Line 2082...
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Display memory pointed to by r2.
; Display memory pointed to by r2.
; destroys r1,r3
; destroys r1,r3
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
;
DisplayMem:
DisplayMemB:
        subui   sp,sp,#24
        subui   sp,sp,#24
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r3,8[sp]
        sw              r3,8[sp]
        sw              lr,16[sp]
        sw              lr,16[sp]
        setlo   r1,#':'
        setlo   r1,#':'
Line 1562... Line 2095...
        call    DisplayWord
        call    DisplayWord
        setlo   r3,#7
        setlo   r3,#7
dspmem1:
dspmem1:
        setlo   r1,#' '
        setlo   r1,#' '
        call    DisplayChar
        call    DisplayChar
        lb              r1,[r2]
        lbu             r1,[r2]
        call    DisplayByte
        call    DisplayByte
        addui   r2,r2,#1
        addui   r2,r2,#1
        loop    r3,dspmem1
        loop    r3,dspmem1
        call    CRLF
        call    CRLF
        lw              lr,16[sp]
        lw              lr,16[sp]
        lw              r3,8[sp]
        lw              r3,8[sp]
        lw              r1,[sp]
        lw              r1,[sp]
        ret             #24
        ret             #24
 
 
 
DisplayMemC:
 
        subui   sp,sp,#24
 
        sw              r1,[sp]
 
        sw              r3,8[sp]
 
        sw              lr,16[sp]
 
        setlo   r1,#':'
 
        call    DisplayChar
 
        mov             r1,r2
 
        call    DisplayWord
 
        setlo   r3,#3
 
dspmemc1:
 
        setlo   r1,#' '
 
        call    DisplayChar
 
        lcu             r1,[r2]
 
        call    DisplayCharr
 
        addui   r2,r2,#2
 
        loop    r3,dspmemc1
 
        call    CRLF
 
        lw              lr,16[sp]
 
        lw              r3,8[sp]
 
        lw              r1,[sp]
 
        ret             #24
 
 
 
DisplayMemW:
 
        subui   sp,sp,#24
 
        sw              r1,[sp]
 
        sw              lr,16[sp]
 
        setlo   r1,#':'
 
        call    DisplayChar
 
        mov             r1,r2
 
        call    DisplayWord
 
        setlo   r1,#' '
 
        call    DisplayChar
 
        lw              r1,[r2]
 
        call    DisplayWord
 
        addui   r2,r2,#8
 
        call    CRLF
 
        lw              lr,16[sp]
 
        lw              r1,[sp]
 
        ret             #24
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Converts binary number in r1 into BCD number in r2 and r1.
; Converts binary number in r1 into BCD number in r2 and r1.
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
;
BinToBCD:
BinToBCD:
Line 1587... Line 2161...
        sw              r7,32[sp]
        sw              r7,32[sp]
        sw              r8,40[sp]
        sw              r8,40[sp]
        setlo   r2,#10
        setlo   r2,#10
        setlo   r8,#19          ; number of digits to produce - 1
        setlo   r8,#19          ; number of digits to produce - 1
bta1:
bta1:
        mod             r3,r1,r2
        modu    r3,r1,r2
        shli    r3,r3,#60       ; shift result to uppermost bits
        shli    r3,r3,#60       ; shift result to uppermost bits
        shli    r7,r5,#60       ; copy low order nybble of r5 to r4 topmost nybble
        shli    r7,r5,#60       ; copy low order nybble of r5 to r4 topmost nybble
        shrui   r4,r4,#4
        shrui   r4,r4,#4
        or              r4,r4,r7
        or              r4,r4,r7
        shrui   r5,r5,#4
        shrui   r5,r5,#4
Line 1693... Line 2267...
        lw              lr,48[sp]
        lw              lr,48[sp]
        ret             #56
        ret             #56
 
 
 
 
;==============================================================================
;==============================================================================
 
; System Monitor Program
;==============================================================================
;==============================================================================
 
;
Monitor:
Monitor:
        lea             sp,STACKTOP0    ; top of stack; reset the stack pointer
        lea             sp,STACKTOP0    ; top of stack; reset the stack pointer
        sb              r0,KeybdEcho    ; turn off keyboard echo
        sb              r0,KeybdEcho    ; turn off keyboard echo
PromptLn:
PromptLn:
        call    CRLF
        call    CRLF
Line 1705... Line 2281...
        call    DisplayChar
        call    DisplayChar
 
 
; Get characters until a CR is keyed
; Get characters until a CR is keyed
;
;
Prompt3:
Prompt3:
 
;       lw              r1,#2                   ; get keyboard character
 
;       syscall #417
        call    KeybdGetChar
        call    KeybdGetChar
        beqi    r1,#-1,Prompt3  ; wait for a character
        beqi    r1,#-1,Prompt3  ; wait for a character
        beqi    r1,#CR,Prompt1
        beqi    r1,#CR,Prompt1
        call    DisplayChar
        call    DisplayChar
        bra             Prompt3
        bra             Prompt3
 
 
; Process the screen line that the CR was keyed on
; Process the screen line that the CR was keyed on
;
;
Prompt1:
Prompt1:
        sc              r0,CursorCol    ; go back to the start of the line
        sb              r0,CursorCol    ; go back to the start of the line
        call    CalcScreenLoc   ; r1 = screen memory location
        call    CalcScreenLoc   ; r1 = screen memory location
        or              r3,r1,r0
        mov             r3,r1
        inch    r1,[r3]
        inch    r1,[r3]
        addui   r3,r3,#2
        addui   r3,r3,#2
        call    ScreenToAscii
        call    ScreenToAscii
        bnei    r1,#'$',Prompt2 ; skip over '$' prompt character
        bnei    r1,#'$',Prompt2 ; skip over '$' prompt character
        inch    r1,[r3]
        inch    r1,[r3]
Line 1730... Line 2308...
; Dispatch based on command character
; Dispatch based on command character
;
;
Prompt2:
Prompt2:
        beqi    r1,#':',Editmem         ; $: - edit memory
        beqi    r1,#':',Editmem         ; $: - edit memory
        beqi    r1,#'D',Dumpmem         ; $D - dump memory
        beqi    r1,#'D',Dumpmem         ; $D - dump memory
        beqi    r1,#'B',CSTART          ; $B - start tiny basic
        beqi    r1,#'F',Fillmem         ; $F - fill memory
 
Prompt7:
 
        bnei    r1,#'B',Prompt4         ; $B - start tiny basic
 
        jmp             CSTART
 
Prompt4:
        beqi    r1,#'J',ExecuteCode     ; $J - execute code
        beqi    r1,#'J',ExecuteCode     ; $J - execute code
        beqi    r1,#'L',LoadS19         ; $L - load S19 file
        bnei    r1,#'L',Prompt9 ; $L - load S19 file
        beqi    r1,#'?',DisplayHelp     ; $? - display help
        jmp             LoadSector
 
Prompt9:
 
        bnei    r1,#'?',Prompt10        ; $? - display help
 
        lea             r1,HelpMsg
 
        call    DisplayString
 
        jmp             Monitor
 
Prompt10:
        beqi    r1,#'C',TestCLS         ; $C - clear screen
        beqi    r1,#'C',TestCLS         ; $C - clear screen
        beqi    r1,#'R',RandomLinesCall
        bnei    r1,#'R',Prompt12
        beqi    r1,#'I',Invaders
        jmp             RandomLinesCall
        beqi    r1,#'P',Piano
Prompt12:
        bra             Monitor
        bnei    r1,#'I',Prompt13
 
        jmp             Invaders
 
Prompt13:
 
        bnei    r1,#'P',Prompt14
 
        jmp             Piano
 
Prompt14:
 
        bnei    r1,#'T',Prompt15
 
        call    tmp_read
 
Prompt15:
 
        jmp             Monitor
 
 
RandomLinesCall:
RandomLinesCall:
        call    RandomLines
        call    RandomLines
        bra             Monitor
        jmp             Monitor
 
 
TestCLS:
TestCLS:
        inch    r1,[r3]
        inch    r1,[r3]
        addui   r3,r3,#2
        addui   r3,r3,#2
        call    ScreenToAscii
        call    ScreenToAscii
Line 1757... Line 2354...
        bnei    r1,#'S',Monitor
        bnei    r1,#'S',Monitor
        call    ClearScreen
        call    ClearScreen
        sb              r0,CursorCol
        sb              r0,CursorCol
        sb              r0,CursorRow
        sb              r0,CursorRow
        call    CalcScreenLoc
        call    CalcScreenLoc
        bra             Monitor
        jmp             Monitor
 
 
DisplayHelp:
 
        setlo   r1,HelpMsg
 
        call    DisplayString
 
        bra             Monitor
 
 
 
        align   16
 
HelpMsg:
HelpMsg:
        db      "? = Display help",CR,LF
        db      "? = Display help",CR,LF
        db      "CLS = clear screen",CR,LF
        db      "CLS = clear screen",CR,LF
        db      ": = Edit memory bytes",CR,LF
        db      ": = Edit memory bytes",CR,LF
        db      "L = Load S19 file",CR,LF
        db      "L = Load S19 file",CR,LF
        db      "D = Dump memory",CR,LF
        db      "D[B|C|H|W] = Dump memory",CR,LF
 
        db      "F[B|C|H|W] = Fill memory",CR,LF
        db      "B = start tiny basic",CR,LF
        db      "B = start tiny basic",CR,LF
        db      "J = Jump to code",CR,LF
        db      "J = Jump to code",CR,LF
        db      "I = Invaders",CR,LF
        db      "I = Invaders",CR,LF
        db      "R = Random lines",CR,LF
        db      "R = Random lines",CR,LF
 
        db      "T = get temperature",CR,LF
        db      "P = Piano",CR,LF,0
        db      "P = Piano",CR,LF,0
        align   16
        align   4
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Ignore blanks in the input
; Ignore blanks in the input
; r3 = text pointer
; r3 = text pointer
; r1 destroyed
; r1 destroyed
Line 1811... Line 2404...
        call    ignBlanks
        call    ignBlanks
        call    GetHexNumber
        call    GetHexNumber
        sb              r1,[r5]
        sb              r1,[r5]
        addui   r5,r5,#1
        addui   r5,r5,#1
        loop    r4,edtmem1
        loop    r4,edtmem1
        bra             Monitor
        jmp             Monitor
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Execute code at the specified address.
; Execute code at the specified address.
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
;
ExecuteCode:
ExecuteCode:
        call    ignBlanks
        call    ignBlanks
        call    GetHexNumber
        call    GetHexNumber
        jal             r31,[r1]
        jal             r31,[r1]
        bra     Monitor
        jmp     Monitor
 
 
 
LoadSector:
 
        call    ignBlanks
 
        call    GetHexNumber
 
        lw              r2,#0x3800
 
        call    spi_read_sector
 
        jmp             Monitor
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Do a memory dump of the requested location.
; Do a memory dump of the requested location.
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
;
DumpMem:
DumpMem:
 
        inch    r1,[r3]
 
        addui   r3,r3,#2
 
        call    ScreenToAscii
 
        mov             r6,r1                   ; r6 = fill type character
        call    ignBlanks
        call    ignBlanks
        call    GetHexNumber
        call    GetHexNumber    ; get start address of dump
        mov             r2,r1
        mov             r2,r1
 
        call    ignBlanks
 
        call    GetHexNumber    ; get number of bytes to dump
 
        shrui   r1,r1,#3                ; 1/8 as many dump rows
 
        bnei    r1,#0,Dumpmem2
 
        lw              r1,#1                   ; dump at least one row
 
Dumpmem2:
        call    CRLF
        call    CRLF
        call    DisplayMem
        beqi    r6,#'W',DumpmemW
        call    DisplayMem
;       beqi    r6,#'H',DumpmemH
        call    DisplayMem
        beqi    r6,#'C',DumpmemC
        call    DisplayMem
DumpmemB:
        call    DisplayMem
        call    DisplayMemB
        call    DisplayMem
        loop    r1,DumpmemB
        call    DisplayMem
        jmp             Monitor
        call    DisplayMem
DumpmemC:
 
        call    DisplayMemC
 
        loop    r1,DumpmemC
 
        jmp             Monitor
 
DumpmemW:
 
        call    DisplayMemW
 
        loop    r1,DumpmemW
 
        jmp             Monitor
 
 
 
;       call    DisplayMem
 
;       call    DisplayMem
 
;       call    DisplayMem
 
;       call    DisplayMem
 
;       call    DisplayMem
 
;       call    DisplayMem
 
;       call    DisplayMem
        bra             Monitor
        bra             Monitor
 
 
 
Fillmem:
 
        inch    r1,[r3]
 
        addui   r3,r3,#2
 
        call    ScreenToAscii
 
        mov             r6,r1                   ; r6 = fill type character
 
        call    ignBlanks
 
        call    GetHexNumber    ; get start address of dump
 
        mov             r2,r1
 
        call    ignBlanks
 
        call    GetHexNumber    ; get number of bytes to fill
 
        mov             r5,r1
 
        call    ignBlanks
 
        call    GetHexNumber    ; get the fill byte
 
        beqi    r6,#'C',FillmemC
 
        beqi    r6,#'H',FillmemH
 
        beqi    r6,#'W',FillmemW
 
FillmemB:
 
        sb              r1,[r2]
 
        addui   r2,r2,#1
 
        loop    r5,FillmemB
 
        jmp             Monitor
 
FillmemC:
 
        sc              r1,[r2]
 
        addui   r2,r2,#2
 
        loop    r5,FillmemC
 
        jmp             Monitor
 
FillmemH:
 
        sh              r1,[r2]
 
        addui   r2,r2,#4
 
        loop    r5,FillmemH
 
        jmp             Monitor
 
FillmemW:
 
        sw              r1,[r2]
 
        addui   r2,r2,#8
 
        loop    r5,FillmemW
 
        jmp             Monitor
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Get a hexidecimal number. Maximum of sixteen digits.
; Get a hexidecimal number. Maximum of sixteen digits.
; R3 = text pointer (updated)
; R3 = text pointer (updated)
; R1 = hex number
; R1 = hex number
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
Line 1979... Line 2641...
        sw              r5,S19StartAddress
        sw              r5,S19StartAddress
        bra             Monitor
        bra             Monitor
ProcessS9:
ProcessS9:
        call    S19Get16BitAddress
        call    S19Get16BitAddress
        sw              r5,S19StartAddress
        sw              r5,S19StartAddress
        bra             Monitor
        jmp             Monitor
 
 
S19Get16BitAddress:
S19Get16BitAddress:
        subui   sp,sp,#8
        subui   sp,sp,#8
        sw              r31,[sp]
        sw              r31,[sp]
        call    sGetChar
        call    sGetChar
Line 2061... Line 2723...
        ret             #8
        ret             #8
 
 
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; Draw random lines on the bitmap screen.
; Draw random lines on the bitmap screen.
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
 
;
RandomLines:
RandomLines:
        subui   sp,sp,#24
        subui   sp,sp,#24
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r3,8[sp]
        sw              r3,8[sp]
        sw              lr,16[sp]
        sw              lr,16[sp]
 
        sw              r0,ctx3start    ; prevent restarting context over and over again
rl5:
rl5:
        gran
        gran
        mfspr   r1,rand                 ; select a random color
        mfspr   r1,rand                 ; select a random color
        outh    r1,GACCEL
        outh    r1,GACCEL
rl1:                                            ; random X0
rl1:                                            ; random X0
        gran
        gran
        mfspr   r1,rand
        mfspr   r1,rand
        lw              r3,#1364
        lw              r3,#1364
        mod             r1,r1,r3
        modu    r1,r1,r3
        outh    r1,GACCEL+8
        outh    r1,GACCEL+8
rl2:                                            ; random X1
rl2:                                            ; random X1
        gran
        gran
        mfspr   r1,rand
        mfspr   r1,rand
        lw              r3,#1364
        lw              r3,#1364
        mod             r1,r1,r3
        modu    r1,r1,r3
        outh    r1,GACCEL+16
        outh    r1,GACCEL+16
rl3:                                            ; random Y0
rl3:                                            ; random Y0
        gran
        gran
        mfspr   r1,rand
        mfspr   r1,rand
        lw              r3,#768
        lw              r3,#768
        mod             r1,r1,r3
        modu    r1,r1,r3
        outh    r1,GACCEL+12
        outh    r1,GACCEL+12
rl4:                                            ; random Y1
rl4:                                            ; random Y1
        gran
        gran
        mfspr   r1,rand
        mfspr   r1,rand
        lw              r3,#768
        lw              r3,#768
        mod             r1,r1,r3
        modu    r1,r1,r3
        outh    r1,GACCEL+20
        outh    r1,GACCEL+20
        setlo   r1,#2                   ; draw line command
        setlo   r1,#2                   ; draw line command
        outh    r1,GACCEL+60
        outh    r1,GACCEL+60
rl8:
rl8:
        call    KeybdGetChar
;       call    KeybdGetChar
        beqi    r1,#CTRLC,rl7
;       beqi    r1,#CTRLC,rl7
        beqi    r1,#'r',rl5
        inch    r1,GACCEL+56    ; ensure controller is in IDLE state
        bra             rl8
        bne             r1,r0,rl8
 
        bra             rl5
rl7:
rl7:
        lw              lr,16[sp]
        lw              lr,16[sp]
        lw              r3,8[sp]
        lw              r3,8[sp]
        lw              r1,[sp]
        lw              r1,[sp]
        ret             #24
        ret             #24
Line 2136... Line 2801...
sac974:
sac974:
        outc    r0,AC97+0x26    ; trigger a read of register 26 (status reg)
        outc    r0,AC97+0x26    ; trigger a read of register 26 (status reg)
sac971:                                         ; wait for status to register 0xF (all ready)
sac971:                                         ; wait for status to register 0xF (all ready)
        call    KeybdGetChar    ; see if we needed to CTRL-C
        call    KeybdGetChar    ; see if we needed to CTRL-C
        beqi    r1,#CTRLC,sac973
        beqi    r1,#CTRLC,sac973
        outc    r1,AC97+0x68    ; wait for dirty bit to clear
        inch    r1,AC97+0x68    ; wait for dirty bit to clear
        bne             r1,r0,sac971
        bne             r1,r0,sac971
        outc    r1,AC97+0x26    ; check status at reg h26, wait for
        inch    r1,AC97+0x26    ; check status at reg h26, wait for
        andi    r1,r1,#0x0F             ; analogue to be ready
        andi    r1,r1,#0x0F             ; analogue to be ready
        bnei    r1,#0x0F,sac974
        bnei    r1,#0x0F,sac974
sac973:
sac973:
        outc    r0,AC97+2               ; master volume, 0db attenuation, mute off
        outc    r0,AC97+2               ; master volume, 0db attenuation, mute off
        outc    r0,AC97+4               ; headphone volume, 0db attenuation, mute off
        outc    r0,AC97+4               ; headphone volume, 0db attenuation, mute off
Line 2151... Line 2816...
        setlo   r1,#0x8000              ; bypass 3D sound
        setlo   r1,#0x8000              ; bypass 3D sound
        outc    r1,AC97+0x20
        outc    r1,AC97+0x20
sac972:
sac972:
        call    KeybdGetChar
        call    KeybdGetChar
        beqi    r1,#CTRLC,sac975
        beqi    r1,#CTRLC,sac975
        outc    r1,AC97+0x68    ; wait for dirty bits to clear
        inch    r1,AC97+0x68    ; wait for dirty bits to clear
        bne             r1,r0,sac972    ; wait a while for the settings to take effect
        bne             r1,r0,sac972    ; wait a while for the settings to take effect
sac975:
sac975:
        lw              lr,8[sp]
        lw              lr,8[sp]
        lw              r1,[sp]
        lw              r1,[sp]
        ret             #16
        ret             #16
Line 2182... Line 2847...
        ; sustain level C
        ; sustain level C
        setlo   r1,#0xCA12
        setlo   r1,#0xCA12
        outc    r1,PSGADSR0
        outc    r1,PSGADSR0
        ori             r1,r0,#0x1104   ; gate, output enable, triangle waveform
        ori             r1,r0,#0x1104   ; gate, output enable, triangle waveform
        outc    r1,PSGCTRL0
        outc    r1,PSGCTRL0
        ori             r1,r0,#25000000 ; delay about 1s
        ori             r1,r0,#2500000  ; delay about 1s
beep1:
beep1:
        loop    r1,beep1
        loop    r1,beep1
        setlo   r1,#13
        setlo   r1,#13
        outb    r1,LED
        outb    r1,LED
        ori             r1,r0,#0x0104   ; gate off, output enable, triangle waveform
        ori             r1,r0,#0x0104   ; gate off, output enable, triangle waveform
        outc    r1,PSGCTRL0
        outc    r1,PSGCTRL0
        ori             r1,r0,#25000000 ; delay about 1s
        ori             r1,r0,#2500000  ; delay about 1s
beep2:
beep2:
        loop    r1,beep2
        loop    r1,beep2
        setlo   r1,#16
        setlo   r1,#16
        outb    r1,LED
        outb    r1,LED
        ori             r1,r0,#0x0000   ; gate off, output enable off, no waveform
        ori             r1,r0,#0x0000   ; gate off, output enable off, no waveform
Line 2326... Line 2991...
        ret
        ret
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
DisplayDatetime:
DisplayDatetime:
        subui   sp,sp,#32
        subui   sp,sp,#48
        sw              r1,[sp]
        sw              r1,[sp]
        sw              r2,8[sp]
        sw              r2,8[sp]
        sw              r3,16[sp]
        sw              r3,16[sp]
 
        sw              r4,24[sp]
 
        sw              r5,32[sp]
        sw              lr,24[sp]
        sw              lr,24[sp]
        call    CursorOff
        call    CursorOff
        lc              r2,CursorRow
        lw              r1,#3                           ; get cursor position
        lc              r3,CursorCol
        syscall #410
        outw    r0,DATETIME+24          ; trigger a snapshot
        mov             r4,r1                           ; r4 = row
        lw              r1,#46                          ; move cursor down to last display line
        mov             r5,r2                           ; r5 = col
        sc              r1,CursorRow
        lw              r1,#2                           ; set cursor position
        lw              r1,#64
        lw              r2,#46                          ; move cursor down to last display line
        sc              r1,CursorCol
        lw              r3,#64
        inw             r1,DATETIME                     ; get the snapshotted date and time
        syscall #410
 
        lw              r1,#1                           ; get the snapshotted date and time
 
        syscall #416
        call    DisplayWord                     ; display on screen
        call    DisplayWord                     ; display on screen
        sc              r2,CursorRow            ; restore cursor position
        lw              r1,#2                           ; restore cursor position
        sc              r3,CursorCol
        mov             r2,r4                           ; r2 = row
        call    CalcScreenLoc
        mov             r3,r5                           ; r3 = col
 
        syscall #410
        call    CursorOn
        call    CursorOn
        lw              lr,24[sp]
        lw              lr,24[sp]
        lw              r3,16[sp]
        lw              r3,16[sp]
        lw              r2,8[sp]
        lw              r2,8[sp]
        lw              r1,[sp]
        lw              r1,[sp]
        ret             #32
        lw              r4,24[sp]
 
        lw              r5,32[sp]
 
        ret             #48
 
 
;==============================================================================
;==============================================================================
;==============================================================================
;==============================================================================
InitializeGame:
InitializeGame:
        subui   sp,sp,#16
        subui   sp,sp,#16
Line 2535... Line 3207...
        addui   sp,sp,#240
        addui   sp,sp,#240
        bra             Monitor
        bra             Monitor
 
 
;==============================================================================
;==============================================================================
;==============================================================================
;==============================================================================
 
;
 
; Initialize the SD card
 
; Returns
 
; r = 0 if successful, 1 otherwise
 
;
 
spi_init:
 
        subui   sp,sp,#24
 
        sw              lr,[sp]
 
        sw              r2,8[sp]
 
        sw              r3,16[sp]
 
        lea             r3,SPIMASTER
 
        lw              r1,#SPI_INIT_SD
 
        outb    r1,SPI_TRANS_TYPE_REG[r3]
 
        lw              r1,#SPI_TRANS_START
 
        outb    r1,SPI_TRANS_CTRL_REG[r3]
 
        nop
 
spi_init1:
 
        inb             r1,SPI_TRANS_STATUS_REG[r3]
 
        mov             r2,r1                                                   ; note: some time needs to be wasted
 
        mov             r1,r2                                                   ; between status reads.
 
        beqi    r1,#SPI_TRANS_BUSY,spi_init1
 
        inb             r1,SPI_TRANS_ERROR_REG[r3]
 
        bfext   r1,r1,#1,#0
 
        bne             r1,#SPI_INIT_NO_ERROR,spi_error
 
        lea             r1,spi_init_ok_msg
 
        call    DisplayString
 
        xor             r1,r1,r1
 
        bra             spi_init_exit
 
spi_error:
 
        call    DisplayByte
 
        lea             r1,spi_init_error_msg
 
        call    DisplayString
 
        lw              r1,#1
 
spi_init_exit:
 
        lw              lr,[sp]
 
        lw              r2,8[sp]
 
        lw              r3,16[sp]
 
        ret             #24
 
 
 
 
 
; SPI read sector
 
;
 
; r1= sector number to read
 
; r2= address to place read data
 
; Returns:
 
; r1 = 0 if successful
 
;
 
spi_read_sector:
 
        subui   sp,sp,#40
 
        sw              lr,[sp]
 
        sw              r5,8[sp]
 
        sw              r2,16[sp]
 
        sw              r3,24[sp]
 
        sw              r4,32[sp]
 
        lea             r3,SPIMASTER
 
 
 
        ; spi master wants a byte address, so we multiply the sector number
 
        ; by 512.
 
        shlui   r1,r1,#9
 
        outb    r1,SPI_SD_ADDR_7_0_REG[r3]
 
        shrui   r1,r1,#8
 
        outb    r1,SPI_SD_ADDR_15_8_REG[r3]
 
        shrui   r1,r1,#8
 
        outb    r1,SPI_SD_ADDR_23_16_REG[r3]
 
        shrui   r1,r1,#8
 
        outb    r1,SPI_SD_ADDR_31_24_REG[r3]
 
 
 
        ; Force the reciever fifo to be empty, in case a prior error leaves it
 
        ; in an unknown state.
 
        lw              r1,#1
 
        outb    r1,SPI_RX_FIFO_CTRL_REG[r3]
 
 
 
        lw              r1,#RW_READ_SD_BLOCK
 
        outb    r1,SPI_TRANS_TYPE_REG[r3]
 
        lw              r1,#SPI_TRANS_START
 
        outb    r1,SPI_TRANS_CTRL_REG[r3]
 
        nop
 
spi_read_sect1:
 
        inb             r1,SPI_TRANS_STATUS_REG[r3]
 
        mov             r4,r1                                                   ; just a delay between consecutive status reg reads
 
        mov             r1,r4
 
        beqi    r1,#SPI_TRANS_BUSY,spi_read_sect1
 
        inb             r1,SPI_TRANS_ERROR_REG[r3]
 
        bfext   r1,r1,#3,#2
 
        bnei    r1,#SPI_READ_NO_ERROR,spi_read_error
 
        lw              r4,#512         ; read 512 bytes from fifo
 
spi_read_sect2:
 
        inb             r1,SPI_RX_FIFO_DATA_REG[r3]
 
        sb              r1,[r2]
 
        addui   r2,r2,#1
 
        loop    r4,spi_read_sect2
 
        xor             r1,r1,r1
 
        bra             spi_read_ret
 
spi_read_error:
 
        call    DisplayByte
 
        lea             r1,spi_read_error_msg
 
        call    DisplayString
 
        lw              r1,#1
 
spi_read_ret:
 
        lw              lr,[sp]
 
        lw              r5,8[sp]
 
        lw              r2,16[sp]
 
        lw              r3,24[sp]
 
        lw              r4,32[sp]
 
        ret             #40
 
 
 
; Read the boot sector from the disk.
 
; Must find it first by looking for the signature bytes 'EB' and '55AA'.
 
;
 
spi_read_boot:
 
        subui   sp,sp,#32
 
        sw              lr,[sp]
 
        sw              r2,8[sp]
 
        sw              r3,16[sp]
 
        sw              r5,24[sp]
 
        sw              r0,startSector                                  ; default starting sector
 
        lw              r3,#500 ;1934720                                                ; number of sectors to read (up to 1GB)
 
        lw              r5,#0                                                    ; r5 = starting address
 
spi_read_boot1:
 
        mov             r1,r5                                                   ; r1 = sector number
 
        lw              r2,#8                                                   ; eight digits
 
        sb              r0,CursorCol
 
        call    DisplayNum                                              ; Display the sector number being checked
 
        mov             r1,r5                                                   ; r1 = sector number
 
        lw              r2,#0x100800000                                 ; r2 = target address
 
        call    spi_read_sector
 
 
 
; The following displays the contents of the sector
 
;       lw              r1,#0x10
 
;       lw              r2,#0x3800
 
;spi_read_boot5:
 
;       call    DisplayMemB
 
;       loop    r1,spi_read_boot5
 
 
 
        addui   r5,r5,#1                                                ; move to next sector
 
        lbu             r1,0x100800000
 
        cmpui   r2,r1,#0xEB
 
        beq             r2,r0,spi_read_boot2
 
spi_read_boot3:
 
        loop    r3,spi_read_boot1
 
        lw              r1,#1                                                   ; r1 = 1 for error
 
        bra             spi_read_boot4
 
spi_read_boot2:
 
        lea             r1,msgFoundEB
 
        call    DisplayString
 
        lbu             r1,0x1008001FE                                  ; check for 0x55AA signature
 
        bnei    r1,#0x55,spi_read_boot3
 
        lbu             r1,0x1008001FF
 
        bnei    r1,#0xAA,spi_read_boot3
 
        subui   r1,r5,#1
 
        sw              r1,startSector
 
        xor             r1,r1,r1                                                ; r1 = 0, for okay status
 
spi_read_boot4:
 
        lw              lr,[sp]
 
        lw              r2,8[sp]
 
        lw              r3,16[sp]
 
        lw              r5,24[sp]
 
        ret             #32
 
 
 
msgFoundEB:
 
        db      "Found EB code.",CR,LF,0
 
        .align 4
 
 
 
; Load the FAT tables into memory
 
;
 
loadFAT:
 
        subui   sp,sp,#8
 
        sw              lr,[sp]
 
        lcu             r3,0x100800016                                  ; sectors per FAT
 
        lbu             r2,0x100800010                                  ; number of FATs
 
        mulu    r3,r3,r2                                                ; offset
 
        lea             r2,0x100800200                                  ; where to place FAT
 
        lcu             r5,0x10080000E                                  ; r5 = # reserved sectors before FAT
 
        lw              r6,startSector
 
        addu    r5,r5,r6
 
loadFAT1:
 
        mov             r1,r5                                                   ; r1 = sector #
 
        call    spi_read_sector
 
        addui   r5,r5,#1
 
        addui   r2,r2,#512                                              ; advance 512 bytes
 
        loop    r3,loadFAT1
 
        lw              lr,[sp]
 
        ret             #8
 
 
 
; Load the root directory from disk
 
; r2 = where to place root directory in memory
 
;
 
loadRootDirectory:
 
        lcu             r3,0x100800016                                  ; sectors per FAT
 
        lbu             r4,0x100800010                                  ; number of FATs
 
        mulu    r3,r3,r4                                                ; offset
 
        lcu             r4,0x10080000E                                  ; r2 = # reserved sectors before FAT
 
        addu    r3,r3,r4                                                ; r3 = root directory sector number
 
        lw              r6,startSector
 
        addu    r5,r3,r6                                                ; r5 = root directory sector number
 
        ; we have to use two byte loads here because the number is at an unaligned data address
 
        lbu             r7,0x100800011                                  ; r7 <= number of root directory entries
 
        lbu             r8,0x100800012
 
        shlui   r8,r8,#8
 
        or              r7,r7,r8
 
        mov             r8,r7                                                   ; r8 = number of root directory entries
 
        shlui   r7,r7,#5                                                ; r7 *=32 = size of root directory table (bytes)
 
        shrui   r7,r7,#9                                                ; r7 /= 512 = number of sectors in root directory
 
        mov             r3,r7
 
loadRootDir1:
 
        mov             r1,r5
 
        call    spi_read_sector
 
        addui   r5,r5,#1
 
        addui   r2,r2,#512
 
        loop    r3,loadRootDir1
 
 
 
loadBootFile:
 
        ; For now we cheat and just go directly to sector 512.
 
        bra             loadBootFileTmp
 
 
 
        lcu             r3,0x100800016                                  ; sectors per FAT
 
        lbu             r2,0x100800010                                  ; number of FATs
 
        mulu    r3,r3,r2                                                ; offset
 
        lcu             r2,0x10080000E                                  ; r2 = # reserved sectors before FAT
 
        addu    r3,r3,r2                                                ; r3 = root directory sector number
 
        ; we have to use two byte loads here because the number is at an unaligned data address
 
        lbu             r7,0x100800011                                  ; r7 <= number of root directory entries
 
        lbu             r8,0x100800012
 
        shlui   r8,r8,#8
 
        or              r7,r7,r8
 
        mov             r8,r7                                                   ; r8 = number of root directory entries
 
        shlui   r7,r7,#5                                                ; r7 *=32 = size of root directory table (bytes)
 
        shrui   r7,r7,#9                                                ; r7 /= 512 = number of sectors in root directory
 
 
 
; now we need to fetch the sectors of the root directory and put them somewhere in
 
; memory
 
;
 
loadBootFile4:
 
        lw              r1,[r3]                                                 ; get filename
 
        cmpui   r1,r1,#0x454C4946544F4F42               ; "BOOTFILE"
 
        beq             r1,r0,loadBootFile5
 
loadBootFile3:
 
        addui   r3,r3,#32                                               ; move to next directory entry
 
        loop    r7,loadBootFile4
 
; boot file not found
 
 
 
; here we found the file in the directory
 
;
 
loadBootFile5:
 
        lcu             r2,0x1a[r3]                                             ; get starting cluster
 
        lcu             r7,0x100800011                                  ; r7 = number of root directory entries
 
        shlui   r7,r7,#5                                                ; r7 *=32 = size of root directory table (bytes)
 
        shrui   r7,r7,#9                                                ; r7 /= 512 = number of sectors in root directory
 
 
 
loadBootFileTmp:
 
        ; We load the number of sectors per cluster, then load a single cluster of the file.
 
        ; This is 16kib
 
        lbu             r3,0x10080000D                                  ; sectors per cluster
 
        lea             r2,0x100800200                                  ; where to place FAT in memory
 
        lw              r5,startSector                                  ; r5=start sector of disk
 
        addui   r5,r5,#512                                              ; r5= sector 512
 
loadBootFile1:
 
        mov             r1,r5                                                   ; r1=sector to read
 
        call    spi_read_sector
 
        addui   r5,r5,#1                                                ; r5 = next sector
 
        addui   r2,r2,#512
 
        loop    r3,loadBootFile1
 
        lhu             r1,0x100800200                                  ; make sure it's bootable
 
        bnei    r1,#0x544F4F42,loadBootFile2
 
        lw              r1,#0x16
 
        lea             r1,msgJumpingToBoot
 
        call    DisplayString
 
        lw              r1,#0x100800204
 
        jal             lr,[r1]
 
        jmp             Monitor
 
loadBootFile2:
 
        lea             r1,msgNotBootable
 
        call    DisplayString
 
        jmp             Monitor
 
 
 
msgJumpingToBoot:
 
        db      "Jumping to boot",0
 
msgNotBootable:
 
        db      "SD card not bootable.",0
 
spi_init_ok_msg:
 
        db "SD card initialized okay.",0
 
spi_init_error_msg:
 
        db      ": error occurred initializing the SD card.",0
 
spi_boot_error_msg:
 
        db      "SD card boot error",0
 
spi_read_error_msg:
 
        db      "SD card read error",0
 
 
 
        .align  4
 
 
 
;==============================================================================
 
; Ethernet
 
;==============================================================================
 
my_MAC1 EQU     0x00
 
my_MAC2 EQU     0xFF
 
my_MAC3 EQU     0xEE
 
my_MAC4 EQU     0xF0
 
my_MAC5 EQU     0xDA
 
my_MAC6 EQU     0x42
 
 
 
        .bss
 
eth_unique_id   dw              0
 
 
 
        .code
 
 
 
; Initialize the ethmac controller.
 
; Supply a MAC address, set MD clock
 
;
 
eth_init:
 
        lea             r3,ETHMAC
 
        lw              r1,#0x64                        ; 100
 
        sh              r1,MIIMODER[r3]
 
        lw              r1,#7                           ; PHY address
 
        sh              r1,MIIADDRESS[r3]
 
        lw              r1,#0xEEF0DA42
 
        sh              r1,0x40[r3]                     ; MAC0
 
        lw              r1,#0x00FF
 
        sh              r1,0x44[r3]                     ; MAC1
 
        ret
 
 
 
; Request a packet and display on screen
 
; r1 = address where to put packet
 
;
 
eth_request_packet:
 
        subui   sp,sp,#24
 
        sw              r3,[sp]
 
        sw              r2,8[sp]
 
        sw              r4,16[sp]
 
        lea             r3,ETHMAC
 
        lw              r2,#4                           ; clear rx interrupt
 
        sh              r2,4[r3]
 
        sh              r1,0x604[r3]            ; storage address
 
        lw              r2,#0xe000                      ; enable interrupt
 
        sh              r2,0x600[r3]
 
eth1:
 
        nop
 
        inh             r2,4[r3]
 
        bfext   r2,r2,#2,#2                     ; get bit #2
 
        beq             r2,r0,eth1
 
        inh             r2,0x600[r3]            ; get from descriptor
 
        shrui   r2,r2,#16
 
        lw              r3,#0
 
        lea             r4,TEXTSCR+7560         ; second last line of screen
 
eth20:
 
        lbu             r2,[r1+r3]                      ; get byte
 
        sc              r2,[r4+r3*2]            ; store to screen
 
        addui   r3,r3,#1
 
        cmpui   r2,r3,#83
 
        bne             r2,r0,eth20
 
        lw              r3,[sp]
 
        lw              r2,8[sp]
 
        lw              r4,16[sp]
 
        ret             #24
 
 
 
; r1 = packet address
 
;
 
eth_interpret_packet:
 
        subui   sp,sp,#16
 
        sw              r3,[sp]
 
        sw              r2,8[sp]
 
        lbu             r2,12[r1]
 
        lbu             r3,13[r1]
 
        bnei    r2,#8,eth2                      ; 0x806 ?
 
        bnei    r3,#6,eth2
 
        lw              r1,#2                           ; return r1 = 2 for ARP
 
eth5:
 
        lw              r3,[sp]
 
        lw              r2,8[sp]
 
        ret             #16
 
eth2:
 
        bnei    r2,#8,eth3                      ; 0x800 ?
 
        bnei    r3,#0,eth3
 
        lbu             r2,23[r1]
 
        bnei    r2,#1,eth4
 
        lw              r1,#1
 
        bra             eth5                            ; return 1 ICMP
 
eth4:
 
        bnei    r2,#0x11,eth6
 
        lw              r1,#3                           ; return 3 for UDP
 
        bra             eth5
 
eth6:
 
        bnei    r2,#6,eth7
 
        lw              r1,#4                           ; return 4 for TCP
 
        bra             eth5
 
eth7:
 
eth3:
 
        xor             r1,r1,r1                        ; return zero for unknown
 
        lw              r3,[sp]
 
        lw              r2,8[sp]
 
        ret             #16
 
 
 
; r1 = address of packet to send
 
; r2 = packet length
 
;
 
eth_send_packet:
 
        subui   sp,sp,#16
 
        sw              r3,[sp]
 
        sw              r4,8[sp]
 
        lea             r3,ETHMAC
 
        ; wait for tx buffer to be clear
 
eth8:
 
        inh             r4,0x400[r3]
 
        bfext   r4,r4,#15,#15
 
        beqi    r4,#1,eth8
 
        lw              r4,#1                   ; clear tx interrupt
 
        sh              r4,4[r3]
 
        ; set address
 
        sh              r1,0x404[r3]
 
        ; set the packet length field and enable interrupts
 
        shlui   r2,r2,#16
 
        ori             r2,r2,#0xF000
 
        sh              r2,0x400[r3]
 
        lw              r4,8[sp]
 
        lw              r3,[sp]
 
        ret             #16
 
 
 
; Only for IP type packets (not ARP)
 
; r1 = rx buffer address
 
; r2 = swap flag
 
; Returns:
 
; r1 = data start index
 
;
 
eth_build_packet:
 
        subui   sp,sp,#64
 
        sw              r3,[sp]
 
        sw              r4,8[sp]
 
        sw              r5,16[sp]
 
        sw              r6,24[sp]
 
        sw              r7,32[sp]
 
        sw              r8,40[sp]
 
        sw              r9,48[sp]
 
        sw              r10,56[sp]
 
        lbu             r3,6[r1]
 
        lbu             r4,7[r1]
 
        lbu             r5,8[r1]
 
        lbu             r6,9[r1]
 
        lbu             r7,10[r1]
 
        lbu             r8,11[r1]
 
        ; write to destination header
 
        sb              r3,[r1]
 
        sb              r4,1[r1]
 
        sb              r5,2[r1]
 
        sb              r6,3[r1]
 
        sb              r7,4[r1]
 
        sb              r8,5[r1]
 
        ; write to source header
 
        lw              r3,#my_MAC1
 
        sb              r3,6[r1]
 
        lw              r3,#my_MAC2
 
        sb              r3,7[r1]
 
        lw              r3,#my_MAC3
 
        sb              r3,8[r1]
 
        lw              r3,#my_MAC4
 
        sb              r3,9[r1]
 
        lw              r3,#my_MAC5
 
        sb              r3,10[r1]
 
        lw              r3,#my_MAC6
 
        sb              r3,11[r1]
 
        bnei    r2,#1,eth16                     // if (swap)
 
        lbu             r3,26[r1]
 
        lbu             r4,27[r1]
 
        lbu             r5,28[r1]
 
        lbu             r6,29[r1]
 
        ; read destination
 
        lbu             r7,30[r1]
 
        lbu             r8,31[r1]
 
        lbu             r9,32[r1]
 
        lbu             r10,33[r1]
 
        ; write to sender
 
        sb              r7,26[r1]
 
        sb              r8,27[r1]
 
        sb              r9,28[r1]
 
        sb              r10,29[r1]
 
        ; write destination
 
        sb              r3,30[r1]
 
        sb              r4,31[r1]
 
        sb              r5,32[r1]
 
        sb              r6,33[r1]
 
eth16:
 
        lw              r3,eth_unique_id
 
        addui   r3,r3,#1
 
        sw              r3,eth_unique_id
 
        sb              r3,19[r1]
 
        shrui   r3,r3,#8
 
        sb              r3,18[r1]
 
        lbu             r3,14[r1]
 
        andi    r3,r3,#0xF
 
        shlui   r3,r3,#2                ; *4
 
        addui   r1,r3,#14               ; return datastart in r1
 
        lw              r3,[sp]
 
        lw              r4,8[sp]
 
        lw              r5,16[sp]
 
        lw              r6,24[sp]
 
        lw              r7,32[sp]
 
        lw              r8,40[sp]
 
        lw              r9,48[sp]
 
        lw              r10,56[sp]
 
        ret             #64
 
 
 
; Compute IPv4 checksum of header
 
; r1 = packet address
 
; r2 = data start
 
;
 
eth_checksum:
 
        subui   sp,sp,#24
 
        sw              r3,[sp]
 
        sw              r4,8[sp]
 
        sw              r5,16[sp]
 
        ; set checksum to zero
 
        sb              r0,24[r1]
 
        sb              r0,25[r1]
 
        xor             r3,r3,r3                ; r3 = sum = zero
 
        lw              r4,#14
 
eth15:
 
        mov             r5,r2
 
        subui   r5,r5,#1                ; r5 = datastart - 1
 
        bge             r4,r5,eth14
 
        lbu             r5,[r1+r4]              ; shi = [rx_addr+i]
 
        lbu             r6,1[r1+r4]             ; slo = [rx_addr+i+1]
 
        shlui   r5,r5,#8
 
        or              r5,r5,r6                ; shilo
 
        addu    r3,r3,r5                ; sum = sum + shilo
 
        addui   r4,r4,#2                ; i = i + 2
 
        bra             eth15
 
eth14:
 
        mov             r5,r3                   ; r5 = sum
 
        andi    r3,r3,#0xffff
 
        shrui   r5,r5,#16
 
        addu    r3,r3,r5
 
        com             r3,r3
 
        sb              r3,25[r1]               ; low byte
 
        shrui   r3,r3,#8
 
        sb              r3,24[r1]               ; high byte
 
        sw              r3,[sp]
 
        sw              r4,8[sp]
 
        sw              r5,16[sp]
 
        ret             #24
 
 
 
; r1 = packet address
 
; returns r1 = 1 if this IP
 
;       
 
eth_verifyIP:
 
        subui   sp,sp,#32
 
        sw              r2,[sp]
 
        sw              r3,8[sp]
 
        sw              r4,16[sp]
 
        sw              r5,24[sp]
 
        lbu             r2,30[r1]
 
        lbu             r3,31[r1]
 
        lbu             r4,32[r1]
 
        lbu             r5,33[r1]
 
        ; Check for general broadcast
 
        bnei    r2,#0xFF,eth11
 
        bnei    r3,#0xFF,eth11
 
        bnei    r4,#0xFF,eth11
 
        bnei    r5,#0xFF,eth11
 
eth12:
 
        lw              r1,#1
 
eth13:
 
        lw              r2,[sp]
 
        lw              r3,8[sp]
 
        lw              r4,16[sp]
 
        lw              r5,24[sp]
 
        ret             #32
 
eth11:
 
        mov             r1,r2
 
        shlui   r1,r1,#8
 
        or              r1,r1,r3
 
        shlui   r1,r1,#8
 
        or              r1,r1,r4
 
        shlui   r1,r1,#8
 
        or              r1,r1,r5
 
        beqi    r1,#0xC0A8012A,eth12
 
        xor             r1,r1,r1
 
        bra             eth13
 
 
 
 
 
eth_main:
 
        call    eth_init
 
eth_loop:
 
        xor             r1,r1,r1
 
        lw              r1,#0x1_00000000                ; memory address zero
 
        call    eth_request_packet
 
        call    eth_interpret_packet    ; r1 = packet type
 
 
 
        bnei    r1,#1,eth10
 
        mov             r2,r1                                   ; save off r1, r2 = packet type
 
        lw              r1,#0x1_00000000                ; memory address zero
 
        call    eth_verifyIP
 
        mov     r3,r1
 
        mov     r1,r2                                   ; r1 = packet type again
 
        bnei    r3,#1,eth10
 
 
 
        lw              r1,#0x1_00000000                ; memory address zero
 
        lw              r2,#1
 
        call    eth_build_packet
 
        mov             r3,r1                                   ; r3 = icmpstart
 
        lw              r1,#0x1_00000000                ; memory address zero
 
        sb              r0,[r1+r3]                              ; [rx_addr+icmpstart] = 0
 
        lbu             r2,17[r1]
 
        addui   r2,r2,#14                               ; r2 = len
 
        mov             r6,r2                                   ; r6 = len
 
        lbu             r4,2[r1+r3]                             ; shi
 
        lbu             r5,3[r1+r3]                             ; slo
 
        shlui   r4,r4,#8
 
        or              r4,r4,r5                                ; sum = {shi,slo};
 
        com             r4,r4                                   ; sum = ~sum
 
        subui   r4,r4,#0x800                    ; sum = sum - 0x800
 
        com             r4,r4                                   ; sum = ~sum
 
        sb              r4,3[r1+r3]
 
        shrui   r4,r4,#8
 
        sb              r4,2[r1+r3]
 
        mov             r2,r3
 
        call    eth_checksum
 
        lw              r1,#0x1_00000000                ; memory address zero
 
        mov             r2,r6
 
        call    eth_send_packet
 
        jmp             eth_loop
 
eth10:
 
        ; r2 = rx_addr
 
        bnei    r1,#2,eth_loop          ; Do we have ARP ?
 
;       xor             r2,r2,r2                        ; memory address zero
 
        lw              r2,#1_00000000
 
        ; get the opcode
 
        lbu             r13,21[r2]
 
        bnei    r13,#1,eth_loop         ; ARP request
 
        ; get destination IP address
 
        lbu             r9,38[r2]
 
        lbu             r10,39[r2]
 
        lbu             r11,40[r2]
 
        lbu             r12,41[r2]
 
        ; set r15 = destination IP
 
        mov             r15,r9
 
        shlui   r15,r15,#8
 
        or              r15,r15,r10
 
        shlui   r15,r15,#8
 
        or              r15,r15,r11
 
        shlui   r15,r15,#8
 
        or              r15,r15,r12
 
        ; Is it our IP ?
 
        bnei    r15,#0xC0A8012A,eth_loop; //192.168.1.42
 
        ; get source IP address
 
        lbu             r5,28[r2]
 
        lbu             r6,29[r2]
 
        lbu             r7,30[r2]
 
        lbu             r8,31[r2]
 
        ; set r14 = source IP
 
        mov             r14,r5
 
        shlui   r14,r14,#8
 
        or              r14,r14,r6
 
        shlui   r14,r14,#8
 
        or              r14,r14,r7
 
        shlui   r14,r14,#8
 
        or              r14,r14,r8
 
        ; Get the source MAC address
 
        lbu             r16,22[r2]
 
        lbu             r17,23[r2]
 
        lbu             r18,24[r2]
 
        lbu             r19,25[r2]
 
        lbu             r20,26[r2]
 
        lbu             r21,27[r2]
 
        ; write to destination header
 
        sb              r16,[r2]
 
        sb              r17,1[r2]
 
        sb              r18,2[r2]
 
        sb              r19,3[r2]
 
        sb              r20,4[r2]
 
        sb              r21,5[r2]
 
        ; and write to ARP destination
 
        sb              r16,32[r2]
 
        sb              r17,33[r2]
 
        sb              r18,34[r2]
 
        sb              r19,35[r2]
 
        sb              r20,36[r2]
 
        sb              r21,37[r2]
 
        ; write to source header
 
;       stbc    #0x00,6[r2]
 
;       stbc    #0xFF,7[r2]
 
;       stbc    #0xEE,8[r2]
 
;       stbc    #0xF0,9[r2]
 
;       stbc    #0xDA,10[r2]
 
;       stbc    #0x42,11[r2]
 
        sb              r0,6[r2]
 
        lw              r1,#0xFF
 
        sb              r1,7[r2]
 
        lw              r1,#0xEE
 
        sb              r1,8[r2]
 
        lw              r1,#0xF0
 
        sb              r1,9[r2]
 
        lw              r1,#0xDA
 
        sb              r1,10[r2]
 
        lw              r1,#0x42
 
        sb              r1,11[r2]
 
        ; write to ARP source
 
;       stbc    #0x00,22[r2]
 
;       stbc    #0xFF,23[r2]
 
;       stbc    #0xEE,24[r2]
 
;       stbc    #0xF0,25[r2]
 
;       stbc    #0xDA,26[r2]
 
;       stbc    #0x42,27[r2]
 
        sb              r0,22[r2]
 
        lw              r1,#0xFF
 
        sb              r1,23[r2]
 
        lw              r1,#0xEE
 
        sb              r1,24[r2]
 
        lw              r1,#0xF0
 
        sb              r1,25[r2]
 
        lw              r1,#0xDA
 
        sb              r1,26[r2]
 
        lw              r1,#0x42
 
        sb              r1,27[r2]
 
        ; swap sender / destination IP
 
        ; write sender
 
        sb              r9,28[r2]
 
        sb              r10,29[r2]
 
        sb              r11,30[r2]
 
        sb              r12,31[r2]
 
        ; write destination
 
        sb              r5,38[r2]
 
        sb              r6,39[r2]
 
        sb              r7,40[r2]
 
        sb              r8,41[r2]
 
        ; change request to reply
 
;       stbc    #2,21[r2]
 
        lw              r1,#2
 
        sb              r1,21[r2]
 
        mov             r1,r2                   ; r1 = packet address
 
        lw              r2,#0x2A                ; r2 = packet length
 
        call    eth_send_packet
 
        jmp             eth_loop
 
 
 
 
 
;==============================================================================
 
;==============================================================================
;****************************************************************;
;****************************************************************;
;                                                                ;
;                                                                ;
;               Tiny BASIC for the Raptor64                              ;
;               Tiny BASIC for the Raptor64                              ;
;                                                                ;
;                                                                ;
; Derived from a 68000 derivative of Palo Alto Tiny BASIC as     ;
; Derived from a 68000 derivative of Palo Alto Tiny BASIC as     ;
Line 2608... Line 4014...
        sw              lr,[sp]
        sw              lr,[sp]
        sw              sp,OSSP
        sw              sp,OSSP
        lw              sp,ENDMEM       ; initialize stack pointer
        lw              sp,ENDMEM       ; initialize stack pointer
        subui   sp,sp,#8
        subui   sp,sp,#8
        sw      lr,[sp]    ; save off return address
        sw      lr,[sp]    ; save off return address
        sc              r0,CursorRow    ; set screen output
        sb              r0,CursorRow    ; set screen output
        sc              r0,CursorCol
        sb              r0,CursorCol
        sb              r0,CursorFlash
        sb              r0,CursorFlash
        sw              r0,pos
        sh              r0,pos
        lw              r2,#0x10000020  ; black chars, yellow background
        lw              r2,#0x10000020  ; black chars, yellow background
        sh              r2,charToPrint
;       sh              r2,charToPrint
        call    ClearScreen
        call    ClearScreen
        lea             r1,msgInit      ;       tell who we are
        lea             r1,msgInit      ;       tell who we are
        call    PRMESGAUX
;       call    PRMESGAUX
        lea             r1,msgInit      ;       tell who we are
        lea             r1,msgInit      ;       tell who we are
        call    PRMESG
        call    PRMESG
        lw              r1,TXTBGN       ;       init. end-of-program pointer
        lw              r1,TXTBGN       ;       init. end-of-program pointer
        sw              r1,TXTUNF
        sw              r1,TXTUNF
        lw              r1,ENDMEM       ;       get address of end of memory
        lw              r1,ENDMEM       ;       get address of end of memory
        subui   r1,r1,#2048     ;       reserve 2K for the stack
        subui   r1,r1,#4096     ;       reserve 4K for the stack
        sw              r1,STKBOT
        sw              r1,STKBOT
        subui   r1,r1,#8192 ;   1000 vars
        subui   r1,r1,#16384 ;   1000 vars
        sw      r1,VARBGN
        sw      r1,VARBGN
        call    clearVars   ; clear the variable area
        call    clearVars   ; clear the variable area
        lw      r1,VARBGN   ; calculate number of bytes free
        lw      r1,VARBGN   ; calculate number of bytes free
        lw              r3,TXTUNF
        lw              r3,TXTUNF
        sub     r1,r1,r3
        subu    r1,r1,r3
        setlo   r2,#0
        setlo   r2,#0
        call    PRTNUM
        call    PRTNUM
        lea             r1,msgBytesFree
        lea             r1,msgBytesFree
        call    PRMESG
        call    PRMESG
WSTART:
WSTART:
Line 2749... Line 4155...
; The end of the character table is a 0 byte which corresponds
; The end of the character table is a 0 byte which corresponds
; to the default routine in the execution table, which is
; to the default routine in the execution table, which is
; executed if none of the other table items are matched.
; executed if none of the other table items are matched.
;
;
; Character-matching tables:
; Character-matching tables:
        align   8
 
TAB1:
TAB1:
        db      "LIS",'T'+0x80        ; Direct commands
        db      "LIS",'T'+0x80        ; Direct commands
        db      "LOA",'D'+0x80
        db      "LOA",'D'+0x80
        db      "NE",'W'+0x80
        db      "NE",'W'+0x80
        db      "RU",'N'+0x80
        db      "RU",'N'+0x80
Line 2871... Line 4277...
    dw  XP_ANDX
    dw  XP_ANDX
TAB10_1
TAB10_1
    dw  XP_OR
    dw  XP_OR
    dw  XP_ORX
    dw  XP_ORX
 
 
        .align  16
        .align  4
 
 
;*
;*
; r3 = match flag (trashed)
; r3 = match flag (trashed)
; r9 = text table
; r9 = text table
; r10 = exec table
; r10 = exec table
Line 4650... Line 6056...
; r1 = pointer to string
; r1 = pointer to string
; r2 = stop character
; r2 = stop character
; return r1 = pointer to end of line + 1
; return r1 = pointer to end of line + 1
 
 
PRTSTG:
PRTSTG:
    sub     sp,sp,#32
    subui   sp,sp,#32
    sw          r5,[sp]
    sw          r5,[sp]
    sw          r5,8[sp]
    sw          r5,8[sp]
    sw          r7,16[sp]
    sw          r7,16[sp]
    sw          lr,24[sp]
    sw          lr,24[sp]
    mov     r5,r1       ; r5 = pointer
    mov     r5,r1       ; r5 = pointer
Line 4680... Line 6086...
 
 
QTSTG:
QTSTG:
        subui   sp,sp,#8
        subui   sp,sp,#8
        sw              lr,[sp]
        sw              lr,[sp]
        setlo   r3,#'"'
        setlo   r3,#'"'
        setlo   r4,#<QT3
        lea             r4,QT3
        sethi   r4,#>QT3
 
        call    TSTC            ; *** QTSTG ***
        call    TSTC            ; *** QTSTG ***
        setlo   r2,#'"'         ; it is a "
        setlo   r2,#'"'         ; it is a "
QT1:
QT1:
        or              r1,r8,r0
        or              r1,r8,r0
        call    PRTSTG          ; print until another
        call    PRTSTG          ; print until another
Line 4693... Line 6098...
        bne             r2,#LF,QT2      ; was last one a CR?
        bne             r2,#LF,QT2      ; was last one a CR?
        addui   sp,sp,#8
        addui   sp,sp,#8
        bra             RUNNXL          ; if so, run next line
        bra             RUNNXL          ; if so, run next line
QT3:
QT3:
        setlo   r3,#''''
        setlo   r3,#''''
        setlo   r4,#<QT4
        lea             r4,QT4
        sethi   r4,#>QT4
 
        call    TSTC            ; is it a single quote?
        call    TSTC            ; is it a single quote?
        setlo   r2,#''''        ; if so, do same as above
        setlo   r2,#''''        ; if so, do same as above
        bra             QT1
        bra             QT1
QT4:
QT4:
        setlo   r3,#'_'
        setlo   r3,#'_'
        setlo   r4,#<QT5
        lea             r4,QT5
        sethi   r4,#>QT5
 
        call    TSTC            ; is it an underline?
        call    TSTC            ; is it an underline?
        setlo   r1,#CR          ; if so, output a CR without LF
        setlo   r1,#CR          ; if so, output a CR without LF
        call    GOOUT
        call    GOOUT
QT2:
QT2:
        lw              lr,[sp]
        lw              lr,[sp]
Line 4738... Line 6141...
        sw              r3,[sp]
        sw              r3,[sp]
        sw              r5,8[sp]
        sw              r5,8[sp]
        sw              r6,16[sp]
        sw              r6,16[sp]
        sw              r7,24[sp]
        sw              r7,24[sp]
        sw              lr,32[sp]
        sw              lr,32[sp]
        ori             r7,r0,#NUMWKA   ; r7 = pointer to numeric work area
        lea             r7,NUMWKA       ; r7 = pointer to numeric work area
        mov             r6,r1           ; save number for later
        mov             r6,r1           ; save number for later
        mov             r5,r2           ; r5 = min number of chars
        mov             r5,r2           ; r5 = min number of chars
        bgt             r1,r0,PN1       ; is it negative? if not
        bgt             r1,r0,PN2       ; is it negative? if not
        neg             r1,r1           ; else make it positive
        neg             r1,r1           ; else make it positive
        subui   r5,r5,#1        ; one less for width count
        subui   r5,r5,#1        ; one less for width count
PN1:
PN2:
        lw              r3,#10
        lw              r3,#10
        mod             r2,r1,r3        ; r2 = r1 mod 10
PN1:
 
        modu    r2,r1,r3        ; r2 = r1 mod 10
        divui   r1,r1,#10       ; r1 /= 10 divide by 10
        divui   r1,r1,#10       ; r1 /= 10 divide by 10
        addui   r2,r2,#'0'      ; convert remainder to ascii
        addui   r2,r2,#'0'      ; convert remainder to ascii
        sb              r2,[r7]         ; and store in buffer
        sb              r2,[r7]         ; and store in buffer
        addui   r7,r7,#1
        addui   r7,r7,#1
        subui   r5,r5,#1        ; decrement width
        subui   r5,r5,#1        ; decrement width
Line 4760... Line 6164...
PN3:
PN3:
        setlo   r1,#' '         ; display the required leading spaces
        setlo   r1,#' '         ; display the required leading spaces
        call    GOOUT
        call    GOOUT
        loop    r5,PN3
        loop    r5,PN3
PN4:
PN4:
        bgt             r6,r0,PN5       ; is number negative?
        bge             r6,r0,PN5       ; is number negative?
        setlo   r1,#'-'         ; if so, display the sign
        setlo   r1,#'-'         ; if so, display the sign
        call    GOOUT
        call    GOOUT
PN5:
PN5:
        subui   r7,r7,#1
        subui   r7,r7,#1
        lb              r1,[r7]         ; now unstack the digits and display
        lb              r1,[r7]         ; now unstack the digits and display
Line 4787... Line 6191...
        sw              r5,[sp]
        sw              r5,[sp]
        sw              r6,8[sp]
        sw              r6,8[sp]
        sw              r7,16[sp]
        sw              r7,16[sp]
        sw              r8,24[sp]
        sw              r8,24[sp]
        sw              lr,32[sp]
        sw              lr,32[sp]
        setlo   r7,#<NUMWKA     ; r7 = pointer to numeric work area
        lea             r7,NUMWKA       ; r7 = pointer to numeric work area
        sethi   r7,#>NUMWKA
 
        or              r6,r1,r0        ; save number for later
        or              r6,r1,r0        ; save number for later
        setlo   r5,#20          ; r5 = min number of chars
        setlo   r5,#20          ; r5 = min number of chars
        or              r4,r1,r0
        mov             r4,r1
        bgt             r4,r0,PHN1              ; is it negative? if not
        bgt             r4,r0,PHN1              ; is it negative? if not
        neg             r4,r4                   ; else make it positive
        neg             r4,r4                   ; else make it positive
        sub             r5,r5,#1        ; one less for width count
        subui   r5,r5,#1        ; one less for width count
        setlo   r8,#20          ; maximum of 10 digits
        setlo   r8,#20          ; maximum of 10 digits
PHN1:
PHN1:
        or              r1,r4,r0
        mov             r1,r4
        andi    r1,r1,#15
        andi    r1,r1,#15
        blt             r1,#10,PHN7
        blt             r1,#10,PHN7
        addui   r1,r1,#'A'-10
        addui   r1,r1,#'A'-10
        bra             PHN8
        bra             PHN8
PHN7:
PHN7:
        add             r1,r1,#'0'              ; convert remainder to ascii
        add             r1,r1,#'0'              ; convert remainder to ascii
PHN8:
PHN8:
        sb              r1,[r7]         ; and store in buffer
        sb              r1,[r7]         ; and store in buffer
        add             r7,r7,#1
        addui   r7,r7,#1
        sub             r5,r5,#1        ; decrement width
        subui   r5,r5,#1        ; decrement width
        shru    r4,r4,#4
        shrui   r4,r4,#4
        beq             r4,r0,PHN6                      ; is it zero yet ?
        beq             r4,r0,PHN6                      ; is it zero yet ?
        loop    r8,PHN1         ; safety
        loop    r8,PHN1         ; safety
PHN6:   ; test pad count
PHN6:   ; test pad count
        ble             r5,r0,PHN4      ; skip padding if not needed
        ble             r5,r0,PHN4      ; skip padding if not needed
PHN3:
PHN3:
Line 4822... Line 6225...
PHN4:
PHN4:
        bgt             r6,r0,PHN5      ; is number negative?
        bgt             r6,r0,PHN5      ; is number negative?
        setlo   r1,#'-'         ; if so, display the sign
        setlo   r1,#'-'         ; if so, display the sign
        call    GOOUT
        call    GOOUT
PHN5:
PHN5:
        sub             r7,r7,#1
        subui   r7,r7,#1
        lb              r1,[r7]         ; now unstack the digits and display
        lb              r1,[r7]         ; now unstack the digits and display
        call    GOOUT
        call    GOOUT
        cmpui   r1,r7,#NUMWKA
        cmpui   r1,r7,#NUMWKA
        bgt             r1,r0,PHN5
        bgt             r1,r0,PHN5
PHNRET:
PHNRET:
Line 4881... Line 6284...
        lw              r1,8[sp]
        lw              r1,8[sp]
        lw              lr,[sp]
        lw              lr,[sp]
        addui   sp,sp,#16
        addui   sp,sp,#16
        jal             r0,[r4]         ; jump to the routine
        jal             r0,[r4]         ; jump to the routine
TC1:
TC1:
        add             r8,r8,#1        ; if equal, bump text pointer
        addui   r8,r8,#1        ; if equal, bump text pointer
        lw              r1,8[sp]
        lw              r1,8[sp]
        lw              lr,[sp]
        lw              lr,[sp]
        ret             #16
        ret             #16
 
 
; ===== See if the text pointed to by r8 is a number. If so,
; ===== See if the text pointed to by r8 is a number. If so,
Line 4906... Line 6309...
        setlo   r2,#0
        setlo   r2,#0
TN1:
TN1:
        lb              r3,[r8]
        lb              r3,[r8]
        bltui   r3,#'0',TSNMRET ; is it less than zero?
        bltui   r3,#'0',TSNMRET ; is it less than zero?
        bgtui   r3,#'9',TSNMRET ; is it greater than nine?
        bgtui   r3,#'9',TSNMRET ; is it greater than nine?
        setlo   r4,#0xFFFFFFFF
        lw              r4,#0x07FFFFFF_FFFFFFFF
        sethi   r4,#0x07FFFFFF
 
        bleu    r1,r4,TN2       ; see if there's room for new digit
        bleu    r1,r4,TN2       ; see if there's room for new digit
        setlo   r1,msgNumTooBig
        lea             r1,msgNumTooBig
        bra             ERROR           ; if not, we've overflowd
        bra             ERROR           ; if not, we've overflowd
TN2:
TN2:
        mului   r1,r1,#10       ; quickly multiply result by 10
        mului   r1,r1,#10       ; quickly multiply result by 10
        addi    r8,r8,#1        ; adjust text pointer
        addui   r8,r8,#1        ; adjust text pointer
        andi    r3,r3,#0x0F     ; add in the new digit
        andi    r3,r3,#0x0F     ; add in the new digit
        add             r1,r1,r3
        addu    r1,r1,r3
        addi    r2,r2,#1        ; increment the no. of digits
        addui   r2,r2,#1        ; increment the no. of digits
        bra             TN1
        bra             TN1
TSNMRET:
TSNMRET:
        lw              lr,[sp]
        lw              lr,[sp]
        ret             #8
        ret             #8
 
 
Line 4938... Line 6340...
IGB2:
IGB2:
        lb              r1,[r8]                 ; get char
        lb              r1,[r8]                 ; get char
        beqi    r1,#' ',IGB1    ; see if it's a space
        beqi    r1,#' ',IGB1    ; see if it's a space
        bnei    r1,#'\t',IGBRET ; or a tab
        bnei    r1,#'\t',IGBRET ; or a tab
IGB1:
IGB1:
        add             r8,r8,#1                ; increment the text pointer
        addui   r8,r8,#1                ; increment the text pointer
        bra             IGB2
        bra             IGB2
IGBRET:
IGBRET:
        lw              r1,[sp]
        lw              r1,[sp]
        ret             #8
        ret             #8
 
 
Line 4956... Line 6358...
;       r8 = pointing to end of text in buffer
;       r8 = pointing to end of text in buffer
;
;
TOUPBUF:
TOUPBUF:
        subui   sp,sp,#8
        subui   sp,sp,#8
        sw              lr,[sp]
        sw              lr,[sp]
        setlo   r8,BUFFER       ; set up text pointer
        lea             r8,BUFFER       ; set up text pointer
        setlo   r3,#0            ; clear quote flag
        setlo   r3,#0            ; clear quote flag
TOUPB1:
TOUPB1:
        lb              r1,[r8]         ; get the next text char.
        lb              r1,[r8]         ; get the next text char.
        add             r8,r8,#1
        addui   r8,r8,#1
        beqi    r1,#CR,TOUPBRT          ; is it end of line?
        beqi    r1,#CR,TOUPBRT          ; is it end of line?
        beqi    r1,#'"',DOQUO   ; a double quote?
        beqi    r1,#'"',DOQUO   ; a double quote?
        beqi    r1,#'''',DOQUO  ; or a single quote?
        beqi    r1,#'''',DOQUO  ; or a single quote?
        bne             r3,r0,TOUPB1    ; inside quotes?
        bne             r3,r0,TOUPB1    ; inside quotes?
        call    toUpper         ; convert to upper case
        call    toUpper         ; convert to upper case
        sb              r1,-1[r8]       ; store it
        sb              r1,-1[r8]       ; store it
        bra             TOUPB1          ; and go back for more
        bra             TOUPB1          ; and go back for more
DOQUO:
DOQUO:
        bne             r3,r0,DOQUO1; are we inside quotes?
        bne             r3,r0,DOQUO1; are we inside quotes?
        or              r3,r1,r0        ; if not, toggle inside-quotes flag
        mov             r3,r1           ; if not, toggle inside-quotes flag
        bra             TOUPB1
        bra             TOUPB1
DOQUO1:
DOQUO1:
        bne             r3,r1,TOUPB1            ; make sure we're ending proper quote
        bne             r3,r1,TOUPB1            ; make sure we're ending proper quote
        setlo   r3,#0            ; else clear quote flag
        setlo   r3,#0            ; else clear quote flag
        bra             TOUPB1
        bra             TOUPB1
Line 4984... Line 6386...
 
 
 
 
; ===== Convert the character in r1 to upper case
; ===== Convert the character in r1 to upper case
;
;
toUpper
toUpper
        blt             r1,#'a',TOUPRET ; is it < 'a'?
        blti    r1,#'a',TOUPRET ; is it < 'a'?
        bgt             r1,#'z',TOUPRET ; or > 'z'?
        bgti    r1,#'z',TOUPRET ; or > 'z'?
        sub             r1,r1,#32       ; if not, make it upper case
        subui   r1,r1,#32       ; if not, make it upper case
TOUPRET
TOUPRET
        ret
        ret
 
 
 
 
; 'CHKIO' checks the input. If there's no input, it will return
; 'CHKIO' checks the input. If there's no input, it will return
Line 5000... Line 6402...
;
;
CHKIO:
CHKIO:
        subui   sp,sp,#8        ; save link reg
        subui   sp,sp,#8        ; save link reg
        sw              lr,[sp]
        sw              lr,[sp]
        call    GOIN            ; get input if possible
        call    GOIN            ; get input if possible
        beq             r1,#-1,CHKRET2          ; if Zero, no input
        beqi    r1,#-1,CHKRET2          ; if Zero, no input
        bnei    r1,#CTRLC,CHKRET        ; is it control-C?
        bnei    r1,#CTRLC,CHKRET        ; is it control-C?
        jmp             WSTART          ; if so, do a warm start
        jmp             WSTART          ; if so, do a warm start
CHKRET2:
CHKRET2:
        xor             r1,r1,r1
        xor             r1,r1,r1
CHKRET:
CHKRET:
Line 5026... Line 6428...
        subui   sp,sp,#16
        subui   sp,sp,#16
        sw              r5,[sp]
        sw              r5,[sp]
        sw              lr,8[sp]
        sw              lr,8[sp]
        mov     r5,r1       ; r5 = pointer to message
        mov     r5,r1       ; r5 = pointer to message
PRMESG1:
PRMESG1:
        add             r5,r5,#1
        addui   r5,r5,#1
        lb              r1,-1[r5]       ;       get the char.
        lbu             r1,-1[r5]       ;       get the char.
        beq             r1,r0,PRMRET
        beq             r1,r0,PRMRET
        call    GOOUT           ;else display it trashes r4
        call    GOOUT           ;else display it trashes r4
        bra             PRMESG1
        bra             PRMESG1
PRMRET:
PRMRET:
        mov             r1,r5
        mov             r1,r5
Line 5072... Line 6474...
;
;
OUTC:
OUTC:
        jmp             DisplayChar
        jmp             DisplayChar
 
 
 
 
; ===== Input a character from the console into register D0 (or
; ===== Input a character from the console into register R1 (or
;       return Zero status if there's no character available).
;       return Zero status if there's no character available).
;
;
INC:
INC:
        jmp             KeybdGetChar
        jmp             KeybdGetChar
 
 
Line 5126... Line 6528...
        ret             #8
        ret             #8
 
 
;       MOVE.B  #228,D7         return to Tutor
;       MOVE.B  #228,D7         return to Tutor
;       TRAP    #14
;       TRAP    #14
 
 
        .align  16
msgInit db      CR,LF,"Raptor64 Tiny BASIC v1.0",CR,LF,"(C) 2013  Robert Finch",CR,LF,LF,0
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
OKMSG   db      CR,LF,"OK",CR,LF,0
msgWhat db      "What?",CR,LF,0
msgWhat db      "What?",CR,LF,0
SRYMSG  db      "Sorry."
SRYMSG  db      "Sorry."
CLMSG   db      CR,LF,0
CLMSG   db      CR,LF,0
msgReadError    db      "Compact FLASH read error",CR,LF,0
msgReadError    db      "Compact FLASH read error",CR,LF,0
Line 5237... Line 6638...
        mfspr   r1,EPC
        mfspr   r1,EPC
        call    DisplayWord
        call    DisplayWord
        wait
        wait
        jmp             start
        jmp             start
dberr_rout:
dberr_rout:
 
        lw              sp,#0x100200100
        lea             r1,msgdberr
        lea             r1,msgdberr
        call    DisplayString
        call    DisplayString
        mfspr   r1,ERRADR
        mfspr   r1,ERRADR
        call    DisplayWord
        call    DisplayWord
        lea             r1,msgEPC
        lea             r1,msgEPC
Line 5265... Line 6667...
        db      "Data bus error at: ",0
        db      "Data bus error at: ",0
msgEPC:
msgEPC:
        db      " EPC: ",0
        db      " EPC: ",0
msgiberr:
msgiberr:
        db      "Err fetching instruction at: ",0
        db      "Err fetching instruction at: ",0
        .align  16
        .align  4
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; IRQ routine
; IRQ routine
 
;
 
; Interrupts are automatically disabled at the time of the interrupt in order
 
; to prevent nested interrupts from occuring. Interrupts are re-enabled by
 
; the IRET instruction at the end of the interrupt routine. If the interrupt
 
; turns out to not match a hardware interrupt, then a software context
 
; switching interrupt is assumed.
 
;
 
; This routine uses it's own private interrupt stack; the stack of the
 
; interrupted context is not used at all. A couple of working registers are
 
; saved off not on the stack. We can get away with this because nested
 
; interrupts are not allowed.
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
;
irqrout:
irqrout:
        subui   sp,sp,#32
        sw              sp,sp_save                              ; use our own private stack for interrupt processing
        sw              r1,[sp]                                 ; save off a working register
        sw              lr,lr_save                              ; so, save off the sp and working registers
        sw              r2,8[sp]                                ; and a second work register
        sw              r26,r26_save
        sw              r26,16[sp]                              ; save off implicit constant builder reg
        sw              r1,r1_save
        sw              lr,24[sp]
        sw              r2,r2_save
 
 
 
        lw              sp,#0x1_00001000                ; the second two kbytes
        inch    r1,PIC                                  ; r1= which IRQ line is active
        inch    r1,PIC                                  ; r1= which IRQ line is active
 
 
 
; Dispatch fork, in order of required timeliness
 
 
 
        beqi    r1,#2,irq1000Hz
 
        beqi    r1,#3,irq100Hz
 
        beqi    r1,#8,irqSerial
 
        beqi    r1,#13,irqRaster
 
        beqi    r1,#15,irqKeybd
 
        beqi    r1,#1,irqColdStart              ; CTRL-ALT-DEL interrupt
 
 
 
; Here, none of the hardware interrupts were active so
 
; assume software context switch interrupt
 
;
 
        lw              sp,sp_save
 
        lw              lr,lr_save
 
        lw              r26,r26_save
 
        lw              r1,r1_save
 
        lw              r2,r2_save
 
        iepp
 
        iret
 
 
; 1000 Hz interrupt
; 1000 Hz interrupt
; This IRQ must be fast, so it's placed inline
; This IRQ must be fast, so it's placed inline. It's also the first
 
; IRQ checked for in the interrupt dispatch.
; Increments the millisecond counter, and switches to the next context
; Increments the millisecond counter, and switches to the next context
;
;
irq1000Hz:
irq1000Hz:
        bnei    r1,#2,irq100Hz
        outb    r0,0xDCFFFD                             ; acknowledge interrupt
        outb    r0,0xFFFFFFFF_FFFF0000  ; acknowledge interrupt
 
        lw              r1,Milliseconds                 ; increment milliseconds count
        lw              r1,Milliseconds                 ; increment milliseconds count
        addui   r1,r1,#1
        addui   r1,r1,#1
        sw              r1,Milliseconds
        sw              r1,Milliseconds
        lea             r2,TEXTSCR
        lw              sp,sp_save
        inch    r1,332[r2]
        lw              lr,lr_save
        addui   r1,r1,#1
        lw              r26,r26_save
        outc    r1,332[r2]
        lw              r1,r1_save
        lw              lr,24[sp]
        lw              r2,r2_save
        lw              r26,16[sp]                              ; restore registers from stack
 
        lw              r2,8[sp]
 
        lw              r1,[sp]
 
        addui   sp,sp,#32                               ; restore stack pointer
 
        iepp                                                    ; move to the next context
        iepp                                                    ; move to the next context
        nop
 
        nop
 
        nop
 
        iret                                                    ; return to the next context
        iret                                                    ; return to the next context
 
 
; 100 Hz interrupt
; 100 Hz interrupt
; This IRQ could have some work to do, including flashing a cursor. So
; This IRQ could have some work to do, including flashing a cursor. So
; we call a subroutine.
; we call a subroutine.
;
;
irq100Hz:
irq100Hz:
        bnei    r1,#3,irqSerial
 
        lw              r1,p100IRQvec
        lw              r1,p100IRQvec
;       jal             lr,[r1]
;       jal             lr,[r1]
        call    Pulse100
        call    Pulse100
        bra             irqret
irqret:
 
        lw              sp,sp_save
 
        lw              lr,lr_save
 
        lw              r26,r26_save
 
        lw              r1,r1_save
 
        lw              r2,r2_save
 
        iret
 
 
irqSerial:
irqSerial:
        bnei    r1,#8,irqRaster
 
        lw              r1,serialIRQvec
        lw              r1,serialIRQvec
        jal             lr,[r1]
        jal             lr,[r1]
        bra             irqret
        bra             irqret
 
 
irqRaster:
irqRaster:
        bnei    r1,#13,irqKeybd
 
        lw              r1,rasterIRQvec
        lw              r1,rasterIRQvec
;       jal             lr,[r1]
;       jal             lr,[r1]
        call    RasterIRQfn
        call    RasterIRQfn
        bra             irqret
        bra             irqret
 
 
irqKeybd:
irqKeybd:
        beqi    r1,#1,ColdStart                 ; CTRL-ALT-DEL interrupt
 
        bnei    r1,#15,irqret
 
        lw              r1,keybdIRQvec
        lw              r1,keybdIRQvec
        call    KeybdIRQ
        call    KeybdIRQ
;       jal             lr,[r1]
;       jal             lr,[r1]
 
        bra             irqret
 
 
irqret:
irqColdStart:
        lw              lr,24[sp]
        jmp             ColdStart
        lw              r26,16[sp]                              ; restore registers from stack
 
        lw              r2,8[sp]
;------------------------------------------------------------------------------
        lw              r1,[sp]
; NMI routine
        addui   sp,sp,#32                               ; restore stack pointer
;
 
; The NMI line is tied to the parity error signal. But also any non-initialized
 
; interrupts get sent here.
 
;------------------------------------------------------------------------------
 
;
 
nmirout:
 
        sw              sp,sp_save
 
        sw              r1,r1_save
 
        sw              r26,r26_save
 
        lw              sp,#0x100001000
 
        outb    r0,0xDCFFFE             ; acknowledge interrupt
 
        lea             r1,msgPerr
 
        call    DisplayString
 
        mfspr   r1,IPC
 
        call    DisplayWord
 
        call    CRLF
 
        lw              sp,sp_save
 
        lw              r1,r1_save
 
        lw              r26,r26_save
        iret
        iret
 
 
 
msgPerr:
 
        db      "Parity error at: ",0
 
 
 
 
;-------------------------------------------
;-------------------------------------------
; NMI routine
; Unimplemented instructions end up here
;-------------------------------------------
;-------------------------------------------
nmirout:
        .align 4
 
ui_irout:
 
        subui   sp,sp,#8
 
        sw              r1,[sp]
 
        lea             r1,msgUnimp
 
        call    DisplayString
 
        mfspr   r1,IPC
 
        call    DisplayWord
 
        call    CRLF
 
        lw              r1,[sp]
 
        addui   sp,sp,#8
 
        ; hang the context
 
ui_irout1:
 
        bra             ui_irout1
        iret
        iret
 
 
 
msgUnimp:
 
        db      "Unimplemented instruction at: ",0
 
 
;-------------------------------------------
;-------------------------------------------
; Handle miss on Data TLB
; Handle miss on Data TLB
;-------------------------------------------
;-------------------------------------------
 
        .align  4
DTLBHandler:
DTLBHandler:
        sw              r1,0xFFFF_FFFF_FFFF_0000
        sw              r1,0xFFFF_FFFF_FFFF_0000
        sw              r2,0xFFFF_FFFF_FFFF_0008
        sw              r2,0xFFFF_FFFF_FFFF_0008
dh1:
dh1:
        omgi    r1,#0            ; try open mutex gate #0 (TLB protector)
        omgi    r1,#0            ; try open mutex gate #0 (TLB protector)
Line 5385... Line 6854...
        org             0xFFFF_FFFF_FFFF_FFC0
        org             0xFFFF_FFFF_FFFF_FFC0
        jmp             DTLBHandler
        jmp             DTLBHandler
        nop
        nop
        nop
        nop
 
 
        ; NMI vector
 
        org     0xFFFF_FFFF_FFFF_FFE0
        org     0xFFFF_FFFF_FFFF_FFE0
        jmp             nmirout
        dw              0                ; 
        nop
        dw              0                ;
        nop
 
 
 
        ; RST vector
        ; RST vector
        org             0xFFFF_FFFF_FFFF_FFF0
        org             0xFFFF_FFFF_FFFF_FFF0
        jmp             start
        jmp             start
        nop
 
        nop
 
 
 
 
; ROM checksum goes here
 
 
 
        org             0xFFFF_FFFF_FFFF_FFF8
 
        dw              0
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.