10 REM >MDump106/s
   20 REM Source for *MDUMP by J.G.Harston
   30 REM v0.10 12-Feb-1986 Original MG version
   40 REM v1.00 10-Mar-1989 Tidied up for Micro User article
   50 REM v1.01 23-Aug-2006 Added -80 option
   60 REM v1.02 23-Aug-2006 Tidied up and compacted code
   70 REM v1.03 25-Aug-2006 Ensured 4-byte Tube address
   80 REM v1.04 27-Sep-2006 Uses &FFFDxxxx and &FFFExxxx for screen memory
   90 REM v1.05 29-Sep-2006 Accesses shadow memory on B, not yet B+
  100 REM v1.06 15-Nov-2006 Accesses ROMs and Tube on Electron
  110 :
  120 OSWRCH=&FFEE:OSNEWL=&FFE7:OSARGS=&FFDA:OSBYTE=&FFF4
  130 :
  140 DIM mcode% &300:load%=&FFFF08F8:ver$="v1.06"
  150 :
  160 addr=&A8:end=&AC:rom=addr+2:mem=addr+3:os=&AE:cols=&AF:lptr=&F0:tube=&27A
  170 FOR P=0 TO 1
  180   P%=load%:O%=mcode%
  190   [OPT P*3+4
  200   .syntax
  210   \BRK:\EQUB 220:\EQUS "Syntax:\ MDump (-<cols>) <start> <end>|+<length>":\BRK
  220   BRK:EQUB 220:EQUS "Syntax: MDump <start> <end>|+<length>":BRK
  230   :
  240   .buff
  250   .start%
  260   LDA #135:JSR OSBYTE
  270   LDX #&16:TYA:BEQ setcols
  280   CPY #3:BEQ setcols:LDX #8
  290   .setcols
  300   STX addr
  310   LDA #1:LDX #lptr:LDY #0:JSR OSARGS:\ NB! writes 4 bytes of memory
  320   LDX #addr
  330   LDA (lptr),Y:CMP #ASC"-":BNE mdumpcols
  340   INY:JSR GetHex
  350   .mdumpcols
  360   CMP #13:BEQ syntax:LDA addr:PHA
  370   JSR GetHex:BEQ syntax
  380   CMP #ASC"+":PHP:BNE P%+5:JSR SkipSpace1
  390   LDX #end:JSR GetHex:PLP:BNE mdump:CLC
  400   LDA addr+0:ADC end+0:STA end+0
  410   LDA addr+1:ADC end+1:STA end+1
  420   :
  430   .mdump
  440   PLA:AND #&1F:CMP #&10:BCC P%+4:SBC #6:STA cols:\ Columns in decimal
  450   LDX #&FF:LDA tube:BMI mdump1:LDA rom:BPL mdump1
  460   STX mem:\ If no Tube, extend &Fxxxxx to &FFFxxxxx
  470   .mdump1
  480   LDA #&FC:BIT &FFB3
  490   BPL loop:STA TUBEIO+2   :\ Modify for Electron TUBE port
  500   :
  510   .loop
  520   LDX #2
  530   .praddr
  540   LDA addr,X:JSR PrHex
  550   DEX:BPL praddr
  560   JSR GetBytes:LDX #0
  570   .loop1
  580   JSR PrSpace
  590   LDA buff,X:JSR PrHex
  600   INX:CPX cols:BCC loop1
  610   JSR PrSpace:LDX #0
  620   .loop2
  630   LDA buff,X:AND #127
  640   CMP #32:BCS pr_char
  650   .pr_dot:LDA #ASC"."
  660   .pr_char:CMP #127:BEQ pr_dot
  670   JSR OSWRCH
  680   INX:CPX cols:BCC loop2
  690   JSR OSNEWL
  700   BIT &FF:BMI escape
  710   :
  720   LDX #&FC:CLC:LDA cols
  730   .inc_addr
  740   ADC addr+4,X:STA addr+4,X
  750   LDA #0:INX:BNE inc_addr
  760   LDA addr+1:EOR end+1:BNE loop
  770   LDA end+0:EOR addr+0
  780   AND #&F0:BNE loop
  790   .escape
  800   LDA #124:JMP OSBYTE     :\ Clear Escape and exit
  810   :
  820   .GetBytes
  830   PHP:SEI:LDA &F4:PHA     :\ Disable IRQs, save ROM
  840   LDA &FE34:PHA           :\ Save ACCCON
  850   LDX mem:INX:BNE GetTube :\ addr<&FFxxxxxx, language memory
  860   AND #&13:JSR SetACCCON  :\ Master, ACCCON=I/O, no FS RAM, main RAM
  870   LDA rom:CLC:ADC #&40    :\ &FFFx and &FF0x - ROM
  880   AND #&8F:JSR SelectROM  :\ Select the specified ROM
  890   LDA rom:TAX
  900   INX:BEQ GetIOMem        :\ &FFFF - Main memory
  910   INX:BEQ GetDisplay      :\ &FFFE - Display memory
  920   INX:BEQ GetShadow       :\ &FFFD - Shadow memory
  930   CMP #&80:AND #&40       :\ &FFCx - Hidden ROM
  940   BCC P%+4:ORA #&08       :\ &FF8x - FS RAM
  950   ORA &FE34:JSR SetACCCON :\ Page in requested memory
  960   JMP GetIOMem
  970   :
  980   .GetDisplay
  990   \LDA &D0:\AND #16:\BEQ GetIOMem :\ Not shadow screen displayed
 1000   LDA #&84:JSR OSBYTE
 1010   TYA:BPL GetIOMem        :\ Not shadow screen displayed
 1020   .GetShadow
 1030   LDA #1:JSR vramSelect   :\ Page in shadow memory
 1040   :
 1050   .GetIOMem
 1060   LDY cols
 1070   .GetByteLp
 1080   DEY:LDA (addr),Y:STA buff,Y
 1090   TYA:BNE GetByteLp
 1110   JSR vramSelect
        :
 1120   PLA:JSR SetACCCON:PLA:PLP :\ Restore ACCCON, restore ROM and IRQs
 1130   .SelectROM
 1140   STA &F4:JMP &FFB9
 1150   :
 1160   .SetACCCON
 1170   \LDX os:\CPX #3
 1180   \BCC P%+5:\STA &FE34    :\ Set ACCCON if on Master
 1190   \LDX OSARGS:\CPX #&5C
 1200   \BCS P%+5:\STA &FE34    :\ Set ACCCON if on Master
 1260   BIT OSARGS+2:BPL P%+5:STA &FE34 :\ Set ACCCON if on Master
 1210   .vramOk
 1220   RTS
 1230   :
 1240   .vramSelect
 1250   PHA:TAX                 :\ A=0 main RAM, A=1 video RAM
 1260   LDA #108:JSR OSBYTE     :\ Attempt to select Master video RAM
 1270   PLA:INX:BNE vramOk      :\ X<>255, successful
 1280   EOR #1:TAX              :\ A=1 main RAM, A=0 video RAM
 1290   LDA #111:JMP OSBYTE     :\ Attempt to select Aries/Watford RAM
 1300   :
 1310   .GetTube
 1320   BIT tube:BPL GetIOMem   :\ No Tube present
 1330   .GetTubeClaim
 1340   LDA #&C0+&10:JSR &406
 1350   BCC GetTubeClaim        :\ Claim Tube
 1360   LDX #addr:LDY #0
 1370   TYA:JSR &406:LDY #0     :\ Read bytes from Tube
 1380   .GetTubeLp
 1390   LDX #9                  :\ Delay between each byte
 1400   .GetTubeWait
 1410   DEX:BNE GetTubeWait     :\ 2+(2+3)*9+2+2 = 51 cycles = 25.5us
 1420   .TUBEIO
 1430   LDA &FEE5:STA buff,Y    :\ Fetch from Tube
 1440   INY:CPY cols:BNE GetTubeLp
 1450   PLA:PLA:PLP             :\ Drop from stack, restore IRQs
 1460   LDA #&80+&10:JMP &406   :\ Release Tube
 1470   :
 1480   .PrSpace
 1490   LDA #32:BNE PrChar
 1500   .PrHex
 1510   PHA:LSR A:LSR A:LSR A:LSR A
 1520   JSR PrDigit:PLA
 1530   .PrDigit
 1540   AND #15:CMP #10:BCC PrNybble:ADC #6
 1550   .PrNybble:ADC #48
 1560   .PrChar  :JMP OSWRCH
 1570   :
 1580   .GetHex
 1590   LDA #0
 1600   STA 0,X:STA 1,X
 1610   STA 2,X:STA 3,X
 1620   .GetHexNext
 1630   LDA (lptr),Y
 1640   CMP #ASC"0":BCC SkipSpace
 1650   CMP #ASC"9"+1:BCC GetHexDigit
 1660   AND #&DF:SBC #7:BCC SkipSpace
 1670   CMP #ASC"@":BCS SkipSpace
 1680   .GetHexDigit
 1690   AND #&0F:PHA:TYA:PHA:LDY #4
 1700   .GetHexMultiply
 1710   ASL 0,X:ROL 1,X:ROL 2,X:ROL 3,X
 1720   DEY:BNE GetHexMultiply
 1730   PLA:TAY
 1740   PLA:ORA 0,X:STA 0,X
 1750   INY:BNE GetHexNext
 1760   :
 1770   .SkipSpace1
 1780   INY
 1790   .SkipSpace
 1800   LDA (lptr),Y:CMP #ASC" ":BEQ SkipSpace1
 1810   CMP #13:RTS
 1820   :
 1830   EQUS ver$
 1840   :
 1850 ]:NEXT
 1860 PRINT"*SAVE MDump "+STR$~mcode%+" "+STR$~O%+" "+STR$~(start%OR&FFFF0000)+" "+STR$~(load%OR&FFFF0000)