;>s.code


a1 RN 0
a2 RN 1
a3 RN 2
a4 RN 3
v1 RN 4
v2 RN 5
v3 RN 6
v4 RN 7
v5 RN 8
v6 RN 9
sl RN 10
fp RN 11
ip RN 12
sp RN 13
lk RN 14
lr RN 14
pc RN 15

f0 FN 0
f1 FN 1
f2 FN 2
f3 FN 3
f4 FN 4
f5 FN 5
f6 FN 6
f7 FN 7




        AREA |C$$code|, CODE, READONLY

|x$codeseg|


SVC_Mode * 3
Overflow_Flag * (1<<28)
Carry_Flag * (1<<29)
Font_Paint * &40086
PDriver_CurrentJob * &80146
PDriver_SelectJob * &80145
PDriver_SelectIllustration * &80153
OS_CallASWIR12 * &71
OS_CallASWI * &6F
Draw_Stroke * &40704
Draw_Fill * &40702
OS_ClaimProcessorVector * &69
GDraw_Fill * &44542
GDraw_Stroke * &44544


buffer * &6000

XOS_MASK      * &00020000 ; mask to make a swi a RISC OS V-error SWI




dofix
 DCD 1

fixmode
 DCD 7


claimswi
 DCD 0


 EXPORT setfixmode


setfixmode

 STR    r0,fixmode
 MOV    pc,lk


 EXPORT fixprintservice


fixprintservice

 STR    r0,printactive
 MOV    pc,lk


 EXPORT fixspriteservice

fixspriteservice

 STR    r0,spriteactive
 MOV    pc,lk


 EXPORT claimvectors


claimvectors
 STMFD  sp!, {R0-R7, lk}  ; Initialisation code

 mov    r0,#2           ; claim SWI vector
 orr    r0,r0,#256

 adr    r1,filter_SWI
 swi    XOS_MASK :OR: OS_ClaimProcessorVector

 movvc  r0,#1
 movvs  r0,#0
 str    r0,claimswi

 bvs    oldcode
 str    r1,instr

 b      claimexit


oldcode

 MOV    R0, #8
 LDR    R0, [R0]            ; Load data at 08 (branch to SWI handler code)
 BIC    R0, R0, #&FF000000  ; Mask out instruction identifier
 MOV    R0, R0, LSL #2      ; (*4) + 16
 ADD    R0, R0, #16
 STR    R0, instr           ; Store address of handler at label
 ADR    R0, filter_SWI      ; Generate a single Branch instr to jump to new
 SUB    R0, R0, #16         ; SWI handler code
 MOV    R0, R0, LSR #2      ; - 16 (/4)
 ORR    R0, R0, #&EA000000  ; Add on instruction identifier
 MOV    R1, #8
 STR    R0, [R1]            ; Save data at 08 (branch to new SWI handler code)


claimexit
 LDMFD  sp!, {R0-R7, pc}    ; Exit code and pull link off the stack


 EXPORT relvectors


relvectors

 STMFD  sp!, {lk}         ; Finalisation code

 ldr    r0,claimswi
 teq    r0,#1
 bne    reloldcode

 mov    r0,#2                 ; rel SWI vector
 ldr    r1,instr
 adr    r2,filter_SWI
 swi    XOS_MASK :OR: OS_ClaimProcessorVector
 b      relexit


reloldcode
 LDR    R0, instr             ; Load address of handler from label
 SUB    R0, R0, #16           ; SWI handler code
 MOV    R0, R0, LSR #2        ; -16 (/4)
 ORR    R0, R0, #&EA000000    ; Add on instruction identifier
 MOV    R1, #8
 STR    R0, [R1]              ; Save data at 08 (branch to SWI handler code)


relexit
 LDMFD  sp!, {pc}           ; Exit code and pull link off the stack


instr     DCD &1F033C0     ; Address of RISC-OS SWI handler
const     DCD &FFF20000    ; mask useful bits of swi number


 B      filter_SWI
 B      filter_SWI


OS_CallASWISwi
 DCD OS_CallASWI

OS_CallASWIR12Swi
 DCD OS_CallASWIR12

PDriverSelectIllustrationSwi
 DCD  PDriver_SelectIllustration

PDriverSwi
 DCD  PDriver_SelectJob

Font_PaintSwi
 DCD  Font_Paint

Draw_StrokeSwi
 DCD  Draw_Stroke

Draw_FillSwi
 DCD  Draw_Fill



filter_SWI                   ; Code replaces RISCOS code that handles the SWI's
 STMFD  R13!, {R9,R11}       ; Save registers to stack
 TEQ    PC,PC                ; EQ if in a 32-bit mode, NE if 26-bit
 BICNE  R9,   R14, #&FC000003; Clear flags from R14_svc to give address of SWI
 MOVEQ  R9,   R14
 LDR    R11,  [R9, #-4]      ; Load R11 with the actual SWI word
 LDR    R9,   const          ; Load in a constant to mask R11 with
 BIC    R11,  R11, R9        ; Mask out unwanted bits 31-17


 LDR    R9,OS_CallASWIR12Swi
 TEQ    R11,R9
 BEQ    CallAswir12


 LDR    R9,OS_CallASWISwi
 TEQ    R11,R9
 BEQ    CallAswi


reenter
 LDR    R9,PDriverSwi
 TEQ    R11,R9
 BEQ    PDriver


 LDR    R9,Font_PaintSwi
 TEQ    R11,R9
 BEQ    Paint                 ; then call the filter code

 LDR    R9,Draw_StrokeSwi
 TEQ    R11,R9
 BEQ    DrawStroke

 LDR    R9,Draw_FillSwi
 TEQ    R11,R9
 BEQ    DrawFill


 LDR    R9,PDriverSelectIllustrationSwi
 TEQ    R11,R9
 BEQ    PDriverSelectIllustration



routine
 LDMFD  R13!, {R9,R11}       ; Restore registers & call previous SWI handler
 LDR    PC, instr


PDriverSelectIllustration
 STR    r0,handle
 B      routine

PDriver
 STR    r0,handle
 B      routine




CallAswir12
 LDR    R9, const            ; Load in a constant to mask R11 with
 BIC    R11, R12, R9         ; Mask out unwanted bits 31-17
 B      reenter


CallAswi
 LDR    R9, const
 BIC    R11, R10, R9
 B      reenter



; r1->string
; r2=plot type
; r3=x coordinate
; r4=y coordinate

; sequences
; 9, lox,midx,hix
; 11, lox,midx,hix
; 17, front
; 18, back,front,offset
; 21, string, <ctrl>
; 25, posn, thickness
; 26, font
; 19, r,g,b,R,G,B,offset
; 27, align, m1,m2,m3,m4
; 28, align, m1,m2,m3,m4,m5,m6




handle
 DCD 0
printactive
 DCD 0
fontrecurse
 DCD 0
spriteactive
 DCD 0



paintxrecurse
 ldmfd  R13!,{r0-r4}
 b      routine


Paint

 stmfd  R13!, {r0-r4}

 str    r2,temp2

 ldr    r0,fontrecurse
 teq    r0,#0
 bne    paintxrecurse

 ldr    r0,dofix
 teq    r0,#1
 bne    paintxx


 ldr    r0,handle
 teq    r0,#0
 beq    paintxx2

 ldr    r0,printactive
 teq    r0,#0
 beq    paintxx1

 ldr    r0,fixmode
 tst    r0,#2
 beq    paintxx


 mov    r2,#buffer
 tst    r1,#&FE000000
 beq    paintxx


paintloop

 mov    r3,r1

 ldrb   r0,[r1],#1
 teq    r0,#9
 addeq  r1,r1,#3
 beq    paintloop1

 teq    r0,#11
 addeq  r1,r1,#3
 beq    paintloop1

 teq    r0,#17
 addeq  r1,r1,#1
 beq    paintloop1

 teq    r0,#18
 addeq  r1,r1,#3
 beq    paintloop1

 teq    r0,#25
 addeq  r1,r1,#2
 beq    paintloop1

 teq    r0,#26
 addeq  r1,r1,#1
 beq    paintloop1

 teq    r0,#21         ; comment
 bne    paint1
commentloop
 ldrb   r0,[r1],#1
 tst    r0,#&E0
 beq    commentloop
 b      paintloop1

paint1
 teq    r0,#19
 addeq  r1,r1,#7
 beq    paintloop1

 teq    r0,#27
 bne    paint2
 add    r1,r1,#3
 bic    r1,r1,#3
 add    r1,r1,#16
 b      paintloop1

paint2
 teq    r0,#28
 bne    paint3
 add    r1,r1,#3
 bic    r1,r1,#3
 add    r1,r1,#24
 b      paintloop1

paint3

 tst    r0,#&E0
 moveq  r0,#0
 streqb r0,[r2],#1
 beq    paintloopx

paintloop1
 ldrb   r0,[r3],#1
 strb   r0,[r2],#1
 teq    r3,r1
 bne    paintloop1

 b      paintloop


paintloopx
 ldmfd  R13!, {r0-r4}
 mov    r1,#buffer
 b      paintxcheck




paintxx2
 ldr    r0,printactive
 teq    r0,#0
 bne    paintxx

paintxx1
 ldr    r0,fixmode
 tst    r0,#1
 beq    paintxx
 ldmfd  R13!,{r0-r4}
 orr    r2,r2,#(1<<11)
 b      paintxcheck


paintxx
 ldmfd  R13!,{r0-r4}
paintxcheck


 mov    r9,#1
 str    r9,fontrecurse

 str    r14,temp14

 teq    pc,pc
 bicne  r9,r14,#&FC000003
 eorne  r14,r14,r9
 adrne  r9,fxxx
 orrne  r14,r14,r9
 adreq  r14,fxxx

 ldmfd  r13!, {r9,r11}

 ldr    PC, instr


 swi    XOS_MASK :OR: Font_Paint
fxxx


 ldr    r2,temp2

 str    r0,temp2

 mov    r0,#0
 str    r0,fontrecurse

 ldr    r0,temp2

 ldr    pc,temp14


temp14
 DCD   0
temp2
 DCD   0


dtemp14
 DCD   0

drawrecurse
 DCD   0

dtemp
 DCD   0

dtemp1
 DCD   0



DrawStroke


 ldr    r9,drawrecurse
 teq    r9,#0
 bne    routine

 ldr    r9,dofix
 teq    r9,#1
 bne    routine

 ldr    r9,fixmode
 tst    r9,#4
 beq    routine

 ldr    r9,spriteactive
 teq    r9,#0
 bne    routine

 ldr    r9,handle
 teq    r9,#0
 beq    gdrawxx

 ldr    r9,printactive
 teq    r9,#0
 beq    gdrawxx



; exit via Draw

drawxx
 str    r14,dtemp14

 teq    pc,pc
 bicne  r9,r14,#&FC000003
 eorne  r14,r14,r9
 adrne  r9,dxxx
 orrne  r14,r14,r9
 adreq  r14,dxxx

 mov    r9,#1
 str    r9,drawrecurse

 ldmfd  r13!, {r9,r11}


 ldr    PC, instr


 swi    XOS_MASK :OR: Draw_Stroke
dxxx


 str    r0,dtemp

 mov    r0,#0
 str    r0,drawrecurse

 ldr    r0,dtemp

 ldr    pc,dtemp14





; exit via GDraw

gdrawxx

 teq    r1,#0               ; default style
 beq    gdrx2
 and    r9,r1,#3            ; mask out winding rule
 teq    r9,#1               ; minus back to draw
 beq    drawxx
 teq    r9,#3               ; plus back to draw
 beq    drawxx
 and    r9,r1,#&3C          ; boundary pixel bits
 teq    r9,#&30             ; allow only 30 and 38
 beq    gdrx2
 teq    r9,#&38
 bne    drawxx

gdrx2

 str    r14,dtemp14

 teq    pc,pc
 bicne  r9,r14,#&FC000003
 eorne  r14,r14,r9
 adrne  r9,gdxxx
 orrne  r14,r14,r9
 adreq  r14,gdxxx

 mov    r9,#1
 str    r9,drawrecurse

 ldmfd  r13!, {r9,r11}

 str    r1,dtemp1
 teq    r1,#0              ; default style
 bne    gdrx1              ; thin line
 teq    r4,#0
 moveq  r1,#&18
 movne  r1,#&38
gdrx1
 teq    r4,#0
 orrne  r1,r1,#&80
 orrne  r1,r1,#&80000000


 ldr    PC, instr


 swi    XOS_MASK :OR: GDraw_Stroke
gdxxx


 str    r0,dtemp

 mov    r0,#0
 str    r0,drawrecurse

 ldr    r0,dtemp

 ldr    r1,dtemp1

 ldr    pc,dtemp14




DrawFill


 ldr    r9,drawrecurse
 teq    r9,#0
 bne    routine

 ldr    r9,dofix
 teq    r9,#1
 bne    routine

 ldr    r9,fixmode
 tst    r9,#4
 beq    routine

 ldr    r9,spriteactive
 teq    r9,#0
 bne    routine

 ldr    r9,handle
 teq    r9,#0
 beq    gdrawfxx

 ldr    r9,printactive
 teq    r9,#0
 beq    gdrawfxx




; exit via Draw

drawfxx


 str    r14,dtemp14

 teq    pc,pc
 bicne  r9,r14,#&FC000003
 eorne  r14,r14,r9
 adrne  r9,dfxxx
 orrne  r14,r14,r9
 adreq  r14,dfxxx

 mov    r9,#1
 str    r9,drawrecurse

 ldmfd  r13!, {r9,r11}


 ldr    PC, instr


 swi    XOS_MASK :OR: Draw_Fill
dfxxx


 str    r0,dtemp

 mov    r0,#0
 str    r0,drawrecurse

 ldr    r0,dtemp

 ldr    pc,dtemp14





; exit via GDraw

gdrawfxx


 teq    r1,#0          ; default style
 beq    gdrfx2
 and    r9,r1,#3
 teq    r9,#1
 beq    drawfxx
 teq    r9,#3
 beq    drawfxx
 and    r9,r1,#&3C
 teq    r9,#&30
 beq    gdrfx2
 teq    r9,#&38
 bne    drawfxx

gdrfx2


 str    r14,dtemp14

 teq    pc,pc
 bicne  r9,r14,#&FC000003
 eorne  r14,r14,r9
 adrne  r9,gdfxxx
 orrne  r14,r14,r9
 adreq  r14,gdfxxx

 mov    r9,#1
 str    r9,drawrecurse

 ldmfd  r13!, {r9,r11}

 str    r1,dtemp1
 teq    r1,#0
 moveq  r1,#&30
 orr    r1,r1,#&80


 ldr    PC, instr


 swi    XOS_MASK :OR: GDraw_Fill
gdfxxx



 str    r0,dtemp

 mov    r0,#0
 str    r0,drawrecurse

 ldr    r0,dtemp

 ldr    r1,dtemp1

 ldr    pc,dtemp14



        LTORG

    AREA |C$$data|



|x$dataseg|



    END
