> BIOS/src  Source for ZNOS BIOS : (A%=0:X%=1:os%=(&FFF4 &FF00)256:os%=6 >&8000:"Running Z80...": "OS_GetEnv" A$:"TextToBas "+A$,A$," ",1+A$," ")))+" -crunch *Z80": 2: <load%=&F200: mcode% &400 F: P P=0 1 ZP%=load%:O%=mcode% d[OPT P*3+4 n; ZNOS BIOS Source Code x; =====================  ); Commentary Copyright (C) J.Harston $; See mdfs.net/Software/CPM/ZNOS ; .BIOS_CBOOT :JP ColdBoot .BIOS_WBOOT :JP WarmBoot $.BIOS_CONST :JP ConsoleStatus .BIOS_CONIN :JP ConsoleIn !.BIOS_CONOUT :JP ConsoleOut .BIOS_LIST :JP List .BIOS_PUNCH :JP PunchOut .BIOS_READER :JP ReaderIn .BIOS_HOME :JP DiskNull .BIOS_SELDSK :JP DiskNull .BIOS_SETTRK :JP DiskNull .BIOS_SETSEC :JP DiskNull ".BIOS_SETDMA :JP DiskNull ,.BIOS_READ :JP DiskNull 6.BIOS_WRITE :JP DiskNull !@.BIOS_LISTST :JP ListStatus J.BIOS_SECTRAN:JP DiskNull T: ^\ Used by SJCCP :h.BATCH :B &00 :\ Batch file active ;r.SUBFCB:B &01:M "$$$ SUB" :\ "A $$$.SUB" filename +|\ F240 :B &00 :\ EX +\ F241 :B &00 :\ S1 +\ F242 :B &00 :\ S2 +\ F243 :B &00 :\ RC /W 0:W 0:W 0:W 0 :\ Alloc Vector W 0:W 0:W 0:W 0 +\ F254 :B &00 :\ CR ,\ F255 :W &0000:B &00 :\ R0-R2 : .LF25B (EQUB &2B ; ConStatus Counter .LF25C )B &21 ; Pending input buffer .LF25D :B &58 ; 0=no input pending, <>0=input pending  ).LF25E ; Reset input stream >&LD A,&83 ; Specify CON=UC1 RDR=TTY PUN=TTY LST=LPT #0LD (&0003),A ; Reset IOBYTE :XOR A #DLD (LF25D),A ; Clear a flag NLD L,&40 XLD A,&03 .b OSBYTE ; Output stream=prn disabled lLD L,&02 vLD A,&02 7JP OSBYTE ; Input stream=kbd, serial enabled : .ConsoleStatus  LF2D5:B &81 'W LF373:W LF330:W LF2C9:W LF2F7 : .ConsoleIn  LF2D5:B &01 &W LF381:W LF33D:W LF2BD: LF31D : .ConsoleOut  LF2D5:B &81 'W LF385:W LF355:W LF299:W LF32C : .List  LF2D5:B &03 ' W LF385:W LF355:W LF38F:W LF38F *: 4.ListStatus > LF2D5:B &03 'HW LF38A:W LF37C:W LF3A6:W LF3A6 R: \.PunchOut f LF2D5:B &05 'pW LF385:W LF355:W LF2F6:W LF2F6 z: .ReaderIn  LF2D5:B &07 'W LF381:W LF33D:W LF2F4:W LF2F4 : .LF2C9  LF2D5:B &07 'W LF373:W LF330:W LF37E:W LF37E : ; I/O dispatch ; ------------ .LF2D5 .POP HL:LD A,(HL) ; Get IOBYTE flag byte 0INC HL ; Point to address block BIT 7,A:LD B,A /RES 7,B ; B=IOBYTE shift amount 0JR NZ,LF2E3 ; b7=1, don't clear flag &$XOR A:LD (LF25B),A ; Clear a flag ..LF2E3 $8LD A,(&0003) ; Get IOBYTE B.LF2E6 1LRLCA:DJNZ LF2E6 ; Rotate IOBYTE by factor /V &06 ; Keep resultant two bits `LD D,&00:LD E,A 2jADD HL,DE ; Index into address block tLD E,(HL):INC HL -~LD D,(HL) ; DE=selected address )EX DE,HL:JP (HL) ; Jump to routine  ; ReaderIn 2,3 ; ------------ .LF2F4 "LD A,&1A:RET ; Return  ; ConStatus 3 ; ----------- ; Checks pending buffer %; Every 12 calls also checks host ; .LF2F7 1 LD A,(LF25D) ; Is pending buffer full? 3 A:RET NZ ; Return NZ if input pending *LD HL,LF25B ; Point to counter (XOR A 2 (HL) 3<JR Z,LF306 ; If zero, check host input +FDEC (HL) ; Decrement counter 4PXOR A:RET ; Return Z - nothing pending Z.LF306 -dLD (HL),&0C ; Reset counter to 12 HnLD HL,&0000 ; Only call host every 12 times ConStatus called xLD A,&81 4 OSBYTE ; (0), fetch any pending input LD A,H INC A :RET Z ; Return Z if no input pending <LD A,L:LD (LF25C),A ; Save character in input buffer 4LD A,&FF:LD (LF25D),A ; Flag input buffer full 6RET ; Return NZ, input pending   ; ConIn 3 ; ------- .LF31D 1LD A,(LF25D): A ; Check pending buffer 3JP Z,OSRDCH ; Empty, jump to OSRDCH 2XOR A:LD (LF25D),A ; Clear pending buffer ?LD A,(LF25C):RET ; Get character from pending buffer " , 6; ConOut 3 @; -------- J.LF32C -TLD A,C:JP &FF9E ; Jump to TERMOUT ^ h r; ConStat 1 |; --------- .LF330 LD L,&00 LD A,&80  OSBYTE ; (0) LD A,L  A RET Z LD A,&FF RET  .LF33D LD L,&02 .LF33F LD A,&02  OSBYTE  OSRDCH &PUSH AF 0LD A,L : A DJR NZ,LF34E NLD L,&02 X.LF34E bLD A,&02 l OSBYTE vPOP AF RET  .LF356 LD HL,&00F4 .LF358 LD A,&03  OSBYTE PUSH HL XOR A  &FFC8 PUSH AF LD A,C  OSWRCH POP AF  &FFC8 POP HL  LD H,&00 *LD A,&03 4JP OSBYTE > H.LF373 RLD L,&01 \LD A,&98 f OSBYTE pJR NC,LF37E zXOR A RET  .LF37E XOR A DEC A RET  .LF381 LD L,&01 JR LF33F .LF385 LD HL,&00F7 JR LF358  .LF38A  LD HL,&FFFD  JR LF3A9 $ .LF38F . LD A,&75 8 OSBYTE B BIT 0,L L JR NZ,LF39D V LD A,&02 ` OSWRCH j .LF39D t LD A,&01 ~ OSWRCH LD A,C  JP OSWRCH  LD HL,&FFFC .LF3A9  LD A,&80 OSBYTE LD A,L  A RET Z XOR A DEC A  RET   ;; COLD BOOT  ;; =========  ;; .( .ColdBoot ; Entered on startup >2 LD SP,&0080 ; Put initial stack in CPM workspace < EI 4F XOR A:LD (&0004),A ; Clear Current Drive+User ?P LD HL,&F730 ; Point to "1.20" in v1.20 client MOS 2Z LD DE,LF3E4 ; Point to "1.20" string 1d LD B,&04 ; Match four characters n .LF3C4 +x LD A,(DE):CP (HL) ; Compare strings  INC HL:INC DE 8 JR C,LF3D1 ; Version string doesn't match 4 DJNZ LF3C4 ; Loop for four characters 2 LD HL,&FCA3 ; v1.20 MOS command flag  JR LF3D4 4 .LF3D1 ; Not version 1.20 Z80 MOS 2 LD HL,&FF8A ; v2.00 MOS command flag .LF3D4 4 LD (HL),&FF ; Set to 'no MOS commands' E LF401 ; Initialise things, error handler, esc state,  ; zero page jumps < LF25E ; Initialise input and output streams G &E00C ; Call BDOS Cold Start, returns A=station number J LD C,&00:JP &D800 ; Enter CCP ColdBoot entry with C=drive 0/user 0  ; CCP entered with: * ; A=station number or &00 if no NetFS " ; C=drive/user , ; B=? ;6 ; HL=>OSWORD control block from reading station number @ ; DE=? J ; Acorn BIOS enters with "T ; A=drive &00-&0F or user &x0 ^ ; C=drive/user h r .LF3E4 1| M "1.20" ; Version string to match    ;; WARM BOOT  ;; =========  ;; .WarmBoot > LD SP,&0080 ; Put initial stack in CPM workspace  EI * LD A,&03: OSWRCH ; End any print job - &E00F ; Call BDOS Warm Start 4 LF3FC ; Fetch CCP and reset vectors J LD C,&00:JP &D803 ; Enter CCP WarmBoot entry with C=drive 0/user 0  & ; Fetch CCP and initialise vectors & ; --------------------------------  .LF3FC & LD A,&3F ; Fetch CCP 0 OSBYTE : D ; Initialise vectors N ; ------------------ X .LF401 4b &FFBF ; Ensure RSTERR at &0038 is set up 0l LD HL,(&FF84) ; Get default error handler .v LD (&FFFA),HL ; Set error handler to it  LD A,&E5 * LD HL,&0001 ; ESC key returns II OSBYTE  LD A,&C3 ) LD (&0000),A ; Put JP opcode into % LD (&0005),A ; RESET and BDOS .LF41A . LD HL,BIOS_WBOOT ; Put RESET destination ) LD (&0001),HL ; in address field - LD HL,&E006 ; Put BDOS destination ) LD (&0006),HL ; in address field .DiskNull  RET    .LF427 * EX (SP),HL 4 PUSH DE > PUSH BC H PUSH AF R .LF42B \ LD A,(HL) f INC HL p A z JR Z,LF437 PUSH HL LF43C POP HL  JR LF42B .LF437 POP AF POP BC POP DE  EX (SP),HL  RET  .LF43C CP &0D JR NZ,LF445  LF445 LD A,&0A $.LF445 .LD C,A 8JP ConsoleOut B AL; left-over code, a copy of the startup code and bits of BDOS V.LF449 `RLCA jDJNZ LF444 tLD HL,&FCA3 ~JR LF454  .LF451 LD HL,&FF8A .LF454 LD (HL),&FF  LF401  LF25E  &E00C LD C,&00 JP &D800 LD SP,&322E JR NC,LF49A ADD A,B  NOP EI LD A,&03 ( OSWRCH 2 &E00F < LF3FC FLD C,&00 PJP &D803 ZLD A,&3F d &28F4 n.LF481 xJR LF481 INC BC JR NZ,LF48D LD A,&8D  OSBYTE JR LF49A .LF48D LD L,&03 CP &02 JR Z,LF495 LD L,&00 .LF495 LD A,&8C  OSBYTE .LF49A POP HL RET "LD (&1364),SP ,PUSH HL 6LD HL,(&FFFA) @LD (&1362),HL JLD HL,&06DB TLD (&FFFA),HL ^POP HL hRET rLD SP,(&1364) |POP HL LD HL,(&FF82) PUSH HL INC HL SUB A,A LD BC,&FFFF CPIR DEC HL LD (HL),&0D POP HL LD A,(HL) INC HL  A JR LF4C9 XOR A .LF4C9 PUSH HL &LD HL,(&1362) 0LD (&FFFA),HL :POP HL DRET NPUSH DE XXOR A bLD E,A l OSARGS vPOP DE RET LD A,&03 RET .LF4DD:B &4A .LF4DE:B &03 $.LF4DF:M "SJ Econet ver 3.4Az$" .LF4F3:B &FE:B &1E .LF4F5:B &CA:B &B9:B &0D .LF4F8:B &FE:B &21 .LF4FA:B &38:B &02 .LF4FC:B &D6:B &09 .LF4FE:B &D6:B &0F ] >"Save ZNOS_BI "+~mcode%+" "+~O%+" "+~load%+" "+~load% *Quit