; 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.
;
; Sources. SWIS

SpriteExtend_SWIDecode

        [ ccompiler
        Debug   gs,"X R0-3",R0,R1,R2,R3
        Debug   gs,"X R4-7",R4,R5,R6,R7
        Debug   gs,"X R8-9,12",R8,R9,R12
        Push    "R0"
        MOV     r0, lr
        Debug   gs,"we will return to ",R0
        Pull    "R0"
        Push    "LR"
        CLRPSR  I_bit,R14                        ; re-enable interrupts

        LDR     r12,[R12]                        ; wsptr --> workspace

        Debug   gs,"R12 = ",R12
        Debug   gs,"R11 = ",R11
        CMP     r11, #2                          ; JPEG_PlotScaled ?
        CMPNE   r11, #3                          ; JPEG_plotFileScaled ?
        CMPNE   r11, #4                          ; JPEG_PlotTransformed ?
        CMPNE   r11, #5                          ; JPEG_PlotFileTransformed ?
        BNE     NonPrinterSWI
        Push    "R8"
        LDR     r8, save_PdriverIntercept
        TST     r8, #1
        BNE     JPEGSWI_Printer
        Pull    "R8"
NonPrinterSWI
        CMP     R11,#maxnewswi
        ADDCC   R14,R11,#(swijptable-swijporg-4)/4    ; bodge factor
        ADDCC   PC,PC,R14,ASL #2                 ; go!
swijporg
        ADR     R0,ErrorBlock_BadSWI
        Push    "R1"
        ADRL    R1, Title
        BL      copy_error_one
        Pull    "R1, PC"

JPEGSWI_Printer
        AND     r8, r11, #63
        Debug   gs, "I should be calling the printer SWI...",R8
        SWI     XPDriver_JPEGSWI
;        SWI     &a015d                  ;PDriver_JPEGSWI
        Pull    "R8,PC"

swijptable
        B       SWIJPEG_Info
        B       SWIJPEG_FileInfo
        B       SWIJPEG_PlotScaled
        B       SWIJPEG_PlotFileScaled
        B       SWIJPEG_PlotTransformed
        B   	SWIJPEG_PlotFileTransformed
	B	SWIJPEG_PDriverIntercept
endswijptable
maxnewswi   *   (endswijptable-swijptable)/4


ErrorBlock_BadSWI
        DCD     ErrorNumber_ModuleBadSWI
        DCB     "BadSWI"
        DCB     0
        ALIGN

ErrorBlock_NoFile
        DCD     ErrorNumber_FileNotFound
        DCB     "NoFile"
        DCB     0
        ALIGN
        ]

SpriteExtend_SWINames
        DCB     SpriteExtendJPEGSWI_Name,0                ; prefix
        DCB     "Info",0
        DCB     "FileInfo",0
        DCB     "PlotScaled",0
        DCB     "PlotFileScaled",0
        DCB     "PlotTransformed",0
        DCB     "PlotFileTransformed",0
        DCB     "PDriverIntercept",0
        DCB     0
        ALIGN

;SpriteExtend_AreaName
;	DCB	"SpriteExtend JPEG",0
;	ALIGN

;SWIJPEG_Info
;In:
;  r0 = flags for desired operation
;         b0 set : return dimensions.
;  r1 = Pointer to JPEG image in memory.
;  r2 = length of data in memory (bytes)
;
;Out:
;  r0 = returned information flags.
;         b0 set : greyscale image.
;         b1 set : set if transformed plots are not supported.
;         b2 set : pixel density is only a ratio.
;  r1 preserved
;  r2 = width in pixels.
;  r3 = height in pixels.
;  r4 = X pixel density.
;  r5 = Y pixel density
;  r6 = 0  (reserved for future use)
;
SWIJPEG_Info

        Pull    "LR"
        Debug   gs,"JPEG: LR =",LR
        Push    "R1-R9,LR"              ; we must stick to the same form of saved registers as 'exitbiggie' assumes,
                                        ; in case of an unexpected exit from the C code.
        CLRPSR  I_bit, R14              ; re-enable interrupts
        BICS    r3, r0, #1              ;has someone set illegal flags?
        ADRNEL  R0, ErrorBlock_BadFlags
        addr    r1, Title, NE
        BLNE    copy_error_one          ; Always sets the V bit
        BVS     exitbiggie

; Set escape stack level in case of unexpected exit from C code.
        [ ccompiler
        ADRL    R3,ccompiler_sp
        STR     SP,[R3]                 ; in case of unexpected exit
        MOV     R4,#0
        ADRL    R5,ccompiler_errptr
        STR     R4,[R5]                 ; in case of error exit
        MOV     r3,r0                   ; put flags into r3
        MOV     r0,r1                   ; put JPEG pointer into r3
        MOV     r7,r1                   ; put JPEG pointer into r6
        MOV     r2, #0

        BL      asm_find_image_dims     ; corrupts r0 and sl, sets r1,r2,r3,r4,r5

        BVS     JPEGInfo_Exit
        Debug   gs,"return from C: R1,R2,R3 =",R1,R2,R3
; If not JPEG Set V and point r0 to error block then pull out...
        CMP     r1, #0
        BEQ     JPEGInfo_Exit1
; If not JPEG Set V and point r0 to error block then pull out...
        AND     r0, r1, #3              ; temp use of r0
        TEQ     r0,#3                   ; Is JPEG Colour?
        BICEQ   r1,r1,#3                ; If so, Reset bits 0 and 1.
;        ORR     r1,r1,#&ff00            ; get them to mask out top bits, in case we use them for other things later.
        TST     r1, #&100               ; is the pixel density a ratio?
        ORRNE   r1, r1, #4

;******THIS MUST BE REMOVED WHEN TRANSFORMATIONS ARE ALLOWED*********
        ORR     r1, r1, #2              ;SET bit 1 because we can't transform JPEGS
;******THIS MUST BE REMOVED WHEN TRANSFORMATIONS ARE ALLOWED*********

        AND     r0,r1,#7                ; put result flags into r0
        MOV     r1,r7                   ; put JPEG pointer into r1
;        MOV     r6,#0
        Debug   gs,"returning R0,R1,R2,R3 =",R0,R1,R2,R3
        Debug   gs,"returning R4,R5,R6 =",R4,R5,R6
        ADDS    sp,sp,#6*4              ; get rid of saved r1-r6 - clear V
        Debug   gs,"Got to 12"
        Pull    "R7-R9,PC"              ; copied from exitbiggie, but returning r1-r6 - r0 restored by exit sequence.

JPEGInfo_Exit1
        ADRL  R0,ErrorBlock_BadJPEG
        BL      copy_error_one
JPEGInfo_Exit
        Pull    "R1-R9,PC"

        MakeSpriteErrorBlock BadJPEG,,BadJPEG

        MakeSpriteErrorBlock JPEGNoRoom,,JPEGNoRoom

        MakeSpriteErrorBlock JPEGFatal,,JPEGFatal

asm_find_image_dims
; On entry:
;   r0 points to JPEG/filename
;   r2 = 0 for JPEG in memory/1 for file
;   exit level for C escape set
; On exit:
;   r1 = 0 or 1 or 3 for not-jpeg or mono or colour
;   r2 = width
;   r3 = height
;   r4 = Xdensity
;   r5 = Ydensity
;   r6 = Memory required
        Push    "r0,sl,lr"
        SUB     sp,sp,#36               ; space for 5+6+7th args, and five returned results
        [ dynamicarea
        MOV     r4, r0                  ; temporrarily store regs r0 and r2
        MOV     r5, r2
        LDR     r0, area_number
        SWI     XOS_ReadDynamicArea     ; find out how big area is
        BVS     %FT01
        CMP     r1, #0			; if size is zero
        MOVEQ   r1, #0                  ; act as if we had no JPEG workspace
        LDRNE   r1, jpeg_info_ptr
01
        MOVS    r0, r4                  ;put regs back where they should be.
        MOV     r2, r5
        |
        LDR     r1, jpeg_info_ptr
        ]
        STR     r1, [sp, #32]
        ADD     r2, r2, sp
        ADD     r2, r2, #32             ; place to store memory requirements
        STR     r2,[sp,#4]               ; set sixth arg to r2
        ADD     r2,sp,#24               ; set up r2 with pointer to 5th returned result
        STR     r2,[sp]                 ; set fifth arg to point to return area
        ADD     r2,sp,#28               ; set up r2 with pointer to error buffer
        STR     r2,[sp,#8]              ; set seventh arg to error space
        Debug   gs,"err =",R2
        ADD     r1,sp,#12               ; set second arg
        ADD     r2,sp,#16               ; set third arg
        ADD     r3,sp,#20               ; set fourth arg
        MOV     SL,R12                  ; will be left alone by compiled C - for debug routines above.
        Debug   gs,"calling CC: R0,R1,R2,R3 =",R0,R1,R2,R3
        BL      find_image_dims         ; dive into the C - returns 0 in r0 if all is well.
        Debug   gs,"just returned: R0,R1,R2,R3,R4 =",R0,R1,R2,R3,R4
        MOV     R12,SL                  ; R12 is ip to a C prog, will have been trampled on - restore it.
        CMP     r0, #1
        LDRGT   r0, [sp,#28]
        BGT     find_image_dims_error
        Debug   gs,"returned"
        LDR     r2,[sp,#12]             ; get image width
        LDR     r3,[sp,#16]             ; get image height
        LDR     r4,[sp,#24]             ; get image density
        LDR     r6,[sp,#32]             ; get memory requirements
        Debug   gs, "returned density = ",R4
        MOV     r5, r4, LSL #16         ; put density into 2 separate regs.
        MOV     r5, r5, LSR #16
        MOV     r4, r4, LSR #16
        Debug   gs, "xdens, ydens =",R4,R5
        MOVS    r1,r0                   ; is it JPEG?
        LDREQ   r1,[sp,#20]             ; get image_type - 1 or 3
        MOVNE   r1,#0
        ADD     sp,sp,#36               ; get rid of stack workspace
        Pull    "r0,sl,pc"
find_image_dims_error
        SETV
        ADD     sp,sp,#36               ; get rid of stack workspace
        Debug   gs,"r0(err) =",R0
        ADD     sp, sp, #4              ; skip over stored verison of r0
        Pull    "sl,pc"                 ; pull up other three
        ]

;SWIJPEG_FileInfo
;In:
;  r0 = flags for desired operation
;         b0 set : return dimensions.
;  r1 = pointer to control character terminated filename for
;       JPEG image.
;
;Out:
;  r0 = returned information flags.
;         b0 set : greyscale image.
;         b1 set : set if transformed plots are not supported.
;         b2 set : pixel density is only a ratio.
;  r1 preserved
;  r2 = width in pixels.
;  r3 = height in pixels.
;  r4 = X pixel density.
;  r5 = Y pixel density
;  r6 = 0  (reserved for future use)
;
SWIJPEG_FileInfo

        [ ccompiler
        Debug   gs, "Filename pointer = ",r1
        Pull    "LR"
        Debug   gs,"JPEGFile: LR =",LR
        Push    "R1-R9,LR"              ; we must stick to the same form of saved registers as 'exitbiggie' assumes,
                                        ; in case of an unexpected exit from the C code.
        CLRPSR  I_bit, R14              ; re-enable interrupts

        BICS    r3, r0, #1              ;has someone set illegal flags?
        ADRNEL  R0, ErrorBlock_BadFlags
        addr    r1, Title, NE
        BLNE    copy_error_one          ; Always sets the V bit
        BVS     exitbiggie
; Set escape stack level in case of unexpected exit from C code.
        ADRL    R3,ccompiler_sp
        STR     SP,[R3]                 ; in case of unexpected exit
        MOV     R4,#0
        ADRL    R5,ccompiler_errptr
        STR     R4,[R5]                 ; in case of error exit
        MOV     r3,r0                   ; put flags into r3
        MOV     r0,r1                   ; put JPEG filename pointer into r3
        MOV     r7,r1                   ; put JPEG filename pointer into r6
        MOV     r2, #1                  ; r1 is pointer to filename...

        BL      asm_find_image_dims     ; corrupts r0 and sl, sets r1-r6

        BVS     JPEGInfo_Exit
        Debug   gs,"return from C: R1,R2,R3 =",R1,R2,R3
; If not JPEG Set V and point r0 to error block then pull out...
        CMP     r1, #0
        BEQ     JPEGInfo_Exit1
        AND     r0, r1, #3              ; temp use of r0
        TEQ     r0,#3                   ; Is JPEG Colour?
        BICEQ   r1,r1,#3                ; If so, Reset bits 0 and 1.
;        ORR     r1,r1,#&ff00            ; get them to mask out top bits, in case we use them for other things later.
        TST     r1, #&100               ; is the pixel density a ratio?
        ORRNE   r1, r1, #4

;******THIS MUST BE REMOVED WHEN TRANSFORMATIONS ARE ALLOWED*********
        ORR     r1, r1, #2              ;SET bit 1 because we can't transform JPEGS
;******THIS MUST BE REMOVED WHEN TRANSFORMATIONS ARE ALLOWED*********

        AND     r0, r1, #7              ; put result flags into r0
        MOV     r1,r7                   ; restore JPEG pointer in r1
;        MOV     r6,#0
        Debug   gs,"returning R0,R1,R2,R3 =",R0,R1,R2,R3
        Debug   gs,"returning R4,R5,R6 =",R4,R5,R6
        ADDS    sp,sp,#6*4              ; get rid of saved r1-r6 - clear V
        Pull    "R7-R9,PC"              ; copied from exitbiggie, but returning r1-r6 - r0 restored by exit sequence.
        ]



;SWIJPEG_PlotScaled
;In:
;  r0 = pointer to JPEG image in memory
;  r1 = x co-ordinate for plot
;  r2 = y co-ordinate for plot
;  r3 = scale factors or 0
;  r4 = length of data in memory
;  r5 = Flags
;       b0 set: dither output when plotting truecolour in 8bpp or less.
;       b1 set: Full error-diffusion when plotting to 8bpp.
;
;Out:
;  all registers preserved.
;
SWIJPEG_PlotScaled
;On Entry: what original code expected...
;  R0 = 66
;  R1 = pointer to JPEG file image
;  R2 = length of JPEG file image
;  R3 = x coordinate at which to plot
;  R4 = y coordinate at which to plot
;  R5 = plot action
;  R6 = scale factors: 0 -> no scaling
;  R7 = pixel translation table
        [ ccompiler
        Pull    "LR"
        Push    "R1-R9,LR"              ; we must stick to the same form of saved registers as 'exitbiggie' assumes,
        MOV     r1, sp
        Debug   gs,"sp after push 1-9+lr =", r1
        MOV     R1, R0
        Debug   gs,"r0 at start =",R0
        MOV     R2, R4
        Debug   gs,"JPEG_PlotScaled sprite: R0,R1,R2 =",R0,R1,R2
        Debug   gs,"JPEG_PlotScaled sprite: R3,R4,R5 =",R3,R4,R5
        Debug   gs,"JPEG_PlotScaled sprite: R6,R7 =",R6,R7
        ADRL    r3, newtranstable
        Debug   gs,"newtranstable at ",r3
        CLRPSR  I_bit, R14              ; re-enable interrupts

        BICS    r3, r5, #3              ;has someone set illegal flags?
        ADRNEL  R0, ErrorBlock_BadFlags
        addr    r1, Title, NE
        BLNE    copy_error_one          ; Always sets the V bit
        BVS     exitbiggie

        AND     r3, r5, #3
        Debug   gs,"Storing in dither...R3 = ",R3
        STR     r3, dither_truecolour
; Set escape stack level in case of unexpected exit from C code.
        ADRL    R3,ccompiler_sp
        STR     SP,[R3]                 ; in case of unexpected exit
        MOV     R4,#0
        ADRL    R5,ccompiler_errptr
        STR     R4,[R5]                 ; in case of error exit
;        ADRL    R5,error_ptr
;        STR     R4,[R5]                 ; in case of error exit

; Space is allocated on the stack, as follows:
;   a fake sprite - spPalette+12 bytes
;   a translation table (in case ColourTrans writes one) - 256 bytes
;   saved registers R1-R9,LR so that exitbiggie can come back to us
        ^       0,sp
pjs_start       #       0
pjs_savearea    #       10*4
pjs_r0save      #       4
pjs_table       #       12                        ; biggest table we can allocate for plotting from 32bpp.
pjs_sprite      #       spPalette+12
pjs_end         #       0
        SUB     sp,sp,#pjs_end-pjs_start          ; allocate that space

; The sprite header sits on the stack. A sprite header consists of:
;   spNext    # 4  ;  Offset to next sprite
;   spName    # 12 ;  Sprite name
;   spWidth   # 4  ;  Width in words-1      (0..639)
;   spHeight  # 4  ;  Height in scanlines-1 (0..255/511)
;   spLBit    # 4  ;  First bit used (left end of row)
;   spRBit    # 4  ;  Last bit used (right end of row)
;   spImage   # 4  ;  Offset to sprite image
;   spTrans   # 4  ;  Offset to transparancy mask
;   spMode    # 4  ;  Mode sprite was defined in
        MOV     r0,#spPalette+100
        STR     r0,pjs_sprite+spNext               ; look realistic for SWI calls that read this header
        MOV     r0,#'x'
        STR     r0,pjs_sprite+spName               ; terminated by a zero character (>>> is this right?)
        MOV     r0,#0
        STR     r0,pjs_sprite+spLBit
        MOV     r0,#spPalette
        STR     r0,pjs_sprite+spImage
        STR     r0,pjs_sprite+spTrans
; Set mode number to... &481680b5
	MOV     r0,#1
	MOV	r3, #90				; dpi;
	ORR	r0, r0, r3, LSL #1		;Horizontal dpi
	ORR	r0, r0, r3, LSL #14		;Vertical dpi
	MOV	r3, #9				;Sprite Type
	ORR	r0, r0, r3, LSL #27
;        MOV     r0,#20                             ; pretend to be mode 20
        STR     r0,pjs_sprite+spMode
        MOV     r0,#-1
        Debug   gs,"sprite: R0,R1,R2 =",R0,R1,R2
        STR     r0,pjs_sprite+spPalette            ; store identifier for indirect JPEG data.
        STR     r1,pjs_sprite+spPalette+4          ; store pointer to JPEG data.
        Debug   gs,"r0 when stored =",R1
        STR     r2,pjs_sprite+spPalette+8          ; store length of JPEG data
;        STR     r0,pjs_sprite+spPalette            ; store identifier for indirect JPEG data.
;        STR     r1,pjs_sprite+spPalette+4          ; store pointer to JPEG data.
;        STR     r2,pjs_sprite+spPalette+8          ; store length of JPEG data

; Call find_image_dims to find the dimensions of the JPEG,
; and use this to fill in the rest of the sprite header.
        MOV     r0, r1                             ; get pointer to JPEG
        MOV     r2, #0                             ; clear r2 because image is in memory
        BL      asm_find_image_dims                ; sets r1,r2,r3
        Debug   gs,"found dims... R1,R2,R3=",R1,R2,R3
        CMP     r1,#0                              ; if 0, it's not good JPEG data
        BEQ     jpegscaled_errorexit1
        SUB     r3,r3,#1
        STR     r3,pjs_sprite+spHeight             ; height in scanlines - 1
        AND     r0,r2,#7
        MOV     r0,r0,LSL #2                       ; (image_width & 7) * 4;
;fixing bug with word aligned jpegs?
	SUB	r0, r0, #1
        AND	r0, r0, #31
;end of hack
        STR     r0,pjs_sprite+spRBit               ; number of bits used in right hand word
        ADD     r0,r2,#7
        MOV     r0,r0,ASR #3
        SUB     r0,r0,#1                           ; ((image_width + 7) >> 3) - 1;
        STR     r0,pjs_sprite+spWidth              ; number of words - 1

; Call ColourTrans to get a suitable translation table for sending 32-bit data
; into this screen mode. This is either a 32K table, or no table at all.
; If this produces an error then we're probably on RISC OS 3.1,
; in which case we go forward with no translation table.
        ADRL    r0,pjs_checkColourTrans
        SWI     XOS_CLI                       ; *RMEnsure ColourTrans 1.25 Error no good
        MOVVS   r7,#0                         ; error return - not new ColourTrans
        BVS     %FT01
        MOV     r0,#6:SHL:27
        ORR     r0,r0,#1                      ; new mode number for 32bpp
        MOV     r1,#-1                        ; default input, output, palette, everything
        MOV     r2,#-1
        MOV     r3,#-1
        ADR     r4,pjs_table                  ; pointer to buffer to put table in
        MOV     r5,#0                         ; no special flags
        MOV     r6,#0
        MOV     r7,#0
        SWI     XColourTrans_SelectTable
        BVS     jpegscaled_errorexit          ; error return, no table about
        ADR     r7,pjs_table                  ; table to use now in r7, all through following code
        Debug   gs,"Generated trans table at ",R7
;        Push    "R0-R5"
;        LDR     R0, [R7, #4]
;        MOV     R2, #0
;loop1
;        LDRB    R1, [R0, R2]
;        ADD     R2, R2, #1
;        LDRB    R3, [R0, R2]
;        ADD     R2, R2, #1
;        LDRB    R4, [R0, R2]
;        ADD     R2, R2, #1
;        LDRB    R5, [R0, R2]
;        Debug   gs,"Table =",R1,R3,R4,R5
;        ADD     R2, R2, #1
;        CMP     R2, #2000
;        BLT     loop1
;        Pull    "R0-R5"
01

; Set up the output from readvduvars and readspritevars
        BL      readvduvars             ; r7 undisturbed
        BVS     jpegscaled_errorexit
; This stuff is copied from readspritevars
        MOV     R3,#5                   ; log2 of 32
        STR     R3,save_inlog2bpc
        STR     R3,save_inlog2bpp
        MOV     R3,#32                  ; bits per pixel
        STR     R3,save_inbpp
        MOV     R3,#1                   ; log2 of 2 OS-units
        Debug   gs,"inlog2px: R3=",R3
        STR     R3,inlog2px             ; pretend to be VGA-size pixels
        STR     R3,inlog2py             ; pretend to be VGA-size pixels
        STR     R3,is_it_jpeg           ; mark as a JPEG sprite
        MOV     R0,#20
        STR     R0,inmode               ; the mode vars are for mode 20 sprites.

; Now set up the registers to enter the regular PutSpriteScaled code
; r7 is already the translation table to use
        ADR     r0,pjs_end              ; get at original saved registers
        LDMIA   r0,{r1-r6}
        ADR     lr,jpegscaled_exit
;        MOV     r0,lr
        Debug   gs,"Lr for ret=",r0
        LDR     r0,pjs_sprite+spPalette+4         ; store pointer to JPEG data.
        Debug   gs,"r0 when lpaded+stored =",R0
        STR     r0, pjs_r0save
        STMIA   sp,{r1-r9,lr}           ; save state for cleanup-and-exit
;        MOV     r5,sp
        Debug   gs,"sp = ",R5
        Debug   gs,"sprite: R0,R1,R2 =",R0,R1,R2
        Debug   gs,"sprite: R3,R4,R5 =",R3,R4,R5
        Debug   gs,"sprite: R6,R7 =",R6,R7
        MOV     r6,r3                   ; put scale in r6
        MOV     r3,r1                   ; put x-coord in r3
        MOV     r1,r0
        MOV     r0,r2                   ; put y-coord in r4
        MOV     r2,r4                   ; put sie in r2
        MOV     r4,r0                   ; put y-coord in r4 part 2
        MOV     r5,#0                   ; only plot action of 0 allowed (eg no XOR etc.)
        ADR     r1,pjs_sprite           ; the fake sprite
        STR     R1,save_sprite          ; so that later code can find the JPEG data again
        MOV     R8,#0                   ; no printer calibration table
        STR     R8,calibration_table
        Debug   gs,"sprite: R0,R1,R2 =",R0,R1,R2
        Debug   gs,"sprite: R3,R4,R5 =",R3,R4,R5
        Debug   gs,"sprite: R6,R7 =",R6,R7
        B       putsprscaled_frompjs
; ??? We come to here from exitbiggie, after either an error or plotting the sprite.
; Just drop the stack, and exit.
jpegscaled_exit
        MOV     r1, sp
        Debug   gs, "We returned to the right place",R1
        ADRL    r1, ccompiler_errptr
        LDR     r0, [r1]
        CMP     r0, #0                  ; did C code return an error?
        BEQ     jpegscaled_exit_ok
        ADD     sp, sp, #4                  ;skip stored R0
        SUB     sp,sp,#pjs_table-pjs_start  ;stop sp ADD in 'jpegscaled_errorextit' moving stack too far.
        TST     r0, #2                  ; C code returned bad jpeg error
        BNE     jpegscaled_errorexit1
        TST     r0, #4                  ; C code bombed out with Fatal error
	BNE	jpegscaled_errorexit2
; Must have a "Run out of memory" error
        Debug   gs, "We think we'be run out of memory"
        ADRL    R0,ErrorBlock_JPEGNoRoom
        Debug   gs,"error block at r0 = ",R0
        BL      copy_error_one
	B	jpegscaled_errorexit
jpegscaled_exit_ok
        MOV     r1, sp
        Debug   gs,"ok1. sp = ",r1
        Pull    "R0"
        Debug   gs,"r0 when lpaded =",R0
        MOV     r1, sp
        Debug   gs,"ok2. sp = ",r1
        ADD     sp,sp,#pjs_end-pjs_table          ; free that space
        MOV     r1, sp
        Debug   gs,"ok3. sp = ",r1
        Pull    "R1-R9,LR"
        Debug   gs,"X R0-3",R0,R1,R2,R3
        Debug   gs,"X R4-7",R4,R5,R6,R7
        Debug   gs,"X R8-9",R8,R9
        MOV     pc, lr

jpegscaled_errorexit2
        Debug   gs, "We think we'be had a fatal error"
        ADRL    R0,ErrorBlock_JPEGFatal
        Debug   gs,"error block at r0 = ",R0
        BL      copy_error_one
	B	jpegscaled_errorexit
jpegscaled_errorexit1
        Debug   gs, "We think we'be got a duff JPEG"
        ADRL    R0,ErrorBlock_BadJPEG
        Debug   gs,"error block at r0 = ",R0
        BL      copy_error_one
        Debug   gs,"1. r0 is now = ",R0
;        MOV     r1, sp
        Debug   gs,"1. sp = ",r1
jpegscaled_errorexit
        MOV     r4, #pjs_end-pjs_table
        Debug   gs,"pjs size = ",R4
        ADD     sp,sp,#pjs_end-pjs_start          ; free that space
        MOV     r4, sp
        Debug   gs,"2. sp = ",r4
        Pull    "R1-R9,LR"
;        MOV     r1, sp
;        Debug   gs,"4. sp = ",r1
        Debug   gs,"r0 is now (at end...) = ",R0
        Debug   gs,"X R0-3",R0,R1,R2,R3
        Debug   gs,"X R4-7",R4,R5,R6,R7
        Debug   gs,"X R8-9,12",R8,R9,R12
        MOV     r4, lr
        Debug   gs,"about to return to ",R4
        MOV     pc, lr

pjs_checkColourTrans
        DCB     "RMEnsure ColourTrans 1.25 Error no good", 0 ; any error will do
        ALIGN
        ]

;SWIJPEG_PlotFileScaled
;In:
;  r0 = pointer to control character terminated filename
;  r1 = x co-ordinate for plot
;  r2 = y co-ordinate for plot
;  r3 = scale factors or 0
;  r4 = Flags
;       b0 set: dither output when plotting truecolour in 8bpp or less.
;       b1 set: Full error-diffusion when plotting to 8bpp.
;
;Out:
;  all registers preserved.
;
SWIJPEG_PlotFileScaled

        [ ccompiler
        BICS    LR, r4, #3              ;has someone set illegal flags?
        ADRNEL  R0, ErrorBlock_BadFlags
        addr    r1, Title, NE
        BLNE    copy_error_one          ; Always sets the V bit
        Pull    "PC", VS

        Pull    "LR"
        Push    "R0,R4-R6,LR"
	Push    "R1-R4"

;Find out file size.
	MOV	r1, r0
	MOV	r0, #23
	SWI	XOS_File
        CMP     r0, #0
        BEQ     JPEG_PlotFileScaled_NoFile
	Debug   gs,"File size =", r4
;Create Dynamic memory area for JPEG
;	Push	"R0-R8"
;        MOV	r0, #0
;	MOV	r1, #-1
;	MOV	r2, r4			; size of JPEG buffer
;	MOV	r3, #-1
;	MOV	r4,
;	MOV	r5, #-1			; Maximum area same as minimum?
;	MOV	r6, #0
;	MOV	r7, #0
;	ADRL	r8, SpriteExtend_AreaName
;	SWI	XOS_DynamicArea

;Claim space for buffer from Module area.
        MOV     r0, #6                   ; prepare for OS_Module call
        MOV     r3, r4                   ; size of JPEG buffer
        SWI     XOS_Module               ; pointer to block now in r2
        Debug   gs,"Block for JPEG =", R2
        BVS     JPEG_PlotFileScaled_error; jump out and return error.
;Read file into buffer
        MOV     r6, r2                  ; Move r2 to r6 because r2 gets changed by OS_FILE
	MOV     r3, #0		  	; clear r3 so r2 used as load address
        MOV     r0, #16                 ; load file Reason code for OS_File
	Debug   gs,"Loading file: r0,r1,r2,r3 =", R0,R1,R2,R3
        SWI     XOS_File                ; file name still in r1
        BVS     JPEG_PlotFileScaled_error; jump out and return error.
	Debug   gs,"Load address = ",R6
	MOV	r0, r6
	Pull    "R1-R3,R5"             ; pull original parameters into correct regs for JPEG_plotscaled.
        Push    "R6"                   ; store address of buffer so we can free it.
        ADR     LR, PlotScaled_return ; set up return from plot code.
        Push    "LR"
	Debug   gs,"Calling PlotScaled: R0,R1,R2,R3,R4,R5=",R0,R1,R2,R3,R4,R5
        B       SWIJPEG_PlotScaled
PlotScaled_return
	Debug   gs,"Return From PlotScaled: R0,R1,R2,R3=",R0,R1,R2,R3
        MOVVS   r4, #1                  ;keep record of error after next SWI call.
        MOVVC   r4, #0
JPEG_PlotFileScaled_exit1
        MOV     r5, r0                  ; temporarily store r0 and r2
        MOV     r6, r2
        Pull    "R2"                    ; recover location of buffer from stack
        MOV     r0, #7
        SWI     XOS_Module              ; Free module space
        BVS     JPEG_PlotFileScaled_error2; jump out and return error.
        MOV     r0, r5                  ; recover original r0 and r2
        MOV     r2, r6
        CMP     r4, #1                  ; Did SWIJPEG_PlotScaled return an error?
        BNE     JPEG_PlotFileScaled_exit2
        SETV                            ; If so, make sure the V flag is set.
        B       JPEG_PlotFileScaled_error2
JPEG_PlotFileScaled_exit2
        Pull    "R0,R4-R6,PC"

JPEG_PlotFileScaled_NoFile
        ADRL    R0,ErrorBlock_NoFile
        Pull    "R1-R4"
        MOV     r4, r1
        Pull    "R1"                     ;should be r0 saved at start...
        BL      copy_error_one
        MOV     r1, r4
	Pull	"R4-R6,PC"

JPEG_PlotFileScaled_error
        Pull    "R1-R4"
        Debug   gs,"about to return from filescaled..."
JPEG_PlotFileScaled_error2
        ADD	sp, sp, #4
	Pull	"R4-R6,PC"
        ]

;SWIJPEG_PlotTransformed
;  In:
;	R0 = Pointer to JPEG file loaded in Memory
;	R1 = flag word
;		b0 set: R2 is pointer to dest. coords, else pointer to matrix
;		b1 set: dither output when plotting truecolour in 8bpp or less.
;		b2 set: Full error-diffusion when plotting to 8bpp.
;	R2 = pointer to matrix (as for Draw module) or
;	     pointer to destination co-ordinate block.
;       R3 = length of data in memory.
;  Out:
;	All registers preserved.

SWIJPEG_PlotTransformed

	Pull    "LR"
        Push	"R0-R11,LR"
        BICS    r4, r1, #7              ;has someone set illegal flags?
        Pull    "R0-R11", NE
        ADRNEL  R0, ErrorBlock_BadFlags
        addr    r1, Title, NE
        BLNE    copy_error_one          ; Always sets the V bit
        Pull    "PC", VS

	TST     r1, #1
	BNE     DestCoords
;Matrix
	LDR	r4, [r2, #4]		;Rotation value
	CMP	r4, #0
        Debug   gs,"Rot value 1..",R4
	BNE	JPEGTrans_ErrorExit
	LDR	r4, [r2, #8]		;Rotation value
	CMP	r4, #0
        Debug   gs,"Rot value 2..",R4
	BNE	JPEGTrans_ErrorExit
	LDR	r4, [r2]		;X scale factor in Draw Transform units
	CMP     r4, #0
	BMI     JPEGTrans_ErrorExit
	LDR	r4, [r2, #12]		;Y scale factor in Draw Transform units
	CMP     r4, #0
	BMI     JPEGTrans_ErrorExit
;Make up scale factor...
	Debug	gs,"scale factors are...",R7,R8,R2,R3
	Push	"R0-R2"
	MOV	r0, #-1
	MOV	r1, #4
	SWI	XOS_ReadModeVariable	; Get X Eig in R2
	MOV	r7, r2		        ; Put into r7
	MOV	r1, #5
	SWI	XOS_ReadModeVariable	; Get Y Eig in R2
	MOV	r8, r2		        ; put into r7
	Pull	"R0-R2"
	SUB	sp, sp, #16		; make room for scale factors
	LDR	r4, [r2]		;X scale factor in Draw Transform units
	STR	r4, [sp]
	LDR	r4, [r2, #12]		;Y scale factor in Draw Transform units
	STR	r4, [sp,#4]
        MOV     r6, #180                ; Dpi of 1 pixel per OS unit sprite.
        MOV     r7, r6, LSR r7          ; X Dpi of output sprite
        MOV     r8, r6, LSR r8          ; Y Dpi of output sprite
        Push    "R1-R6"
; JPEG pointer already in r0?        MOV     r0, r0
        MOV     r2, #0
        BL      asm_find_image_dims
        MOV     r9, r4
        MOV     r10, r5
        Pull    "R1-R6"

; *************************************************
; ***  DivRem - Integer division and remainder  ***
; ***  rc := ra DIV rb; ra := ra REM rb         ***
; ***  rb preserved, rtemp corrupt              ***
; ***  DivRem   rc, ra, rb, rtemp               ***
; *************************************************

; We need to use a ratio of Output dpi to input dpi to convert
; the OS unit to OS unit scale factor from matrix to a pixel to
; pixel scale factor which we can send to PlotScaled.
	MOV	r4, r9, LSL #16		; X input dpi * 2^16 (because of
					; transform coordinates)
        DivRem  r5, r4, r7, r9          ; r5 = xdivisor div outdpi
	STR	r5, [sp,#8]
	MOV     r4, r10, LSL #16	; X input dpi * 2^16 (because of
					; transform coordinates)
        DivRem  r5, r4, r8, r9          ; r5 = xdivisor div outdpi
	STR	r5, [sp,#12]
;Set up registers for PutScaled Call
	MOV	r4, r3
	MOV	r3, sp                  ; Pointer to Scale factors
	MOV     r5, r1, LSR #1
	LDR	r1, [r2, #16]		; X-coordinate in 1/256th OSunit
        MOV     r1, r1, ASR #8
	LDR	r2, [r2, #20]		; Y-coordinate in 1/256th OSunit
        MOV     r2, r2, ASR #8
	Debug	gs,"Calliing PutScaled.R0,R1,R2,R3,R4,R5=",R0,R1,R2,R3,R4,R5
	ADRL	lr, Trans_PlotReturn
	Push	"LR"
	BL 	SWIJPEG_PlotScaled
DestCoords
	Debug	gs,"Doing a DestCoords Plot Transformed"
	MOV	r11, r1
;Check output coord block is a rectangle
	LDR     r4, [r2]		;X0
	Debug	gs,"load 1 ",r4
	LDR	r5, [r2, #24]		;X3
	Debug	gs,"load 2 ",r5
	CMP	r4, r5
        BNE	JPEGTrans_ErrorExit
	Debug	gs,"Check 1 passed"
	LDR     r4, [r2, #4]		;Y0
	LDR     r5, [r2, #12]		;Y1
	CMP	r4, r5
        BNE	JPEGTrans_ErrorExit
	Debug	gs,"Check 2 passed"
	LDR     r4, [r2, #20]		;Y2
	LDR     r5, [r2, #28]		;Y3
	CMP	r4, r5
        BNE	JPEGTrans_ErrorExit
	Debug	gs,"Check 3 passed"
	LDR     r4, [r2, #8]		;X1
	LDR     r5, [r2, #16]		;X2
	CMP	r4, r5
        BNE	JPEGTrans_ErrorExit
	Debug	gs,"Check 4 passed"
	LDR     r4, [r2]		;X0
	CMP	r4,r5			; which one is biggest?
	BGT	JPEGTrans_ErrorExit	; can't allow flipping...
	Debug	gs,"Check 5 passed"
	LDR     r6, [r2, #4]		; Y0
	LDR     r7, [r2, #28]		; Y3
	CMP	r7,r6			; which one is biggest?
	BGT	JPEGTrans_ErrorExit	; can't allow flipping...
	Debug	gs,"Check 6 passed"
	SUB	r4, r5, r4		; dest X-size in r4 in 1/256th OS units
	SUB	r5, r6, r7		; dest Y-size in r5 in 1/256th OS units
	MOV	r4, r4, LSR #8		; dest X-size in r4 in OS units
	MOV	r5, r5, LSR #8		; dest Y-size in r5 in OS units
;convert dest size from OS units to pixels
	Debug	gs,"Plot dosen't include any rotation or flipping"
	Push	"R0-R2"
	MOV	r0, #-1
	MOV	r1, #4
	SWI	XOS_ReadModeVariable	; Get X Eig in R2
	MOV	r7, r4, LSR r2		; Dest X-Size in pixels
	MOV	r1, #5
	SWI	XOS_ReadModeVariable	; Get Y Eig in R2
	MOV	r8, r5, LSR r2		; Dest Y-Size in pixels
	Pull	"R0-R2"
	MOV     r9, r2			; temp store of pointer to coord block;
	MOV	r10, r3			; temp store of length of data;
;find size of JPEG
	MOV	r1, r0			; pointer to JPEG
	MOV	r0, #1
	MOV	r2, r3			; length.
	ADRL	lr, Trans_InfoReturn
	Push	"LR"
	B	SWIJPEG_Info
;Make up scale factor...
Trans_InfoReturn
	Debug	gs,"scale factors are...",R7,R8,R2,R3
	SUB	sp, sp, #16		; make room for scale factors
	STR	r7, [sp]
	STR	r8, [sp,#4]
	STR	r2, [sp,#8]
	STR	r3, [sp,#12]
;Set up registers for PutScaled Call
	MOV	r3, sp                  ; Pointer to Scale factors
	MOV 	r0, r1			; Pointer to JPEG
	LDR	r1, [r9]		; X-coordinate in 1/256th OSunit
        MOV     r1, r1, ASR #8
	LDR	r2, [r9,#28]		; Y-coordinate in 1/256th OSunit
        MOV     r2, r2, ASR #8
	MOV	r4, r10
	MOV     r5, r11, LSR #1
	Debug	gs,"Calliing PutScaled.R0,R1,R2,R3,R4,R5=",R0,R1,R2,R3,R4,R5
	ADRL	lr, Trans_PlotReturn
	Push	"LR"
	BL 	SWIJPEG_PlotScaled
Trans_PlotReturn
;what if error returned?
	ADDVS	sp, sp, #16
	BVS	JPEGTrans_ErrorExit1
;recover stack space
	Debug	gs,"Returned from putscaled"
	ADD	sp, sp, #16
	Pull	"R0-R11,PC"

JPEGTrans_ErrorExit
        ADRL  	R0,ErrorBlock_BadJPEGPlot
        BL      copy_error_one
        Debug   gs,"Done 'copy_error_one'"
JPEGTrans_ErrorExit1
	ADD     sp, sp, #4                      ;Skip over r0
	Pull	"R1-R11,PC"
;	MOV     pc, lr

;SWIJPEG_PlotFileTransformed
;  In:
;	R0 = Pointer to control charater terminated filename for JPEG image
;	R1 = flag word
;		b0 set: R2 is pointer to dest. coords, else pointer to matrix
;		b1 set: dither output when plotting truecolour in 8bpp or less.
;		b2 set: Full error-diffusion when plotting to 8bpp.
;	R2 = pointer to matrix (as for Draw module) or
;	     pointer to destination co-ordinate block.
;  Out:
;	All registers preserved.


SWIJPEG_PlotFileTransformed

        [ ccompiler
        Pull    "LR"
        Push    "R0,R3-R6,LR"
        BICS    r3, r1, #7              ;has someone set illegal flags?
        Pull    "R0,R3-R6", NE
        ADRNEL  R0, ErrorBlock_BadFlags
        addr    r1, Title, NE
        BLNE    copy_error_one          ; Always sets the V bit
        Pull    "PC", VS

	Push    "R1-R3"

;Find out file size.
	MOV	r1, r0
	MOV	r0, #23
	SWI	XOS_File
        CMP     r0, #0
        BEQ     JPEG_PlotFileTransformed_NoFile
	Debug   gs,"File size =", r4

;Claim space for buffer from Module area.
        MOV     r0, #6                   ; prepare for OS_Module call
        MOV     r3, r4                   ; size of JPEG buffer
        SWI     XOS_Module               ; pointer to block now in r2
        Debug   gs,"Block for JPEG =", R2
        BVS     JPEG_PlotFileTransformed_error; jump out and return error.
;Read file into buffer
        MOV     r6, r2                  ; Move r2 to r6 because r2 gets changed by OS_FILE
	MOV     r3, #0		  	; clear r3 so r2 used as load address
        MOV     r0, #16                 ; load file Reason code for OS_File
	Debug   gs,"Loading file: r0,r1,r2,r3 =", R0,R1,R2,R3
        SWI     XOS_File                ; file name still in r1
        BVS     JPEG_PlotFileTransformed_error; jump out and return error.
	Debug   gs,"Load address = ",R6
        MOV     r3, r4
  	MOV	r0, r6
	Pull    "R1-R2,R4"             ; pull original parameters into correct regs for JPEG_plotTransformed.
        Push    "R6"                   ; store address of buffer so we can free it.
        ADR     LR, PlotTransformed_return ; set up return from plot code.
        Push    "LR"
	Debug   gs,"Calling PlotTransformed: R0,R1,R2,R3,R4,R5=",R0,R1,R2,R3,R4,R5
        B       SWIJPEG_PlotTransformed
PlotTransformed_return
	Debug   gs,"Return From PlotTransformed: R0,R1,R2,R3=",R0,R1,R2,R3
        MOVVS   r4, #1                  ;keep record of error after next SWI call.
        MOVVC   r4, #0
JPEG_PlotFileTransformed_exit1
        MOV     r5, r0                  ; temporarily store r0 and r2
        MOV     r6, r2
        Pull    "R2"                    ; recover location of buffer from stack
        MOV     r0, #7
        SWI     XOS_Module              ; Free module space
        BVS     JPEG_PlotFileTransformed_error2; jump out and return error.
        MOV     r0, r5                  ; recover original r0 and r2
        MOV     r2, r6
        CMP     r4, #1                  ; Did SWIJPEG_PlotTransformed return an error?
        BNE     JPEG_PlotFileTransformed_exit2
        SETV                            ; If so, make sure the V flag is set.
        B       JPEG_PlotFileTransformed_error2
JPEG_PlotFileTransformed_exit2
        Pull    "R0,R3-R6,PC"

JPEG_PlotFileTransformed_NoFile
        ADRL    R0,ErrorBlock_NoFile
        Pull    "R1-R3"
        MOV     r4, r1
        Pull    "R1"                     ;should be r0 saved at start...
        BL      copy_error_one
        MOV     r1, r4
	Pull	"R3-R6,PC"

JPEG_PlotFileTransformed_error
        Pull    "R1-R3"
        Debug   gs,"about to return from fileTransformed..."
JPEG_PlotFileTransformed_error2
        ADD	sp, sp, #4
	Pull	"R3-R6,PC"
        ]

;SWIJPEG_PDriverIntercept
;  In:
;	R0 = flags
;	   	b0 = intercept state; 0 = off, 1 = on
;	   	b1 = set: plot all JPEGs using translation table
;		b2-31 reserved (set to 0)
;  Out:
;	All registers preserved.

SWIJPEG_PDriverIntercept

        Debug   gs,"Pdriver Intercept called...."
      	Push	"R1"
	LDR	r1, save_PdriverIntercept
	AND	r0, r0, #3
	STR	r0, save_PdriverIntercept
	Debug   gs, "Setting the Pdriver intercept flag to ...",R0
	MOV	r0, r1
	Pull	"R1,PC"

        MakeSpriteErrorBlock BadJPEGPlot,,BadJPEGPlot

        END