        TTL     => Middle

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; VecRdLine - Read line from input stream (OSWORD 0 equivalent)

; In    r0 -> buffer for characters
;       r1 = max length of line (excluding carriage return)
;       r2 = lowest character put into buffer
;       r3 = highest character put into buffer
;       wp -> OsbyteVars

; Out   r1 = length of line (excluding carriage return)
;       C=0 => line terminated by return (CR or LF)
;       C=1 => line terminated by ESCAPE

; ReadLine: suggested extensions (available RSN)
;
; are 1) stopping it reflecting control characters/characters not put in the
;        buffer
;     2) making any reflection print a given character (for hiding passwords
;        etc
;
; So, definition is :
;
; Top byte R0 contains flags :
;   Bit 31 set means don't reflect characters that don't go in the buffer
;   Bit 30 set means reflect with the character in R4
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

VecRdLine ROUT

        Push    "R4-R7"
        AND     R7, R0, #&C0000000      ; extract flags
        AND     R4, R4, #&FF
        ORR     R7, R7, R4              ; got flags, potential echo byte in R7

        BIC     R4, R0, #ARM_CC_Mask-3  ; R4 -> buffer

        MOV     R6, #0                  ; R6 = index into buffer
        STRB    R6, PageModeLineCount   ; reset page lines

        B       %FT10
        LTORG

05
        SWI     XOS_WriteC
        BVS     ReadLine_Vset
10
        SWI     XOS_ReadC
        BVS     ReadLine_Vset
        BCS     %FT70                   ; ESCAPE

        LDRB    R5, WrchDest            ; does output include VDU ?
        TST     R5, #2
        BNE     %FT30                   ; no, then still buffer

        LDRB    R5, VDUqueueItems       ; is VDU queueing ?
        TEQ     R5, #0
        BNE     %BT05                   ; yes, then just print

30
        TEQ     R0, #127                ; is it DELETE ?
        TEQNE   R0, #8                  ; or backspace?
        BNE     %FT40                   ; no, then skip

        TEQ     R6, #0                  ; yes, then have we any chars ?
        BEQ     %BT10                   ; no, then loop
        SUB     R6, R6, #1              ; go back 1 char
        MOV     R0, #127
        B       %BT05                   ; print DEL and loop

40
        TEQ     R0, #21                 ; is it CTRL-U ?
        BNE     %FT50                   ; no, then skip

        TEQ     R6, #0                  ; yes, then have we any chars ?
        BEQ     %BT10                   ; no, then loop

45
        SWI     XOS_WriteI+127          ; print DELs to start of line
        BVS     ReadLine_Vset
        SUBS    R6, R6, #1
        BNE     %BT45
        B       %BT10                   ; then loop

50
        TEQ     R0, #13                 ; is it CR ?
        TEQNE   R0, #10                 ; or LF ?
        MOVEQ   r0, #13                 ; always store CR if so
        STRB    R0, [R4, R6]            ; store byte in buffer
        BEQ     %FT60                   ; Exit if either

        CMP     R6, R1                  ; is buffer full ?
        MOVCS   R0, #7                  ; if so, beep and loop
        BCS     %BT05

        CMP     R0, R2                  ; is char >= min ?
        CMPCS   R3, R0                  ; and char <= max ?
        ADDCS   R6, R6, #1              ; if so, then inc pointer
        BCS     %FT80
        CMP     R7, #0                  ; no reflection
        BMI     %BT10                   ; of non-entered chars

80      TST     R7, #1:SHL:30
        ANDNE   R0, R7, #&FF            ; echo char -> R0

        B       %BT05                   ; echo character

60      SWI     XOS_NewLine
        BVS     ReadLine_Vset

; insert code here to call NetVec with R0 = &0D

70
        CLRV
EndReadLine
        MOVVC   R0, R4                  ; restore R0
        MOV     R5, #0
        LDRB    R5, [R5, #ESC_Status]
        MOVS    R5, R5, LSL #(32-6)     ; shift esc bit into carry

        MOV     R1, R6                  ; R1 := length
        Pull    "R4-R7, lr"             ; Always claiming vector
        BIC     lr, lr, #V_bit :OR: C_bit
        MOV     r12, pc
        AND     r12, r12, #V_bit :OR: C_bit
        ORRS    pc, lr, r12             ; back with C, V affected.

ReadLine_Vset
        SETV
        B       EndReadLine

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI OS_Control (deprecated): set handlers

SCTRL   Push    "R0-R3, lr"

        TEQP    PC, #SVC_mode+I_bit ; need IRQs off to get consistent state
        MOV     R0, #EventHandler
        MOV     R1, R3
        BL      CallCESWI
        STR     R1, [stack, #3*4]

        MOV     R0, #EscapeHandler
        LDR     R1, [stack, #2*4]
        BL      CallCESWI
        STR     R1, [stack, #2*4]

        MOV     R0, #ErrorHandler
        Pull    "R1, R3"
        BL      CallCESWI
        MOV     R0, R1
        MOV     R1, R3

        Pull    "R2, R3, lr"
        ExitSWIHandler


CallCESWI
        Push    lr
        MOV     r2, #0                  ; readonly
        SWI     XOS_ChangeEnvironment
        Pull    pc

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI OS_SetEnv (deprecated): Environment setting

SSTENV  Push    "R0, R1, lr"
        TEQP    PC, #SVC_mode+I_bit     ; no irqs - want consistent set.
        MOV     R0, #AddressExceptionHandler
        MOV     R1, R7
        SWI     XOS_ChangeEnvironment
        MOV     R7, R1

        MOV     R0, #DataAbortHandler
        MOV     R1, R6
        SWI     XOS_ChangeEnvironment
        MOV     R6, R1

        MOV     R0, #PrefetchAbortHandler
        MOV     R1, R5
        SWI     XOS_ChangeEnvironment
        MOV     R5, R1

        MOV     R0, #UndefinedHandler
        MOV     R1, R4
        SWI     XOS_ChangeEnvironment
        MOV     R4, R1

        MOV     R0, #MemoryLimit
        LDR     R1, [stack, #4]
        SWI     XOS_ChangeEnvironment
        STR     R1, [stack, #4]

        MOV     R0, #ExitHandler
        Pull    "R1"
        BL      CallCESWI
        Push    "R1"

        MOV     R12, #0
        LDR     R2, [R12, #RAMLIMIT]    ; this is read-only
        MOV     R3, #0                  ; never any Brazil-type buffering
                                        ; m2 tools will complain if there is!
        Pull    "R0, R1, lr"
        ExitSWIHandler

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Change user state SWIs
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

SINTON  BIC     lr, lr, #I_bit
        ExitSWIHandler

SINTOFF ORR     lr, lr, #I_bit
        ExitSWIHandler

SENTERSWI ORR   lr, lr, #SVC_mode
        ExitSWIHandler

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI OS_BreakPt: user breakpoint - unsuitable for debugging SVC mode code!

SBRKPT ROUT

        ADD     sp, sp, #4              ; discard stacked R11
        MOV     r12, #0
        LDR     r12, [r12, #BrkBf]
        SUB     r14, R14, #4
        STR     r14, [r12, #15*4]       ; PC of the SWI put in.
        TST     r14, #SVC_mode
        BNE     %FT01
        STMIA   r12!, {r0}
        MOV     r0, r12
        LDMFD   sp, {r10-r12}
        STMIA   r0, {r1-r12, r13_usr, r14_usr}^ ; user mode case done.

10      LDR     stack, =SVCSTK
        MOV     r12, #BrkAd_ws
        LDMIA   r12, {r12, pc}          ; call breakpoint handler


01      TST     r14, #1                 ; SWI mode?
        TSTNE   r14, #2
        BNE     %FT02                   ; [yes]

        STMIA   r12!, {r0}
        MOV     r0, r12
        LDMFD   sp, {r10-r12}           ; Not banked if IRQ mode
        TEQP    pc, R14                 ; get at registers
        MOVNV   r0, r0
        STMIA   r0, {r1-r14}
        TEQP    pc, #SVC_mode
        B       %BT10


02      MOV     r14, r12                ; supervisor mode. R14 in buffer dead
        LDMFD   sp!, {r10-r12}
        STMIA   r14, {r0-r14}
        B       %BT10

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI OS_UnusedSWI (deprecated): Set the unused SWI handler

SUNUSED Push    "R1, lr"
        MOV     R1, R0
        MOV     R0, #UnusedSWIHandler
        SWI     XOS_ChangeEnvironment
        MOV     R0, R1
        Pull    "R1, lr"
        ExitSWIHandler

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI OS_UpdateMEMC: Read/write MEMC control register

SSETMEMC ROUT

        AND     r10, r0, r1
        MOV     r12, #0
        TEQP    pc, #SVC_mode+I_bit+F_bit
        LDR     r0, [r12, #MEMC_CR_SoftCopy] ; return old value
        BIC     r11, r0, r1
        ORR     r11, r11, R10
        BIC     r11, r11, #&FF000000
        BIC     r11, r11, #&00F00000
        ORR     r11, r11, #MEMCADR
        STR     r11, [r11]
        STR     r11, [r12, #MEMC_CR_SoftCopy]
        TEQP    pc, #SVC_mode+I_bit
        ExitSWIHandler

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI OS_SetCallBack: Set callback flag

SSETCALL ROUT

        TEQP    pc, #SVC_mode+I_bit
        MOV     r10, #0
        LDRB    r11, [r10, #CallBack_Flag]
        ORR     r11, r11, #CBack_OldStyle
        STRB    r11, [r10, #CallBack_Flag]
        Pull    "r11"
        Pull    "r10-r12"
        MOVS    pc, lr                  ; Do NOT exit via normal mechanism

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI read mouse information
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

VecMouse
     MOV   R10, #MouseV
     TEQP  PC, #SVC_mode+I_bit ; no irqs
     Push "lr"
     BL    CallVector
     Pull "lr"
     ExitSWIHandler

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Supervisor routines to set default handlers
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

; Reset Error and Escape handlers

DEFHAN LDR  R1, =GeneralMOSBuffer         ; decent length error buffer
       ADR  R0, ERRORH
       ADR  R2, ESCAPH
       MOV  R3, #0
       MOV  R4, R14
       SWI  XOS_Control

       MOV  r0, #UpCallHandler
       ADR  r1, DefUpcallHandler
       MOV  r2, #0
       SWI  XOS_ChangeEnvironment

       MOV  PC, R4

; Reset Exception, Event, BreakPoint, UnusedSWI, Exit and CallBack handlers

DEFHN2 MOV  R12, R14
       MOV  R0, #0
       MOV  R1, #0
       MOV  R2, #0
       ADR  R3, EVENTH
       SWI  XOS_Control
       LDR  R0, =DUMPER
       ADR  R1, NOCALL
       SWI  XOS_CallBack
       ADRL R0, CLIEXIT
       MOV  R1, #0
       MOV  R2, #0
       ADR  R4, UNDEF
       ADR  R5, ABORTP
       ADR  R6, ABORTD
       ADRL R7, ADDREX
       SWI  XOS_SetEnv
       LDR  R0, =DUMPER
       ADR  R1, DEFBRK
       SWI  XOS_BreakCtrl
       ADRL R0, NoHighSWIHandler
       SWI  XOS_UnusedSWI
       MOV  PC, R12

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; system handlers
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

DefUpcallHandler
ESCAPH
EVENTH  MOV     pc, lr


NOCALL  MOV     r0, #0                  ; default callback routine
        LDR     r14, [r0, #CallBf]
        LDMIA   r14, {r0-r12, r13_usr, r14_usr}^ ; load user's regs
        LDR     r14, [r14, #4*15]
        MOVS    pc, r14


ERRORH ROUT

        SWI     OS_WriteS
        =       10,13,"Error:",10,13, 0
        ALIGN
        LDR     r0, =GeneralMOSBuffer+4
        BL      PrintError
        B       GOSUPV


DEFBRK  SWI     OS_WriteS
        = "Stopped at break point at &", 0
        ALIGN
        TEQP    pc, #0
        MOVNV   r0, r0
        MOV     r13, #0
        LDR     r13, [r13, #BrkBf]
        LDR     r0, [r13, #15*4]
        LDR     r1, =GeneralMOSBuffer
        MOV     r2, #?GeneralMOSBuffer
        SWI     OS_ConvertHex8
        SWI     OS_Write0
        SWI     OS_NewLine

Quit_Code
        SWI     OS_Exit


PrintError
       MOV    R12, R14
       LDR    R10, [R0], #4
       SWI    XOS_Write0
       BVS    %FT02  
       SWI    XOS_WriteS
       =     " (Error number &", 0
       BVS    %FT02
       LDR    R1,=GeneralMOSBuffer
       MOV    R2, #&E0
       MOV    R0, R10
       SWI    XOS_ConvertHex8       ; can't fail!
01     LDRB   R1, [R0], #1
       CMP    R1, #"0"
       BEQ    %BT01
       CMP    R1, #0
       SUBEQ  R0, R0, #1
       SUB    R0, R0, #1
       SWI    XOS_Write0
       SWIVC  XOS_WriteI+")"
       SWIVC  XOS_NewLine
02     MOVS   PC, R12
       LTORG

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Exception handling

DumpyTheRegisters  ROUT

        LDR     R1, [R0, -R0]         ; PC when exception happened
        STR     R1, [R0, #(15-8)*4]   ; In the right slot now ...
        TST     R1, #SVC_mode
        STMEQIA R0, {R8-R14}^         ; user mode case done.
        BEQ     UNDEF1

        TST     R1, #1                ; SWI mode?
        TSTNE   R1, #2
        BNE     %FT02
        ORR     R1, R1, #I_bit :OR: F_bit
                                 ; keep interrupts off until handlers restored
        TEQP    R1, #0                  ; get at registers
        MOVNV   R0, R0
        STMIA   R0, {R8-R14}
        TEQP    PC, #SVC_mode :OR: I_bit :OR: F_bit
        AND     R1, R1, #SVC_mode
        EORS    R2, R1, #FIQ_mode       ; Was we in FIQ ? Zero if so
        MOVEQ   R3, #IOC
        STREQB  R2, [R3, #IOCFIQMSK]    ; Blow away all FIQ sources
        B       UNDEF1

02      STMIA   R0, {R8-R14}

; ... and fall into

UNDEF1  LDR     sp, =SVCSTK             ; Flatten superstack

 [ ExceptionsAreErrors
        MOV     R0, #0
        LDR     R0, [R0, #ExceptionDump]
        ADD     R1, R0, #10*4           ; point at dumped R10
        LDMIA   R1, {R10-R12}           ; try and put back user registers
        Push    "R10-R12"               ; for error handler to find on stack
        LDR     R1, [R0, #15*4]
        Push    R1

        ADRL    R0, (RESET1-8)          ; Store B RESET1 at 0 again
        MOV     R0, R0, LSR #2
        ORR     R0, R0, #&EA000000
        STR     R0, [R1, -R1]

        BIC     R14, R14, #ARM_CC_Mask
        LDR     R0, =GeneralMOSBuffer+128 ; so can do deviant sharing !

        LDR     r11, [r14], #4          ; Copy error number
        STR     r11, [r0], #4

01      LDRB    r11, [r14], #1          ; Copy error string
        STRB    r11, [r0], #1
        CMP     r11, #0                 ; Test for end of string
        BNE     %BT01
        SUB     r1, r0, #1              ; point, ready for conversion

        LDR     R2, =GeneralMOSBuffer+?GeneralMOSBuffer
        SUB     r2, r2, r1              ; amount left in buffer

        MOV     R0, #0
        LDR     R0, [R0, #ExceptionDump]
        LDR     R0, [R0, #15*4]         ; saved PC
        BIC     R0, R0, #ARM_CC_Mask
        SWI     XOS_ConvertHex8

        LDR     R0, =GeneralMOSBuffer+128

        TEQP    PC, #IRQ_mode+I_bit
        MOV     R1, #0
        STR     R1, [R1, #IRQsema]
        LDR     SPIRQ, =IRQSTK
        SWI     OS_GenerateError
   |
        Push    R14
        BL      DEFHAN
        BL      DEFHN2
        Pull    R0
        TEQP    PC, #IRQ_mode
        MOVNV   R0, R0
        LDR     SPIRQ, =IRQSTK
        BIC     R0, R0, #ARM_CC_Mask
        SWI     OS_Write0
        B       UNDEF3
    ]


UNDEF ROUT

        TEQP    pc, #F_bit :OR: I_bit :OR: SVC_mode ; FIQ off too
        STR     R14, [R0, -R0]
        MOV     R14, #0
        LDR     R14, [R14, #ExceptionDump]
        STMIA   R14!, {R0-R7}
        MOV     R0, R14
        BL      DumpyTheRegisters
 [ ExceptionsAreErrors
        MakeErrorBlock UndefinedInstruction
 |
        =       "Undefined instruction at ", 0
        ALIGN
 ]


ABORTP ROUT

        TEQP    pc, #F_bit :OR: I_bit :OR: SVC_mode ; FIQ off too
        STR     R14, [R0, -R0]
        MOV     R14, #0
        LDR     R14, [R14, #ExceptionDump]
        STMIA   R14!, {R0-R7}
        MOV     R0, R14
        BL      DumpyTheRegisters
 [ ExceptionsAreErrors
        MakeErrorBlock InstructionAbort
 |
        =       "Abort on instruction fetch at ", 0
        ALIGN
 ]


ABORTD ROUT

        TEQP    pc, #F_bit :OR: I_bit :OR: SVC_mode ; FIQ off too
        STR     R14, [R0, -R0]
        MOV     R14, #0
        LDR     R14, [R14, #ExceptionDump]
        STMIA   R14!, {R0-R7}
        MOV     R0, R14
        BL      DumpyTheRegisters
 [ ExceptionsAreErrors
        MakeErrorBlock DataAbort
 |
        =       "Abort on data transfer at ", 0
        ALIGN
 ]


ADDREX ROUT

        TEQP    pc, #F_bit :OR: I_bit :OR: SVC_mode ; FIQ off too
        STR     R14, [R0, -R0]
        MOV     R14, #0
        LDR     R14, [R14, #ExceptionDump]
        STMIA   R14!, {R0-R7}
        MOV     R0, R14
        BL      DumpyTheRegisters
 [ ExceptionsAreErrors
        MakeErrorBlock AddressException
 |
        =       "Address exception at ", 0
        ALIGN
 ]


; Can branch through zero in any mode

RESET1 ROUT

        STR     R1, [R0, -R0]
        MOV     R1, #0
        LDR     R1, [R1, #ExceptionDump]
        STMIA   R1, {R0-R15}
        LDR     R0, [R0, -R0]
        STR     R0, [R1, #1*4]
        SWI     XOS_EnterOS

 [ ExceptionsAreErrors
        BL      UNDEF1
        MakeErrorBlock BranchThrough0
 |
        LDR     sp, =SVCSTK
        TEQP    PC, #IRQ_mode
        LDR     SPIRQ, =IRQSTK
        TEQP    PC, #0
        BL      DEFHAN
        BL      DEFHN2
        SWI     OS_WriteS
        =      "Entering Supervisor because of branch through 0", 0
        B       UNDEF2
 ]

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI to call the UpCall vector
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

DoAnUpCall ROUT

        Push    lr                  ; better have one of these to pull later !
        AND     r10, lr, #&F0000000 ; copy user flags (I_bit clear)
        TEQP    r10, #SVC_mode      ; ints on, stay in SVC mode, flags in psr
        MOV     r10, #UpCallV
        BL      CallVector
        Pull    lr
        BIC     lr, lr, #&F0000000
        MOV     R10, PC, LSR #(32-4)
        ORR     lr, lr, R10, LSL #(32-4)
        ExitSWIHandler

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI OS_ChangeEnvironment: Call the environment change vector
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

ChangeEnvironment ROUT

        Push    lr
        MOV     R10, #ChangeEnvironmentV
        BL      CallVector
        Pull    lr
        B       SLVK_TestV


; ..... and the default handler .....

AdjustOurSet
        TEQP    PC, #SVC_mode+I_bit
        CMP     R0, #MaxEnvNumber
        BHI     AOS_Silly

  [ False
        CMP     r0, #CallBackHandler
        BLEQ    testcallbackpending
  ]

        ADR     R10, AOS_Table
        ADD     R11, R0, R0, LSL #1   ; number * 3
        ADD     R10, R10, R11, LSL #2 ; point at entry

        MOV     R12, R1
        LDR     R11, [R10]
        CMP     R11, #0
        LDRNE   R1,  [R11]
        CMPNE   R12, #0
        STRNE   R12, [R11]

        MOV     R12, R2
        LDR     R11, [R10, #4]
        CMP     R11, #0
        LDRNE   R2,  [R11]
        CMPNE   R12, #0
        STRNE   R12, [R11]

        MOV     R12, R3
        LDR     R11, [R10, #8]
        CMP     R11, #0
        LDRNE   R3,  [R11]
        CMPNE   R12, #0
        STRNE   R12, [R11]

        Pull    pc,,^

AOS_Silly
        ADR     r0, ErrorBlock_BadEnvNumber
exit_AOS
        Pull    "lr"
        ORRS    pc, lr, #V_bit
        MakeErrorBlock BadEnvNumber

   [ False

testcallbackpending
        CMP     r1, #0                ; OK if only reading
        CMPEQ   r2, #0
        CMPEQ   r3, #0
        LDRNEB  r10, [r0, #CallBack_Flag-CallBackHandler]
        TSTNE   r10, #CBack_OldStyle
        MOVEQ   pc, r14
  SetBorder r0, r14, 15, 0, 0
        ADR     r0, ErrorBlock_CallbackPending
        B       exit_AOS
        MakeErrorBlock CallbackPending
   ]

AOS_Table
        &  MemLimit     ;  MemoryLimit
        &  0
        &  0

        &  UndHan       ; UndefinedHandler
        &  0
        &  0
    
        &  PAbHan       ; PrefetchAbortHandler
        &  0
        &  0

        &  DAbHan       ; DatabortHandler
        &  0
        &  0

        &  AdXHan       ; AddressExceptionHandler
        &  0
        &  0

        &  0            ; OtherExceptionHandler
        &  0
        &  0

        &  ErrHan       ; ErrorHandler
        &  ErrHan_ws
        &  ErrBuf

        &  CallAd       ; CallBackHandler
        &  CallAd_ws
        &  CallBf

        &  BrkAd        ; BreakPointHandler
        &  BrkAd_ws
        &  BrkBf

        &  EscHan       ; EscapeHandler
        &  EscHan_ws
        &  0

        &  EvtHan       ; EventHandler
        &  EvtHan_ws
        &  0

        &  SExitA       ; ExitHandler
        &  SExitA_ws
        &  0

        &  HiServ       ; UnusedSWIHandler
        &  HiServ_ws
        &  0

        &  ExceptionDump ; ExceptionDumpArea
        &  0
        &  0

        &  AplWorkSize  ; application space size
        &  0
        &  0

        &  Curr_Active_Object
        &  0
        &  0

        &  UpCallHan
        &  UpCallHan_ws
        &  0

        assert (.-AOS_Table)/12 = MaxEnvNumber

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI OS_ReadDefaultHandler

; In    r0 = environment number

ReadDefaultHandler ROUT

        CMP     r0, #(dhte-defhantab)/12
        MOVHS   r0, #0                  ; return wally value
        ADD     r10, r0, r0, LSL #1     ; *3
        ADD     r10, pc, r10, LSL #2    ; *4 (pc = defhantab-4)
        LDMIB   r10, {r1-r3}            ; gives additional +4
        ExitSWIHandler

defhantab
     & 0                ; wally entry
     & 0
     & 0

     & UNDEF            ; UndefinedHandler
     & 0
     & 0

     & ABORTP           ; PrefetchAbortHandler
     & 0
     & 0

     & ABORTD           ; DataAbortHandler
     & 0
     & 0

     & ADDREX           ; AddressExceptionHandler
     & 0
     & 0

     & 0                ; OtherExceptionHandler
     & 0
     & 0

     & ERRORH           ; ErrorHandler
     & 0
     & GeneralMOSBuffer

     & NOCALL           ; CallBackHandler
     & 0
     & DUMPER

     & DEFBRK           ; BreakPointHandler
     & 0
     & DUMPER

     & ESCAPH           ; EscapeHandler
     & 0
     & GeneralMOSBuffer

     & EVENTH           ; EventHandler
     & 0
     & 0

     & CLIEXIT          ; ExitHandler
     & 0
     & 0

     & NoHighSWIHandler ; UnusedSWIHandler
     & 0
     & 0

     & 0                ; exception dump
     & 0
     & 0

     & 0                ; app space size
     & 0
     & 0

     & 0                ; cao pointer
     & 0
     & 0

     & DefUpcallHandler ; upcall handler
     & 0
     & 0

dhte

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; In    r0 = sysinfo handle

; Out   r0 = sysinfo for r0in

ReadSysInfo_Code
        Push    "r1, r2, lr"
        CMP     r0, #0
        Pull    "r1, r2", NE
        BNE     AOS_Silly
        MOV     r0, #ReadCMOS
        MOV     r1, #ScreenSizeCMOS
        SWI     XOS_Byte
        MOV     r10, #0
        LDR     r10, [r10, #Page_Size]
        MULTIPLY r0, r2, r10

        CMP     r0, #0
        BNE     RSICmosScreenWillDo

        LDR     r0, [r0, #RAMLIMIT]     ; If 305 then ScreenSize 0 -> 80K
        CMP     r0, #512*1024           ; otherwise 160K
        MOVEQ   r0, #80*1024
        MOVNE   r0, #160*1024

RSICmosScreenWillDo
        CMP     r0, #20*1024            ; ensure mode 0 gettable
        MOVLT   r0, #20*1024
        CMP     r0, #480*1024           ; Can't have > 480K in the screen
        MOVGT   r0, #480*1024
        Pull    "r1, r2, lr"
        ExitSWIHandler

        LNK     Super1
