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 BIOS, BDOS and CCP
 1030   \ ------------------------------------
 1040   .ServOsbyte
 1050   LDA &EF:CMP #&3F:BNE ServExit      :\ If not OSBYTE 63, exit unclaimed
 1060   LDA #&08:JSR L81D8                 :\ Copy 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              :\ *WHILEHIMEM
 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
 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:LDX #&36:LDY #&82         :\ Point to &0000F200
 1840   JSR &0406                          :\ Enter code on Z80 at &F200 to cold boot
 1850   .L8236
 1860   EQUD &0000F200                     :\ Address to enter on Z80
 1870   
 1880   \ -----------------
 1890   \ Print inline text
 1900   \ -----------------
 1910   .L823A
 1920   PLA:STA &A8:PLA:STA &A9            :\ Get address after JSR
 1930   LDY #&00:BEQ L8247                 :\ Jump into print loop
 1940   .L8244
 1950   JSR OSASCI                         :\ Print character
 1960   .L8247
 1970   INC &A8:BNE L824D:INC &A9          :\ Increment address
 1980   .L824D
 1990   LDA (&A8),Y:BNE L8244              :\ Get character, print if not zero
 2000   INC &A8:BNE L8257:INC &A9          :\ Increment before exiting
 2010   .L8257
 2020   JMP (&00A8)                        :\ Jump to code after string
 2030   
 2040   \ ------------------------
 2050   \ Find a language to enter
 2060   \ ------------------------
 2070   .L825A
 2080   LDA #&AA
 2090   LDX #&00:LDY #&FF:JSR OSBYTE       :\ Get address of ROM type table
 2100   STX &A8:STY &A9
 2110   LDY &F4                            :\ Get this ROM number
 2120   .L8269
 2130   DEY:BPL L826E                      :\ Not <0, jump to check
 2140   LDY #&0F                           :\ ROM<0, check from 15 downwards
 2150   .L826E
 2160   TYA:CMP &F4:BEQ L82A7              :\ Looped to this ROM, no more left to check
 2170   LDA (&A8),Y:AND #&40:BEQ L8269     :\ Not a language ROM, check next one down
 2180   TYA:PHA                            :\ Save ROM number
 2190   JSR L823A                          :\ Print message:
 2200   EQUS "Alternative language selected:":EQUB 13:EQUB 13
 2210   EQUB 0
 2220   PLA:TAX:LDA #&8E:JSR OSBYTE        :\ Enter this language
 2230   
 2240   .L82A7
 2250   JSR L823A                          :\ Print message:
 2260   EQUS "No other language ROM found.":EQUB 0
 2270   .L82C7
 2280   JMP L82C7                          :\ Enter infinite loop
 2290   
 2300   .L82CA
 2310   \ left over data
 2320   SBC (&CD),Y
 2330   DEC &EF
 2340   CMP (&30),Y
 2350   SBC &18
 2360   LDA &D921,Y
 2370   SBC (&97),Y
 2380   ASL &08
 2390   .L82D9
 2400   EQUB &77
 2410   EQUB &23
 2420   BPL L82D9
 2430   CMP #&21
 2440   SBC (&F1,X)
 2450   ROL &FF,X
 2460   EQUB &23
 2470   ROL &06,X
 2480   EQUB &EB
 2490   CMP &E3CD
 2500   AND (&E3,X)
 2510   SBC (&C5),Y
 2520   SBC &06
 2530   EQUB &3
 2540   .L82F1
 2550   ROR &03CD,X
 2560   BBS 6,&77,&831A
 2570   BPL L82F1
 2580   SBC (&C1,X)
 2590   CMP #&C5
 2600   SBC &06
 2610   EQUB &3
 2620   .L8300
 2630   \ &8300-&8AFF - CCP  - copied to &D800-&DFFF
 2640   \ &8B00-&xxFF - BDOS - copied to &E000-&F1FF
 2650   \ &8x00-&9FFF - BIOS - copied to &F200-&F4FF
 2660 ]:NEXT
 2670 PRINT" *SAVE ZNOS6502 ";~mcode%;" ";~O%;" FFFF0000 FFFBBC00"