10 REM > ZNOS/S
   20 REM Source for ZNOS ROM 6502 code
   30 REM
   40 REM v0.01 JGH: Initial source code recreated
   50 :
   60 OS_CLI=&FFF7:OSBYTE=&FFF4:OSWORD=&FFF1:OSWRCH=&FFEE
   70 OSASCI=&FFE3:OSGBPB=&FFD1:OSNEWL=&FFE7:OSFILE=&FFDD
   80 :
   90 DIM mcode% &400
  100 FORP=0TO1
  110   P%=&8000:O%=mcode%
  120   [OPT P*3+4
  130   .L8000
  140   CLC:SEI:EQUB &90                   :\ Language entry
  150   .L8003                             :\ Dual code, 6502 and Z80
  160   JMP Service                        :\ Service entry
  170   EQUB &EA:EQUB L802F-L8000
  180   .ROMVersion
  190   EQUB &65
  200   .ROMTitle
  210   EQUS "This is FREEWARE: type *HELP ZNOS":EQUB 0:EQUS "1.02"
  220   .ROMCopyright
  230   .L802F
  240   EQUB 0:EQUS "(C)1986 SJ Research":EQUB 0
  250   EQUD &0000B000                     :\ CoPro relocation address
  260   :
  270   EQUS STRING$(&8050-P%,CHR$255)
  280   
  290   
  300   \ ---------------------------------------
  310   \ Entry point if entered as 6502 language
  320   \ ---------------------------------------
  330   .L8050
  340   CLI:JSR L8057                      :\ Display Z80 warning message
  350   JMP L825A                          :\ Find another language to enter
  360   
  370   \ ---------------------------
  380   \ Display Z80 warning message
  390   \ ---------------------------
  400   .L8057
  410   JSR L823A
  420   EQUS "Requires Z80 second processor":EQUB 13:EQUB 0
  430   RTS
  440   
  450   \ --------------------------------------
  460   \ Entry point if entered as Z80 language
  470   \ --------------------------------------
  480   .L807A
  490   EQUB &21:EQUB &00:EQUB &D0 :\ LD HL,&D000
  500   EQUB &11:EQUB &00:EQUB &F5 :\ LD DE,&F500
  510   EQUB &01:EQUB &01:EQUB &1D :\ LD BC,&1D01
  520   EQUB &ED:EQUB &B8          :\ LDDR         ; Copy code up to &D800
  530   EQUB &C3:EQUB &00:EQUB &F2 :\ JP &F200     ; Enter Cold Boot
  540   \
  550   \ ROM &8300-&A000 copied to Z80 memory &D800-&F500
  560   \ 8300-8AFF -  &800 bytes - CCP  -> copied to &D800-&DFFF
  570   \ 8B00-9CFF - &1200 bytes - BDOS -> copied to &E000-&F1FF
  580   \ 9D00-9FFF -  &300 bytes - BIOS -> copied to &F200-&F4FF
  590   \
  600   \ -----------------------
  610   \ Print long help message
  620   \ -----------------------
  630   .L8088
  640   JSR L823A                          :\ Print start of help message
  650   EQUS "         FREEWARE message":EQUB 13:EQUB 13
  660   EQUS "SJ Research ZNOS allows Acorn Z80":EQUB 13
  670   EQUS "2nd Processors to be used with the Econet":EQUB 13:EQUB 13
  680   EQUS "You may make any number of copies":EQUB 13
  690   EQUS "and distribute them freely, provided":EQUB 13
  700   EQUB 0
  710   
  720   .L8137
  730   LDA #L9B80 AND 255:STA &A8         :\ Point to rest of help text
  740   LDA #L9B80 DIV 256:STA &A9
  750   LDY #&00
  760   .L8141
  770   LDA (&A8),Y:BEQ ServClaim          :\ Zero byte, exit with call claimed
  780   JSR OSASCI                         :\ Print character
  790   INC &A8:BNE L8141
  800   INC &A9:BNE L8141                  :\ Increment address, loop to next char
  810   
  820   .ServClaim
  830   PLA:TAY:PLA:LDA #&00:LDX &F4       :\ Restore stacked registers
  840   RTS                                :\ Exit with A=0 to claim
  850   
  860   \ ----------------
  870   \ Display ROM help
  880   \ ----------------
  890   .ServHelp
  900   LDA (&F2),Y:CMP #&0D:BEQ L8166     :\ If no parameters, display short help
  910   JSR L81B7:BNE ServExit             :\ If not 'ZNOS', exit silently
  920   JMP L8088                          :\ Jump to display long help message
  930   
  940   .L8166
  950   JSR L823A                          :\ Display short help message
  960   EQUB 13
  970   .L816A                             :\ Also used as 'ZNOS' command string
  980   EQUS "ZNOS ROM ver 1.01":EQUB 13:EQUB 0
  990   JMP ServExit
 1000   
 1010   \ ---------------------
 1020   \ OSBYTE 63 - Fetch CCP
 1030   \ ---------------------
 1040   .ServOsbyte
 1050   LDA &EF:CMP #&3F:BNE ServExit      :\ If not OSBYTE 63, exit unclaimed
 1060   LDA #&08:JSR L81D8                 :\ Copy 8 pages of code to second processor
 1070   LDA #&83:JSR &0406                 :\ Release Tube
 1080   JMP ServClaim                      :\ Exit with service claimed
 1090   
 1100   \ --------------------
 1110   \ Service call handler
 1120   \ --------------------
 1130   .Service
 1140   TAX:PHA:TYA:PHA:TXA                :\ Save registers
 1150   CMP #&04:BEQ ServCommand           :\ *command
 1160   CMP #&09:BEQ ServHelp              :\ *HELP
 1170   CMP #&07:BEQ ServOsbyte            :\ OSBYTE
 1180   .ServExit
 1190   PLA:TAY:PLA:LDX &F4                :\ Restore resisters
 1200   RTS
 1210   
 1220   \ ---------
 1230   \ *commands
 1240   \ ---------
 1250   .ServCommand
 1260   JSR L81B7:BNE ServExit             :\ If not 'ZNOS', exit unclaimed
 1270   LDA #&1D:JSR L81D8                 :\ Copy CCP+BDOS+BIOS to second processor
 1280   JMP L822D                          :\ Enter Z80 at &F200 to cold boot
 1290   
 1300   \ -----------------------
 1310   \ Check for 'ZNOS' string
 1320   \ -----------------------
 1330   .L81B7
 1340   LDX #&00                           :\ Point to first character
 1350   .L81B9
 1360   LDA (&F2),Y:AND #&5F               :\ Get upper case character
 1370   CMP L816A,X:BNE L81D1              :\ Doesn't match 'ZNOS', check for '.'
 1380   INY:INX:CPX #&04:BNE L81B9         :\ Loop for four characters
 1390   LDA (&F2),Y:CMP #&41:BCS L81D5     :\ More letters, exit unmatched
 1400   .L81CE
 1410   LDA #&00:RTS                       :\ Exit matched
 1420   .L81D1
 1430   CMP #&0E:BEQ L81CE                 :\ If '.', exit matched
 1440   .L81D5
 1450   LDA #&01:RTS                       :\ Exit unmatched
 1460   
 1470   \ -----------------------------------------------
 1480   \ Copy ZNOS code over to second processor
 1490   \ On entry, A=number of pages to copy, &08 or &1D
 1500   \ CCP is &D800+&800
 1510   \ CCP+BDOS+BIOS is &D800+&1D00
 1520   \ -----------------------------------------------
 1530   .L81D8
 1540   PHA:LDA #&EA                       :\ Save entry parameter
 1550   LDX #&00:LDY #&FF:JSR OSBYTE       :\ Is Tube present?
 1560   INX:BEQ L81EE                      :\ Tube present, jump to copy code
 1570   JSR L8057                          :\ Display Z80 warning
 1580   PLA:PLA:PLA:JMP ServClaim          :\ Clear stack and return claimed
 1590   
 1600   .L81EE
 1610   LDA #&C3:JSR &0406:BCC L81EE       :\ Claim Tube with ID &03
 1620   LDA #&00:STA &AA:STA &AC:STA &AD   :\ Set up copy addresses
 1630   LDA #&D8:STA &AB                   :\ &A8/9    =&8300 - source address in 6502
 1640   LDA #&00:STA &A8                   :\ &AA/B/C/D=&D800 - destination address in Z80
 1650   LDA #&83:STA &A9
 1660   PLA:TAX                            :\ Get number of pages
 1670   .L820B
 1680   TXA:PHA                            :\ Save number of pages to go
 1690   LDA #&07
 1700   LDX #&AA:LDY #&00:JSR &0406        :\ Transfer 256 bytes
 1710   PLA:TAX:LDY #&00
 1720   .L821A
 1730   LDA (&A8),Y:STA &FEE5:INY          :\ Send a byte
 1740   NOP:NOP:NOP:BNE L821A              :\ Delay, loop back for 256 bytes
 1750   INC &A9:INC &AB                    :\ Increment pointers
 1760   DEX:BNE L820B                      :\ Loop for all pages
 1770   RTS
 1780   
 1790   \ -----------------
 1800   \ Enter code in Z80
 1810   \ -----------------
 1820   .L822D
 1830   LDA #&04
 1840   LDX #L8236 AND 255
 1850   LDY #L8236 DIV 256                 :\ Point to &0000F200
 1860   JSR &0406                          :\ Enter code on Z80 at &F200 to cold boot
 1870   .L8236
 1880   EQUD &0000F200                     :\ Address to enter on Z80
 1890   
 1900   \ -----------------
 1910   \ Print inline text
 1920   \ -----------------
 1930   .L823A
 1940   PLA:STA &A8:PLA:STA &A9            :\ Get address after JSR
 1950   LDY #&00:BEQ L8247                 :\ Jump into print loop
 1960   .L8244
 1970   JSR OSASCI                         :\ Print character
 1980   .L8247
 1990   INC &A8:BNE L824D:INC &A9          :\ Increment address
 2000   .L824D
 2010   LDA (&A8),Y:BNE L8244              :\ Get character, print if not zero
 2020   INC &A8:BNE L8257:INC &A9          :\ Increment before exiting
 2030   .L8257
 2040   JMP (&00A8)                        :\ Jump to code after string
 2050   
 2060   \ ------------------------
 2070   \ Find a language to enter
 2080   \ ------------------------
 2090   .L825A
 2100   LDA #&AA
 2110   LDX #&00:LDY #&FF:JSR OSBYTE       :\ Get address of ROM type table
 2120   STX &A8:STY &A9
 2130   LDY &F4                            :\ Get this ROM number
 2140   .L8269
 2150   DEY:BPL L826E                      :\ Not <0, jump to check
 2160   LDY #&0F                           :\ ROM<0, check from 15 downwards
 2170   .L826E
 2180   TYA:CMP &F4:BEQ L82A7              :\ Looped to this ROM, no more left to check
 2190   LDA (&A8),Y:AND #&40:BEQ L8269     :\ Not a language ROM, check next one down
 2200   TYA:PHA                            :\ Save ROM number
 2210   JSR L823A                          :\ Print message:
 2220   EQUS "Alternative language selected:":EQUB 13:EQUB 13
 2230   EQUB 0
 2240   PLA:TAX:LDA #&8E:JSR OSBYTE        :\ Enter this language
 2250   
 2260   .L82A7
 2270   JSR L823A                          :\ Print message:
 2280   EQUS "No other language ROM found.":EQUB 0
 2290   .L82C7
 2300   JMP L82C7                          :\ Enter infinite loop
 2310   
 2320   .L82CA
 2330   \ left over data
 2340   SBC (&CD),Y
 2350   DEC &EF
 2360   CMP (&30),Y
 2370   SBC &18
 2380   LDA &D921,Y
 2390   SBC (&97),Y
 2400   ASL &08
 2410   .L82D9
 2420   EQUB &77
 2430   EQUB &23
 2440   BPL L82D9
 2450   CMP #&21
 2460   SBC (&F1,X)
 2470   ROL &FF,X
 2480   EQUB &23
 2490   ROL &06,X
 2500   EQUB &EB
 2510   CMP &E3CD
 2520   AND (&E3,X)
 2530   SBC (&C5),Y
 2540   SBC &06
 2550   EQUB &3
 2560   .L82F1
 2570   ROR &03CD,X
 2580   BBS 6,&77,&831A
 2590   BPL L82F1
 2600   SBC (&C1,X)
 2610   CMP #&C5
 2620   SBC &06
 2630   EQUB &3
 2640   .L8300
 2650   \ &8300-&8AFF - CCP  - copied to &D800-&DFFF
 2660   \ &8B00-&xxFF - BDOS - copied to &E000-&F1FF
 2670   \ &8x00-&9FFF - BIOS - copied to &F200-&F4FF
 2680 ]:NEXT
 2690 PRINT" *SAVE ZNOS6502 ";~mcode%;" ";~O%;" FFFF0000 FFFBBC00"