; Copyright 1996 Acorn Computers Ltd ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; ; > $.Source.PMF.osbyte ; New version of OSBYTE which claims the ByteV(ector) properly ; PMF 18/9/86 ; Updates: ; Kernel ; Version Date Who Why ; 2.01 15-June-90 JSR Change OS_Byte 124/125/126 to update the CallBack_Flag byte ; correctly, rather than setting it to 1. The bug caused vector ; callbacks to be delayed over much when escape was pressed. ; ???? 08-Feb-95 WT Change OS_Byte 106 to support the new cursor storage method ; introduced for Stork LCD support. OsbyteLowLimit * &6A ; osbytes lower than this get Y set to 0 OsbyteVeryLow * &1A ; osbytes lower than this are all recognised OsbyteSetCountry * &46 OsbyteSetAlphKey * &47 OsbyteKeyStatus * &CA ; only OS_Byte variable which isn't pure any more! ArthurINKEY256 * &A7 ; INKEY-256 value ; ***************************************************************************** GBLS ByteRegs GBLA StackOffset [ AssemblingArthur :LOR: Module ByteRegs SETS "" StackOffset SETA 4*4 ; stack offset in osbyte routines to user pc | ByteRegs SETS "R11, WsPtr," StackOffset SETA 6*4 ; stack offset in osbyte routines to user pc ] MACRO MyOsbyte $cond B$cond GoMyOsbyte MEND MACRO MyOsWord $cond B$cond GoMyOsword MEND MACRO Unused $cond MOV$cond PC, R14 ; just return and let the next person have a go MEND MACRO ByteReturnV $cond [ AssemblingArthur :LOR: ErrorsInR0 ASSERT "$cond"="" :LOR: "$cond"="VS" [ "$cond"="" Pull "R0,R3,$ByteRegs R14,PC", VC ] ADDVS R13, R13, #4 ; junk stacked R0 Pull "R3,$ByteRegs R14,PC", VS | Pull "R0,R3,$ByteRegs R14,PC", $cond ; for GenError systems ] MEND ; Main OSbyte entry point ; R0,R1,R2 are parameters OsByte [ AssemblingArthur :LOR: Module Push "R0, R3, $ByteRegs R14" BL OsByteGo ; Call the subsid entry pt. Pull "R0,R3" Push "R0-R4" LDMIA R13, {R2-R4} ; R2=A, R3=X, R4=Y MOV R1, #Service_UKByte ; osbyte service reason IssueService TEQ R1, #0 STMEQIA R13, {R2-R4} ; if claimed, then update ; returned R0-R2 CLRPSR V_bit, R3 ; clear V flag Pull R0 ADRNE R0, BadCommandError ; not claimed, R0 -> error [ International BLNE TranslateError ] SWINE XOS_GenerateError ; set V if not claimed Pull "R1-R4, $ByteRegs R14, PC" BadCommandError MakeErrorBlock BadCommand | Push "R0, R3, $ByteRegs R14" BL OsByteGo Pull "R0, R3, $ByteRegs PC" ; no services, so pass it on ] GoMyOsbyte CLRPSR V_bit, R3 Pull "R0,R3, $ByteRegs R14,PC" ; pull the world AND the PC to return ; ***************************************************************************** OsByteGo ROUT [ :LNOT: AssemblingArthur :LAND: :LNOT: Module BYTEWS WsPtr ] AND R0, R0, #&FF ; no funny business! SUBS R3, R0, #OsbyteLowLimit ; is it a low one ? BCS HiOsbyte MOV R2, #0 ; lo one, so set Y to 0 CMP R0, #OsbyteVeryLow ; is it one we recognise ? 10 ADDCC PC, PC, R0, LSL #2 ; then go thru despatch table B TryInternational ; else issue unknown osbyte service 20 ASSERT %BT20-%BT10 = 8 BAL Osbyte00 BAL Osbyte01 BAL Osbyte02 BAL Osbyte03 BAL Osbyte04 BAL Osbyte05 BAL Osbyte06 BAL Osbyte07 BAL Osbyte08 BAL Osbyte09 BAL Osbyte0A BAL Osbyte0B BAL Osbyte0C BAL Osbyte0D BAL Osbyte0E BAL Osbyte0F BAL Osbyte10 BAL Osbyte11 BAL Osbyte12 BAL Osbyte13 BAL Osbyte14 BAL Osbyte15 BAL Osbyte16 BAL Osbyte17 BAL Osbyte18 BAL Osbyte19 HiOsbyte CMP R0, #MainVars ; is it a variable ? 30 ADDCC PC, PC, R3, LSL #2 B DoOsbyteVar ; yes, then do variable mangling 40 ASSERT %BT40-%BT30=8 BAL Osbyte6A BAL Osbyte6B BAL Osbyte6C BAL Osbyte6D BAL Osbyte6E BAL Osbyte6F BAL Osbyte70 BAL Osbyte71 BAL Osbyte72 BAL Osbyte73 BAL Osbyte74 BAL Osbyte75 BAL Osbyte76 BAL Osbyte77 BAL Osbyte78 BAL Osbyte79 BAL Osbyte7A BAL Osbyte7B BAL Osbyte7C BAL Osbyte7D BAL Osbyte7E BAL Osbyte7F BAL Osbyte80 BAL Osbyte81 BAL Osbyte82 BAL Osbyte83 BAL Osbyte84 BAL Osbyte85 BAL Osbyte86 BAL Osbyte87 BAL Osbyte88 BAL Osbyte89 BAL Osbyte8A BAL Osbyte8B BAL Osbyte8C BAL Osbyte8D BAL Osbyte8E BAL Osbyte8F BAL Osbyte90 BAL Osbyte91 BAL Osbyte92 BAL Osbyte93 BAL Osbyte94 BAL Osbyte95 BAL Osbyte96 BAL Osbyte97 BAL Osbyte98 BAL Osbyte99 BAL Osbyte9A BAL Osbyte9B BAL Osbyte9C BAL Osbyte9D BAL Osbyte9E BAL Osbyte9F BAL OsbyteA0 BAL OsbyteA1 BAL OsbyteA2 BAL OsbyteA3 BAL OsbyteA4 BAL OsbyteA5 TryInternational ; special ones in the middle TEQ R0, #OsbyteSetCountry BEQ DoOsbyteSetCountry TEQ R0, #OsbyteSetAlphKey BEQ DoOsbyteSetAlphKey MOV PC, R14 ; ***************************************************************************** ; The Osbyte routines themselves ; Mos version number and title string ; R1 = 0 -> give an error with and string MosTitle ; R1 <>0 -> RETURN with R1 = MosVer ; R2 is Preserved Osbyte00 ROUT TEQ R1, #0 MOVNE R1, #MosVer MyOsbyte NE ADR R0, FX0Error SWI XOS_GenerateError ByteReturnV FX0Error & &F7 = "$MosTitle",0 ALIGN ; ***************************************************************************** ; Write User Flag Osbyte01 V2B156 ADD R0, R0, #&F0 ; convert 1,5,6 to &F1,&F5,&F6 B DoOsbyteVar ; Select input stream Osbyte02 ROUT AND R0, R1, #1 ; new buffer id TEQ R1, #0 ; 0 => disable RXI [ DriversInKernel MOVNE R1, #RXEN6850 ; else enable RXI MOV R2, #(&FF :EOR: RXEN6850) ; AND mask (R1 = EOR mask) BL ModifyControl6850 ; on exit, R1 = old control reg LDRB R2, RS423conflag ; R2 = new control reg Push "R1, R2" BL RSETX ; try to enable RX interrupts Pull "R1, R2" TEQ R1, R2 BEQ %FT10 ; no change in RXI Push R11 ; now purge data register when going LDR R11, =ACIA ; from disabled -> enabled; (also LDRB R1, ACIARxData ; does it for enabled -> disabled, this ; is irrelevant) Pull R11 10 | Push "r0" BNE %FT10 ; [enabling serial] ; disable serial by closing stream LDRB r1, SerialInHandle TEQ r1, #0 MOVNE r0, #0 ; close file if handle non-zero STRNEB r0, SerialInHandle ; zero handle first SWINE XOS_Find B %FT20 ; enable serial by opening stream 10 LDRB r0, SerialInHandle TEQ r0, #0 ; if a stream open already BNE %FT20 ; then skip MOV r0, #open_read + open_mustopen ADR r1, SerialInFilename ; open serial stream for input SWI XOS_Find STRVCB r0, SerialInHandle ; if did open then store handle ; (may store same value if already open, but who cares?) 20 Pull "r0" ] LDRB R1, InputStream ; old input stream STRB R0, InputStream MyOsbyte LTORG [ :LNOT: DriversInKernel SerialInFilename = "Serial#Buffer1:", 0 ALIGN ] ; Select output stream Osbyte03 Osbyte04 ; select cursor keys actions V2B34 ADD R0, R0, #&E9 ; convert 3,4 to &EC,&ED B DoOsbyteVar ; Write Printer driver type Osbyte05 ROUT BL MakePrinterDormant ; for netprint MOV R14, PC ; for restoring I afterwards 10 MVN R3, #I_bit TSTP R3, PC ; CLI TEQP R14, #0 ; restore old I MOV R3, #0 LDRB R3, [R3, #ESC_Status] TST R3, #&40 MyOsbyte NE ; ESCAPE, so don't change LDR R3, PrinterActive TEQ R3, #0 BNE %BT10 ; still active, then loop ; insert code here to notify UPTVEC of change B V2B156 ; R0 = 5, update variable ; Write Printer Ignore Character Osbyte06 STRB R2, NoIgnore ; (R2=0) allow chars to be ignored B V2B156 [ DriversInKernel ; Write RS423 receive rate Osbyte07 BL DoOsbyte07 MyOsbyte ; Write RS432 transmit rate Osbyte08 BL DoOsbyte08 MyOsbyte | ; Write RS423 receive rate ; Write RS432 transmit rate Osbyte07 Osbyte08 SUB r0, r0, #2 ; 7 -> 5; 8 -> 6 SWI XOS_SerialOp MyOsbyte ] [ DriversInKernel ; Modified 30-Mar-88 to handle new baud rates ; Format of SerULAreg is as follows:- ; Bit Contents ; 7 TX3 ; *** NEW *** ; 6 RX3 ; *** NEW *** ; 5 RX2 ; 4 RX1 ; 3 RX0 ; 2 TX2 ; 1 TX1 ; 0 TX0 ; FX7/8 RX/TX bits above Baud ; value 3 2 1 0 rate ; ; 1 0 1 1 1 75 ; 2 0 0 1 1 150 ; 3 0 1 0 1 300 ; 4 0 0 0 1 1200 ; 5 0 1 1 0 2400 ; 6 0 0 1 0 4800 ; 7 or 0 0 1 0 0 9600 ; 8 0 0 0 0 19200 ; 9 1 0 1 1 50 ; 10 1 1 0 1 109.92 ; 11 1 0 0 1 134.58 ; 12 1 1 1 0 600 ; 13 1 0 1 0 1800 ; 14 1 1 0 0 3600 ; 15 1 0 0 0 7200 ; 16 1 1 1 1 Undefined DoOsbyte07 ROUT Push "R11, R14" LDRB R2, SerULAreg CMP R1, #16+1 BCS %FT10 ; invalid ADR R3, SerBaudTable ; point to silly serproc table LDRB R3, [R3, R1] ; get entry BIC R0, R2, #&78 ; clear old bits ORR R0, R0, R3, LSL #3 ; or in new bits DoFx7or8 STRB R0, SerULAreg ; first set up the carry flag to indicate whether RX = TX AND R1, R0, #&07 ; get Tx bits 0-2 TST R0, #&80 ORRNE R1, R1, #&08 ; R1 = Tx bits EOR R3, R1, R0, LSR #3 ; EOR Rx and Tx bits AND R3, R3, #15 ; ignore other bits CMP R3, #1 ; C=1 => different ; now program both RX and TX (start with TX) ADR R3, TxBaudTable ; (R1 = Tx bits) LDRB R3, [R3, R1] MOV R1, R0, LSR #3 ; R1 = RX bits for later AND R1, R1, #15 PHPSEI ; NB preserves carry LDR R11, =ACIA LDRB R0, ACIAControl ; replace old baud bits with new AND R0, R0, #(ACIASBN :OR: ACIAWL1 :OR: ACIAWL0) ORR R0, R0, R3 ; external RX clock by default ORRCC R0, R0, #&10 ; if RX=TX use internal RX clock STRB R0, ACIAControl BCC %FT20 ; if RX=TX then we've finished ADR R3, RxBaudTable ; point to timer latch values table LDR R3, [R3, R1, LSL #2] ; get entry MOV R0, #IOC STRB R3, [R0, #Timer2LL] MOV R3, R3, LSR #8 STRB R3, [R0, #Timer2LH] STRB R3, [R0, #Timer2GO] 20 PLP 10 MOV R1, R2 ; R1 = R2 = "old serproc contents" Pull "R11, PC" DoOsbyte08 Push "R11, R14" LDRB R2, SerULAreg CMP R1, #16+1 BCS %BT10 ; invalid ADR R3, SerBaudTable ; point to silly serproc table LDRB R3, [R3, R1] ; get entry BIC R0, R2, #&87 ; clear old bits TST R3, #8 ; if bit 3 is set EORNE R3, R3, #&88 ; then move to bit 7 ORR R0, R0, R3 ; OR in new bits B DoFx7or8 LTORG SerBaudTable = 4, 7, 3, 5, 1, 6, 2, 4, 0 ; silly table for BBC compat = 11, 13, 9, 14, 10, 12, 8, 15 TxBaudTable ; ordered on values in SerBaudTable = Baud19200, Baud1200, Baud4800, Baud150 = Baud9600, Baud300, Baud2400, Baud75 = Baud7200, Baud135, Baud1800, Baud50 = Baud3600, Baud110, Baud600, BaudUndef ALIGN RxBaudTable ; ordered on values in SerBaudTable & 2, 51, 12, 416, 6, 207, 25, 832 & 8, 463, 34, 1249, 16, 568, 103, 0 ] ; Write First Flash Time Osbyte09 MOV R2, #1 ; and drop thru to ... ; Write Second Flash Time Osbyte0A ; (R2=0) Osbyte910 MOV R0, R1 ; new period LDRB R1, [R2, #OsbyteVars + :INDEX: SpacPeriod] ; get old state STRB R0, [R2, #OsbyteVars + :INDEX: SpacPeriod] ; store new LDRB R3, FlashCount TEQ R3, #0 ; are we frozen ? MyOsbyte NE ; no, then finish STRB R0, FlashCount ; kick the counter STRB R2, FlashState ; force new state VDWS WsPtr TEQ R2, #0 BEQ ForceSecondState Push "R1,R2" BL DoFirstFlash Pull "R1,R2" MyOsbyte ForceSecondState Push "R1,R2" BL DoSecondFlash Pull "R1,R2" MyOsbyte ; Write Keyboard Delay Osbyte0B V2BBC ADD R0, R0, #(&C4-&0B) B DoOsbyteVar ; Write Keyboard Rate Osbyte0C TEQ R1, #0 BNE V2BBC CLRPSR I_bit, R0 ; this may take some time BL ReadKeyDefaults MyOsbyte ; ***************************************************************************** ; Disable / Enable Events ; R1 = Event number. Decrement/Increment semaphore for this event Osbyte0D ROUT Osbyte0E ROUT CMP R1, #32 ; if illegal event number MOVCS R2, #0 ; then return + say was disabled BCS %FT10 ADD R3, WsPtr, #:INDEX: EventSemaphores LDRB R2, [R3, R1] ; get semaphore for this event CMP R0, #13 ; 13 => disable, 14 => enable SUBEQ R0, R2, #1 ; decrement semaphore ADDNE R0, R2, #1 ; increment semaphore CMP R0, #&100 ; C=1 => wrapped, so don't store back STRCCB R0, [R3, R1] 10 MOV R1, R2 ; R1 = R2 = old semaphore MyOsbyte ; ***************************************************************************** ; Flush Buffer Osbyte0F ROUT TEQ R1, #0 BNE FlushInput BL FlushAll MyOsbyte ; flush all buffers FlushAll Push R14 MOV R1, #(NBuffers-1) 10 BL FlushThis SUBS R1, R1, #1 BPL %BT10 Pull PC ; flush input buffer FlushInput LDROSB R1, InputStream ; get buffer id of input stream BL FlushThis MyOsbyte ; ***************************************************************************** ; Clear out the softkeys Osbyte12 ROUT MOV R0, #0 STRB R0, SoftKeyLen ; purge current expansion MOV R11, #KeyWorkSpace ; can corrupt R11 Push R4 MOV R1, #15 10 MOV R3, R1 BL SetupKeyName ; exits with R0 -> SoftKeyName MOV R2, #-1 ; destroy variable MOV R3, #0 ; context pointer 0 MOV R4, #0 ; type irrelevant SWI XOS_SetVarVal ; V will be set if not present SUBS R1, R1, #1 BPL %BT10 Pull R4 MyOsbyte ; ***************************************************************************** ; Wait for Vsync Osbyte13 ROUT MOV R14, PC ; bug fix for MED-03165. Having a DPMS-blanked screen stopped printing. ; The reason is that HSyncs stop and VSyncs stop as a consequence, ; but the Hourglass module uses this call to wait for the next VSync ; before animating the hourglass. ; When the screen is DPMS-blanked this osbyte will now return ; immediately. This is equivalent to the operation of the DPMSUtils ; module shipped with OS 3.50. VDWS R2 LDRB R0, [R2,#ScreenBlankFlag] LDRB R1, [R2,#ScreenBlankDPMSState] TEQ R0, #0 ; NE => blanked TSTNE R1, #1 ; NE => blanked and DPMS turned off HSyncs BNE %FT20 ; if true exit immediately LDRB R2, CFStime 10 TEQP R14, #I_bit ; CLI ;StrongARM core will not see interrupt unless disable is cleared for at least 5 cycles, ;in order to fill synchroniser pipe [ StorkPowerSave NOP MOV R0, #0 LDRB R0, [R0, #PortableFlags] TST R0, #PortableFeature_Idle SWINE XPortable_Idle | NOP NOP NOP NOP NOP ] TEQP R14, #0 ; SEI LDRB R1, CFStime TEQ R1, R2 BEQ %BT10 20 MyOsbyte ; ***************************************************************************** ; Restore font definitions Osbyte14 MOV R1, #1 ; start at character 1*32 MOV R2, #3 ; do 3 pages B ResetPartFont ; ***************************************************************************** ; Flush Selected Buffer Osbyte15 ROUT ; ; TMD 24-Apr-92: Don't check buffer number, as this prevents the flushing ; of buffer manager buffers. ; ; CMP R1, #NBuffers ; BCS %FT10 ; invalid buffer number BL FlushThis ;10 MyOsbyte FlushThis ; code inserted here to zero PrinterActive iff you are flushing the printer ; buffer and the print destination is not a stream one [ DriversInKernel TEQ R1, #Buff_Print ; is it the printer buffer ? BNE %FT15 ; no, then skip LDRB R0, PrinterDrivType ; if printer type 0, 1 or 2 CMP R0, #3 MOVCC R0, #0 ; then mark printer dormant STRCC R0, PrinterActive 15 ] CMP R1, #Buff_RS423Out ; is it an input buffer ? (not mouse) BCS %FT20 ; no, then branch MOV R0, #0 STRB R0, SoftKeyLen ; kill soft key expansion STRB R0, VDUqueueItems ; flush VDU queue 20 SETV ; indicate purge not count B CnpEntry ; Reset Group of font definitions Osbyte19 ROUT CMP R1, #8 MyOsbyte CS ; not in range 0..7, ignore TEQ R1, #0 MOVEQ R1, #1 ; if 0 then start at 1*32, do 7 pages MOVEQ R2, #7 MOVNE R2, #1 ; else start at n*32, do 1 page ResetPartFont ; first offer to International module Push "R1, R2, R4, R5" MOV R4, R1, LSL #5 ; R4 = start character ADD R5, R4, R2, LSL #5 ; R5 = end character+1 SUB R5, R5, #1 ; R5 = end character LDRB R3, Alphabet MOV R2, #Inter_Define BL OfferInternationalService Pull "R1, R2, R4, R5" MyOsbyte EQ ; if claimed, don't use hard font ByteToNosbod DoResetFont MyOsbyte ; ***************************************************************************** ; Set country number ; in: R1 = country number DoOsbyteSetCountry ROUT TEQ R1, #&7F ; if 127, just read country LDREQB R1, Country MyOsbyte EQ BL GetCountry Push R4 BL ConvertCNoToANo ; convert country no. to alphabet no. Pull R4, NE MOVNE R1, #0 ; if not claimed, return with X=0 MyOsbyte NE ; was claimed, so have country number in R1 and R3, alphabet no. in R4 LDRB R1, Country ; save old country STRB R3, Country ; store new country STRB R4, Alphabet ; and new alphabet BL NewKeyboard ; R3=new keyboard, R4=alphabet for it BL SetAlphabet Pull R4 MyOsbyte SetAlphabet Push "R1,R5,R14" MOV R2, #Inter_Define ; now redefine the chars MOV R3, R4 MOV R4, #32 MOV R5, #255 BL OfferInternationalService Pull "R1,R5,PC" ConvertCNoToANo MOV R3, R1 ; put country no. in R3 MOV R2, #Inter_CNoToANo OfferInternationalService Push R14 MOV R1, #Service_International IssueService TEQ R1, #0 ; set Z flag if claimed Pull PC ; Notify keyboard handler of new keyboard NewKeyboard Push "R1,R4,R14" STRB R3, Keyboard STRB R4, KeyAlphabet MOV R2, #Inter_Keyboard BL OfferInternationalService Pull "R1,R4,PC",,^ ; ***************************************************************************** ; Set keyboard/alphabet for a particular country DoOsbyteSetAlphKey ROUT TST R1, #&80 ; if set then setting keyboard BNE %FT10 ; [setting keyboard] ; setting alphabet TEQ R1, #&7F ; 127 => just read alphabet LDREQB R1, Alphabet MyOsbyte EQ ; 20/8/87 added code to do setting of default alphabet BL GetCountry Push R4 BL ConvertCNoToANo ; try to convert R1 to alphabet number MOVNE R4, R3 ; if failed, try without converting BL SetAlphabet ; try to set this alphabet Pull R4 MOVNE R1, #0 ; if not claimed, return with X=0 MyOsbyte NE LDRB R1, Alphabet STRB R3, Alphabet MyOsbyte ; setting keyboard 10 AND R1, R1, #&7F TEQ R1, #&7F ; 127 => just read keyboard LDREQB R1, Keyboard MyOsbyte EQ BL GetCountry Push R4 BL ConvertCNoToANo ; validating country no. Pull R4, NE MOVNE R1, #0 ; if not claimed, return with X=0 MyOsbyte NE LDRB R1, Keyboard ; load old keyboard BL NewKeyboard ; R3=new keyboard, R4=alphabet for it Pull R4 MyOsbyte ; ***************************************************************************** ; All osbytes from &1A to &69 are unused (apart from international ones!) ; End of unused block ; Write pointer shape number, mouse linkage ; ; R1 = 0 => pointer off ; R1 = 1..4 => use pointer shape 1..4, linked to mouse ; R1 = &81..&84 => use pointer shape 1..4, unlinked ; [ LCDSupport ;Must copy the shape from the buffer image into the 'current' buffer (ie create 4 instances) Osbyte6A ;;;don't do a wait for vsync ;;; [ Fix8 ;;; CLRPSR I_bit, R0 ; could take some time ;;; ] ;;; MOV R3, R1 ; OS_Byte 19 corrupts R1 & R2 (why oh why oh why oh why oh why...) ;;; MOV R0, #19 ; wait for vsync, so we change ;;; SWI XOS_Byte ; cleanly (ignore errors) ;;; MOV R1, R3 VDWS R0 LDRB R3, [R0, #PointerShapeNumber] ; get old shape number AND R2, R1, #&7F ; allow 0..4, &80..&84 CMP R2, #4+1 STRCCB R1, [R0, #PointerShapeNumber] MOV R1, R3 MyOsbyte CS ;Leave if pointer shape was out of range CMP R2, #0 MyOsbyte EQ ;Leave if pointer shape was 'off' Push "r0-r12,r14" SUB R2, R2, #1 ;Now in range 0-3 LDR R0, =CursorData MOV R1, R0 ;R1 points to 1st current image ADD R0, R0, #&400 ;R0 points to the start of the buffer images ADD R0, R0, R2, LSL #8 ;Now, it points to the source buffer image ADD R2, R1, #&100 ;R2 points to 2nd current image ADD R3, R2, #&F8 ;R3 points to 3rd current image (top line will get lost, on purpose!) ADD R4, R3, #&100 ;R4 points to 4th current image (correct wrt 3rd image) ;StrongARM note: cursor area is now marked cacheable/bufferable (so that SWI despatch etc. is also) ;However, since the area for the current cursor (@ CursorData, &400 bytes) is never read by RISC OS, ;it can never be in the cache, so there is no need to clean the write-back cache to force the new data ;out. All that remain is the write buffer, but this will drain quickly without help. ; ADD R5, R0, #&100 ;R5 is the end address. 11 LDMIA R0!, {R6-R12,R14} STMIA R1!, {R6-R12,R14} STMIA R2!, {R6-R12,R14} STMIA R3!, {R6-R12,R14} STMIA R4!, {R6-R12,R14} CMP R0, R5 BNE %BT11 ;Keep going, more to do Pull "r0-r12,r14" MyOsbyte ;This is a silly macro! | Osbyte6A VDWS R0 LDRB R3, [R0, #PointerShapeNumber] ; get old shape number AND R2, R1, #&7F ; allow 0..4, &80..&84 CMP R2, #4+1 STRCCB R1, [R0, #PointerShapeNumber] MOV R1, R3 MyOsbyte ] ; Set vdu driver's screen number Osbyte70 ByteToNosbod DoSetDriverBank MyOsbyte ; Set displayed screen number Osbyte71 ByteToNosbod DoSetDisplayBank MyOsbyte ; *SHADOW Osbyte72 MOV R0, #&EF ; redirect to shadow variable MOV R2, #0 B DoOsbyteVar ; ***************************************************************************** ; Read VDU Status Osbyte75 Push R2 ByteToNosbod DoReadVDUStatus Pull R2 MyOsbyte ; Reflect Keyboard Status In LEDs Osbyte76 MOV R11, #KeyWorkSpace MOV R12, #IOC BL UpdateLEDs MyOsbyte ; Write Keys Pressed Info Osbyte78 BL WriteKeysDown MyOsbyte ; Perform Keyboard Scan from 16 Osbyte7A MOV R1, #&10 ; and drop thru to ... ; Perform Keyboard Scan Osbyte79 BL BBCScanKeys MyOsbyte ; Inform OS Printer Driver going Dormant Osbyte7B BL MakePrinterDormant ByteReturnV ; Clear Escape Condition Osbyte7C BL DoOsbyte7C MyOsbyte ; Set Escape Condition Osbyte7D BL DoOsbyte7D MyOsbyte DoOsbyte7C Push "R11, R14" MOV R11, #0 B Osbyte7C7D DoOsbyte7D Push "R11, R14" MOV R11, #&FF Osbyte7C7D [ AssemblingArthur :LOR: Module MOV R12, #EscHan_ws STRB R11, [R12, #ESC_Status-EscHan_ws] ; set escape flag MOV R14, PC LDMIA R12, {R12, PC} | MOV R12, #0 STRB R11, [R12, #ESC_Status] ; set escape flag MOV R14, PC ; ADRS R14, Exit7D LDR PC, [R12, #EscHan] ] Exit7D TEQ R12, #1 [ Version >= 201 Pull "R11, PC", NE MOV R11, PC ; Preserve old processor state ORR R12, R11, #SVC_mode ; Switch to SVC mode preserving IRQ_bit TEQP R12, #0 NOP Push R14 ; Preserve SVC_R14 SWI XOS_SetCallBack ORRVS R11, R11, #V_bit ; Preserve V_bit Pull R14 ; Restore SVC_R14 TEQP R11, #0 ; Switch back to original mode, with V_bit intact from SWI NOP Pull "R11, PC" | STREQB R12, [R12, #IRQ_CallBack_Flag-1] ] Pull "R11, PC" ; Acknowledge ESCAPE Osbyte7E ROUT MOV R3, #0 LDRB R3, [R3, #ESC_Status] TST R3, #&40 BEQ NoESCToAck ; escape flag clear LDRB R0, ESCeffect TEQ R0, #0 BNE NoESCToAck ; escape effects disabled CLRPSR I_bit, R0 ; enable interrupts (doing SOUNDs and ; closing files may take some time!) [ AssemblingArthur :LOR: Module SWI XSound_QInit BVS %FT99 ; no noises anyway! LDR R0, =&01010008 ; channel 8, amplitude &101 MOV R1, #&00010000 ; pitch 0, duration 1 10 SWI XSound_ControlPacked BVS %FT99 ; (R0 would be corrupted) SUB R0, R0, #1 ; decrement channel TST R0, #&FF ; if channel <> 0 then loop BNE %BT10 99 MOV R0, #0 ] STRB R0, PageModeLineCount ; zero line count LDRB R1, ExecFileH CMP R1, #0 ; is EXEC file open (and V:=0) STRNEB R0, ExecFileH ; if so, zero handle and close ; (will enable IRQs for me) SWINE XOS_Find ; (R0=0, R1=handle) ByteReturnV VS ; if error then bomb out BL FlushAll NoESCToAck BL DoOsbyte7C ANDS R1, R3, #&40 ; set R1 to 0 if wasn't escape, MOVNE R1, #&FF ; &FF if was MyOsbyte ; Check for EOF Osbyte7F MOV R0, #OSArgs_EOFCheck SWI XOS_Args ; result comes back in R2 MOV R1, R2 ByteReturnV ; ***************************************************************************** ; Read ADC or buffer status Osbyte80 AND R1, R1, #&FF ; no funny business TST R1, #&80 ; is it ADVAL(-n) BEQ AdvalPositive ; no, then do adval(+ve) EOR R1, R1, #&FF ; convert to buffer number CLC ; (C:=0 and V:=0) TEQ R1, #Buff_Mouse ; is it mouse (only input buf >= 2) ? CMPNE R1, #Buff_RS423Out ; C=1 <=> output buffer, so count spaces ; V=0, so will do count not purge ADR R14, MyOsbyte80 CnpEntry Push "R10,R12,R14" MOV R10, #CNPV B GoVec MyOsbyte80 MyOsbyte AdvalPositive ROUT TEQ R1, #7 TEQNE R1, #8 Unused NE Push R11 MOV R11, R1 ; save adval number SWI XOS_Mouse Pull R11, VS ByteReturnV VS TEQ R11, #7 MOVEQ R1, R0 ; R1 is required value MOV R2, R1, LSR #8 ; put lo in R1, hi in R2 AND R1, R1, #&FF AND R2, R2, #&FF Pull R11 MyOsbyte ; ***************************************************************************** ; Perform INKEY operation Osbyte81 ROUT TST R2, #&80 ; is it negative inkey ? BEQ %FT10 ; no, then not INKEY-256 ANDS R1, R1, #&FF ; zero => INKEY(-256) MOVEQ R1, #ArthurINKEY256 ; then X := OS version number MOVEQ R2, #0 ; and Y := 0 MyOsbyte EQ ; if was INKEY-256 then claim 10 Push R14 ; save return address for if passing on ADR R14, My81 Push R14 ; stack 'claiming' return address BL DoInkeyOp ; R14 = 'passing on' return address NotMy81 ; DoInkeyOp passed it on Pull "R3,R14" ; Throw away 'claiming' return address ; and restore real passing on return address Unused ; else pass it on still My81 Pull R14 ; throw away real passing on address ByteReturnV ; ***************************************************************************** ; Read Machine High Order Address Osbyte82 MOV R1, #&FF ; Pretend we're an I/O processor ! MOV R2, #&FF MyOsbyte ; ***************************************************************************** ; Read OSHWM Osbyte83 LDRB R2, OSHWM ; Read from silly variable MOV R1, #0 ; lo-byte is 0 MyOsbyte ; ***************************************************************************** ; Read Text Cursor Position (input cursor if split) Osbyte86 ByteToNosbod DoReadPOSVPOSI ; Results in R1, R2 (i.e. POS, VPOS) MyOsbyte ; ***************************************************************************** ; Read Screen Mode and Character at text cursor position Osbyte87 [ Fix6 LDR R3, [R13, #StackOffset] ; get user's psr ANDS R3, R3, #I_bit ; EQ => irqs were on CLRPSR I_bit, R3, EQ ; so clear I_bit now ] ByteToNosbod DoOSBYTE87 ; Results in R1, R2 (i.e. char, mode) MyOsbyte ; ***************************************************************************** ; Insert Character Into Buffer Osbyte8A BL INSERT MyOsbyte ; ***************************************************************************** ; Write Filing System Options : *OPT Osbyte8B MOV R0, #FSControl_OPT SWI XOS_FSControl ByteReturnV ; ***************************************************************************** ; Issue Paged ROM Service Request Osbyte8F IssueService MyOsbyte ; ***************************************************************************** ; Select vertical screen shift and interlace option :*TV Osbyte90 LDRB R0, TVVertical STRB R1, TVVertical MOV R1, R0 ; old vertical in R1 AND R0, R2, #1 LDRB R2, TVInterlace ; old interlace in R2 STRB R0, TVInterlace MyOsbyte ; ***************************************************************************** ; Get Character From Buffer Osbyte91 CLRV ; remove not examine RemVEntry ADR R14, MyOsbyte80 REMOVE Push "R10,R12,R14" MOV R10, #REMV B GoVec ; ***************************************************************************** ; Examine Buffer Status Osbyte98 SETV ; examine not remove B RemVEntry ; ***************************************************************************** ; Insert Character Code Into buffer checking for ESCAPE Osbyte99 BL DoInsertESC MyOsbyte ; ***************************************************************************** ; Update pseudo 6850 control register and soft copy Osbyte9C MOV r0, #7 ; OS_SerialOp to modify 6850 control register SWI XOS_SerialOp MyOsbyte ; ***************************************************************************** ; 'Fast TUBE BPUT' Osbyte9D MOV R0, R1 ; R0 := character MOV R1, R2 ; R1 := handle SWI XOS_BPut ByteReturnV ; ***************************************************************************** ; Read VDU Variable (0..15 implemented) OsbyteA0 ByteToNosbod DoReadVDUVariable MyOsbyte ; ***************************************************************************** ; Read CMOS RAM OsbyteA1 ; R1 = address , R2 = result CLRPSR I_bit, R0 ; this may take some time MOV R0, R1 BL Read ; Read CMOS ram at address <R0> MOV R2, R0 ; Result in R0, return in R2 MyOsbyte ; Write CMOS RAM OsbyteA2 CLRPSR I_bit, R0 ; this may take some time [ E2ROMSupport MOVS R0, R1 | ANDS R0, R1, #&FF ; only look at bottom byte ] [ ProtectStationID MyOsbyte EQ ] [ STB :LAND: :DEF: ObsoleteNC1CMOS ; Protect machine address CMOS (if not corrupt) ASSERT EtherCheckCMOS = EtherAddrCMOS+6 CMP r0, #EtherAddrCMOS BLT %FT10 CMP r0, #EtherCheckCMOS BGT %FT10 Push "r0,r1" BL GetMachineAddressCMOS Pull "r0,r1" MyOsbyte EQ ; don't allow write if address is valid 10 ] MOV R1, R2 BL Write MOV R1, R0 ; R1 is supposed to be preserved MyOsbyte ; ***************************************************************************** ; OsByte 163,... applications call OsbyteA3 ROUT TEQ R1, #242 Unused NE ; not 242 - pass it on BL %FT10 MyOsbyte ; if come to here, has been claimed 10 Push R14 ByteToNosbod DoOsbyte163_242 Pull R14 ; if come to here, wasn't claimed Unused ; ***************************************************************************** ; Read Output cursor Position OsbyteA5 ByteToNosbod DoReadPOSVPOSO ; Result in R1,R2 (Horiz,vert) MyOsbyte ; ***************************************************************************** ; ; All calls &A6 to &FF are implemented together. ; <NEW VALUE> = (<OLD VALUE> AND R2 ) EOR R1 ; The old value is returned in R1 and the next location is returned in R2 ; ; ***************************************************************************** DoOsbyteVar SUB R0, R0, #MainVars ; Point to this block starting at &A6 LDRB R3, [WsPtr, R0] ; Load the byte AND R11, R3, R2 ; Mangle it as required by the law EOR R11, R11, R1 ; ................................ MOV R1, R3 ; Return old value in R1 TEQ R0, #OsbyteKeyStatus - MainVars ; sorry - it's not pure any more. BEQ DoOsbyteKeyStatus ; mea culpa. KJB. STRB R11, [R0, WsPtr]! ; R0 +:= WsPtr LDRB R2, [R0, #1] ; Return contents of next loc in R2 MyOsbyte ; Keyboard status (OS_Byte 202). ; on entry: R0 = OsbyteKeyStatus - MainVars ; R1 = old value ; R11 = new value DoOsbyteKeyStatus ROUT Push "R0-R3,R10" MOV R10,#UpCallV ; (Can't use OS_UpCall - it enables IRQs and we're documented as not doing so) MOV R3,R11 ; R3 = new value MOV R2,R1 ; R2 = old value MOV R1,#0 ; pre-change MOV R0,#UpCall_KeyboardStatus BL CallVector ; go on then, interfere (Corrupts R10 & WsPtr) LDR R0, [R13] ; get back original R0 STRB R3, [R0, #OsbyteVars]! ; R0 +:= WsPtr LDRB R14, [R0, #1] ; Return contents of next loc in R2 STR R14, [R13, #8] ; by popping it on the stack TEQ R2, R3 ; don't bother with UpCall if it didn't change... MOVNE R10,#UpCallV MOVNE R1,#1 ; post-change MOVNE R0,#UpCall_KeyboardStatus BLNE CallVector ; can't do anything about it now... Pull "R0-R3,R10" MyOsbyte LTORG ; All the unused OS_Byte calls ; ADC stuff Osbyte10 ROUT Osbyte11 ROUT ; Incr/Decr Polling Int Osbyte16 Osbyte17 ; Unused Osbyte18 ; Write 1MHz bus selection Osbyte6B ; Write Usage of Shadow memory for normal access Osbyte6C ; Make temporary filing system permanent Osbyte6D ; &6E and &6F are reserved by 3rd parties Osbyte6E Osbyte6F ; &73 and &74 reserved for Electron Osbyte73 Osbyte74 ; Close SPOOL(ON) & EXEC files Osbyte77 ; Read top of USER RAM Osbyte84 ; Read top of user RAM for given mode Osbyte85 ; *CODE Osbyte88 ; *MOTOR Osbyte89 ; *TAPE Osbyte8C ; *ROM Osbyte8D ; Enter Language ROM Osbyte8E ; Access Mem.Map.IO &92..&97 Osbyte92 Osbyte93 Osbyte94 Osbyte95 Osbyte96 Osbyte97 ; Write to VidULA & COPY Osbyte9A Osbyte9B ; Old Style Speech Osbyte9E Osbyte9F ; Check Processor Type OsbyteA4 Unused ; ***************************************************************************** ; ; GetCountry - Read country ; ; in: R1 = country number or alphabet number ; ; out: IF R1=0 THEN ; R1:=Configured Country ; IF R1=0 THEN ; R1:=LastKbId ; IF R1>=&20 THEN R1:=0 ; ENDIF ; ENDIF ; ; R0 undefined ; GetCountry ROUT TEQ R1, #0 ; if not setting default, exit MOVNE PC, R14 Push R14 MOV R0, #CountryCMOS ; read configured country BL Read MOVS R1, R0 ; if not Country Default, exit Pull PC, NE MOV R0, #KeyWorkSpace LDRB R1, [R0, #:INDEX: LastKbId] ; read last valid keyboard id CMP R1, #&20 ; if <&20 then use this MOVCS R1, #0 ; else set to 0 Pull PC END