10 REM > LDPIC/s
   20 REM Screen Loader
   30 REM David Acton/Bruce Smith
   40 REM BBC B/B+/M/Electron
   50 REM (c) Acorn User October 1986
   60 REM Bugfixed by J.G.Harston
   70 REM 14-Feb-1994 Added shadow screen support
   80 REM 22-Dec-2017 Added 12-bit nULA palette
   90 :
  100 name$="LDPIC":ver$="v2.10"
  110 oswrch=&FFEE:osbyte=&FFF4
  120 osfind=&FFCE:osbget=&FFD7:osargs=&FFDA
  130 DIM mcode% &200:load%=&FFFF0900
  140 addr=&A8:mode=&A8:bits=&AA:data=&AB
  150 byte=&AC:count=&AD:dbits=&AE:cbits=&AF
  160 :
  170 FOR opt%=4 TO 7 STEP 3
  180   O%=mcode%:P%=load%
  190   [OPT opt%
  200   .stack:BRK:.chn:BRK:.startHi:BRK
  210   .step:BRK:.pass:BRK
  220   ]
  230   O%=mcode%:P%=load%
  240   [OPT opt%
  250   .errSyntax
  260   BRK:EQUB 220:EQUS "Syntax: LDPIC <afsp>"
  270   .errNotFound
  280   BRK:EQUB 214:EQUS "File not found":BRK
  290   :
  300   .go%
  310   LDX #addr:LDY #0:LDA #1:JSR osargs   :\ Get command line
  320   LDA (addr),Y:CMP #33:BCC errSyntax   :\ No parameters
  330   LDX addr+0:LDY addr+1:LDA #&40
  340   JSR osfind:TAY:BEQ errNotFound       :\ No file
  350   :
  360   STA chn                    :\ Channel
  370   LDA #0:STA bits            :\ Clear bit accumulator
  380   JSR read8bits:STA dbits    :\ Bits per data value
  390   JSR read8bits:STA mode     :\ Screen mode
  400   AND #7:TAX
  410   LDA modebase,X:STA startHi :\ Get start of screen
  420   LDA #0:LDX #1:JSR osbyte   :\ Get machine type
  430   LDY #0:CPX #2:BEQ bPlus    :\ B+, force to non-shadow
  440   LDA #&84:JSR osbyte        :\ Y.b7=shadow screen
  450   .bPlus
  460   TYA:AND #&80:PHA           :\ Save shadow setting
  470   LDA #&87:JSR osbyte        :\ Y=current screen mode
  480   CPY mode:BEQ nochange      :\ Same mode
  490   LDA #&16:JSR oswrch        :\ MODE
  500   PLA:PHA:ORA mode:JSR oswrch:\ screen mode
  510   :
  520   .nochange
  530   PLA:STA mode                  :\ Remember shadow flag in b7
  540   LDX #&0F                      :\ 16 palette entries
  550   .loop1
  560   TXA:PHA:LDX #4:JSR readbits   :\ Read 4 bits
  570   TAY:PLA:TAX:TYA:STA palette,X :\ Store palette entry
  580   DEX:BPL loop1
  590   JSR read8bits:STA step        :\ Step-1 between bytes
  600   JSR read8bits:STA cbits       :\ Bits per count value
  610   :
  620   TSX:STX stack                    :\ Save stack for EOF
  630   LDA step:STA pass
  640   BIT mode:BPL dopass              :\ Not shadow screen
  650   LDA #1:JSR vramSelect            :\ Page in video RAM
  660   .dopass
  670   LDA startHi:STA addr+1
  680   LDA pass:STA addr+0:DEC addr+0   :\ addr=>start for this pass
  690   :
  700   .mainlp
  710   JSR read1bit:BCC forward         :\ 0=immediate data
  720   LDX cbits:JSR readbits:STA count :\ Get byte count
  730   LDX dbits:JSR readbits:\STA byte :\ Get byte
  740   LDY #&00
  750   .goback
  760   LDA byte:STA (addr),Y            :\ Store byte
  770   JSR addmove                      :\ Update address
  780   DEC count:BNE goback             :\ Loop to store these bytes
  790   BEQ next
  800   :
  810   .forward
  820   LDX dbits:JSR readbits           :\ Get byte
  830   LDY #&00:STA (addr),Y            :\ Store byte
  840   JSR addmove                      :\ Update address
  850   :
  860   .next
  870   LDA addr+1:BPL mainlp            :\ Still within screen memory
  880   DEC pass:BNE dopass              :\ Do another pass
  890   :
  900   .align
  910   LDA #0:STA bits                  :\ Flush to align to byte boundary
  920   LDA #&7F:LDX chn:JSR osbyte      :\ Read EOF
  930   TXA:PHA
  940   :
  950   LDA #19:JSR osbyte               :\ Wait for HSync to minimise flicker
  960   LDA #&40:STA &FE22               :\ Reset nULA
  970   LDA &248:STA &FE20               :\ Reset vULA
  980   PLA:BNE setpalette               :\ No more file, set 4-bit palette
  990   \LDA #0                          :\ b4-b7=palette index
 1000   .rgb12lp
 1010   SEC:SBC #&10:STA dbits        :\ Step to next palette index
 1020   LDX #4:JSR readbits           :\ red
 1030   ORA dbits:STA &FE23           :\ Store index+red
 1040   LDX #4:JSR readbits:ASL A     :\ green
 1050   ASL A:ASL A:ASL A:STA cbits   :\ Move green to b4-b7
 1060   LDX #4:JSR readbits           :\ blue
 1070   ORA cbits:STA &FE23           :\ Store green+blue
 1080   LDA dbits:BNE rgb12lp
 1090   JSR read8bits:BEQ setpalette  :\ No more settings
 1100   .auxlp
 1110   PHA:JSR read8bits:STA &FE22   :\ Set nULA aux register
 1120   PLA:SEC:SBC #1:BNE auxlp
 1130   :
 1140   .setpalette
 1150   LDX #&0F                  :\ 16 palette entries
 1160   .rgb4lp
 1170   LDA #&13:JSR oswrch       :\ VDU 19
 1180   TXA:JSR oswrch            :\ Colour number
 1190   LDA palette,X:JSR oswrch  :\ Set physical colour
 1200   LDA #&00:JSR oswrch       :\ rgb=0,0,0
 1210   JSR oswrch:JSR oswrch
 1220   DEX:BPL rgb4lp
 1230   :
 1240   .close
 1250   LDA &248:STA &FE20        :\ Reset vULA
 1260   LDA #0:JSR vramSelect     :\ Page out video RAM
 1270   LDA #0:LDY chn:JMP osfind :\ Close file and end
 1280   :
 1290   .addmove
 1300   LDA addr+0:CLC:ADC step:STA addr+0
 1310   LDA addr+1:ADC #&00:STA addr+1
 1320   RTS
 1330   :
 1340   .read1bit
 1350   DEC bits:BPL noget          :\ Decr. bits remaining
 1360   LDY chn:JSR osbget:BCS eof  :\ Get a byte
 1370   STA data:LDA #7:STA bits    :\ 8 bits remaining
 1380   .noget
 1390   ASL data:RTS                :\ Get bit to carry
 1400   .eof
 1410   LDX stack:BEQ close         :\ Stack not saved, close file
 1420   TXS:BNE setpalette          :\ Stack saved, set palette
 1430   :
 1440   .read8bits
 1450   LDX #8
 1460   .readbits
 1470   TXA:PHA:LDA #0:STA byte
 1480   .nextbit
 1490   JSR read1bit:ROR byte       :\ Move bits into top of byte
 1500   DEX:BNE nextbit
 1510   :
 1520   PLA:TAX
 1530   .alignbits
 1540   CPX #8:BCS return
 1550   ROR byte:INX:BNE alignbits  :\ Align to bottom of byte
 1560   .return
 1570   LDA byte
 1580   .vramOk
 1590   RTS
 1600   :
 1610   .vramSelect
 1620   PHA:TAX                  :\ A=0 main RAM, A=1 video RAM
 1630   LDA #108:JSR osbyte      :\ Attempt to select Master/Integra-B video RAM
 1640   PLA:INX:BNE vramOk       :\ X<>255, successful
 1650   EOR #1:TAX               :\ A=1 main RAM, A=0 video RAM
 1660   LDA #111:JMP osbyte      :\ Attempt to select Aries/Watford video RAM
 1670   :
 1680   .palette
 1690   .modebase
 1700   EQUB &30:EQUB &30:EQUB &30:EQUB &40:EQUB &58:EQUB &58:EQUB &60:EQUB &7C
 1710   EQUS ver$
 1720   :
 1730   ]:IF palette+16>&B00:PRINT"Code overrun":END
 1740 NEXT:PRINT"Saving ";name$;
 1750 OSCLI "SAVE "+name$+" "+STR$~mcode%+" "+STR$~O%+" "+STR$~(go%OR&FFFF0000)+" "+STR$~load%
 1760 PRINT