INITIO  TITLE   "Z80 BCPL Run Time System  -  Section INITIO"
        GET     "HEADER"
        LAYOUT
;  This section contains the basic stand alone I/O routines for the Z80 BCPL
;  system.  The nature of the raw I/O devices will depend on the hardware
;  for which the code is intended.
        LAYOUT
        REF     C.FNDI
        REF     C.FNDO
        REF     F.FNDI
        REF     F.FNDO

        DEF     C.RDCH
        DEF     C.WRCH

G.SARD  EQU     2*21                    ;  Global number of "sardch"
G.SAWR  EQU     2*22                    ;  Global number of "sawrch"
G.INIO  EQU     2*50                    ;  Global number of "initio"
G.IOLS  EQU     2*51                    ;  Global number of "iolist"
G.OSRD  EQU     2*130                   ;  Global number of "osrdch"
G.OSWR  EQU     2*131                   ;  Global number of "oswrch"
G.OSCL  EQU     2*132                   ;  Global number of "oscli"
G.MAXG  EQU     2*150                   ;  Highest referenced global
        LAYOUT
;  Equates which define the interface to the BBC micro using the 1MHz bus, and
;  the commands which can be sent down it.


O.NULL  EQU     0                       ;  Null command used for handshaking
O.RDCH  EQU     1                       ;  OS Rdch
O.WRCH  EQU     2                       ;  OS Wrch
O.CLI   EQU     3                       ;  OS CLI
O.BYTE  EQU     4                       ;  OS Byte
O.FIND  EQU     5                       ;  OS Find  (open)
O.BGET  EQU     6                       ;  OS Bget
O.BPUT  EQU     7                       ;  OS Bput
O.CLOSE EQU     8                       ;  OS Find  (close)

B.STAT  EQU     #X10                    ;  BBC Status Register
B.RX    EQU     #X11                    ;  BBC Receive Register
B.TX    EQU     #X12                    ;  BBC Transmit Register

B.RDRF  EQU     #X01                    ;  Flag for "receive register full"
B.TDRF  EQU     #X02                    ;  Flag for "transmit register full"
        LAYOUT
        RELOCATABLE

        ORG     0

INITIO  DEFB    'BCPL'                  ;  Entry flag for BCPL module
        DEFW    INITIOE-INITIO          ;  Length of module in bytes
        LAYOUT
;  INITIO
;  ------
;
;    initio()


        ALIGN

INIO    SETLINK                         ;  Set up BCPL linkage

;  Open and select the default input stream:
;
;    selectinput( findinput( "**" ) )

        LD      HL,INAME                ;  Name of default input file
        SRL     H                       ;  Make BCPL pointer ...
        RR      L                       ;  ... from file name
        EXX                             ;  Save argument register set
        LD      L,(IY-10)               ;  Low byte of "findinput"
        LD      H,(IY-9)                ;  High byte of "findinput"
        APPLY                           ;  Apply the function
        DEFB    0                       ;  Increase in stack size
        EXX                             ;  Save argument register set
        LD      L,(IY-6)                ;  Low byte of "selectinput"
        LD      H,(IY-5)                ;  High byte of "selectinput"
        APPLY                           ;  Apply the function
        DEFB    0                       ;  Increase in stack size

;  Open and select the default output stream:
;
;    selectoutput( findoutput( "**" ) )

        LD      HL,ONAME                ;  Name of default output file
        SRL     H                       ;  Make BCPL pointer ...
        RR      L                       ;  ... from file name
        EXX                             ;  Save argument register set
        LD      L,(IY-8)                ;  Low byte of "findoutput"
        LD      H,(IY-7)                ;  High byte of "findoutput"
        APPLY                           ;  Apply the function
        DEFB    0                       ;  Increase in stack size
        EXX                             ;  Save argument register set
        LD      L,(IY-4)                ;  Low byte of "selectoutput"
        LD      H,(IY-3)                ;  High byte of "selectoutput"
        APPLY                           ;  Apply the function
        DEFB    0                       ;  Increase in stack size

        RETURN                          ;  And return


        ALIGN
INAME   DEFB    "**"                    ;  Default input file name

        ALIGN
ONAME   DEFB    "**"                    ;  Default output file name
        LAYOUT
;  OSWRCH  +  SAWRCH
;  ------     ------
;
;    oswrch( ch )


        ALIGN

SAWR                                    ;  Double entry point
OSWR    PUSH    HL                      ;  Save return address
        EXX                             ;  Switch register sets
        LD      A,L                     ;  Low byte of argument
        CALL    OSWRCH                  ;  Write the character
        RET                             ;  And return
        LAYOUT
;  OSRDCH  +  SARDCH
;  ------     ------
;
;    ch  :=  osrdch()


        ALIGN

SARD                                    ;  Double entry point
OSRD    PUSH    HL                      ;  Save return address
        CALL    OSRDCH                  ;  Read character
        LD      H,0                     ;  High byte of result
        LD      L,A                     ;  Low byte of result
        RET                             ;  And return
        LAYOUT
;  OSCLI
;  -----
;
;    oscli( commandline )


        ALIGN

OSCL    PUSH    HL                      ;  Save return address
        EXX                             ;  Get argument register set
        ADD     HL,HL                   ;  Get byte pointer to string
        CALL    OSCLI                   ;  Call the OS interface
        RET                             ;  And return
        LAYOUT
;  BBC ROUTINES
;  ------------
;
;  Interface routines which enable calls to be made to the BBC operating
;  system.  They rely on two lower level routines, "BBCR" and "BBCW" which
;  handle I/O using the 1MHz bus interface, and "BBCCOM" which handles the
;  synchronisation necessary to write a command.


C.RDCH                                  ;  Raw console read
OSRDCH  LD      A,O.RDCH                ;  Command code
        CALL    BBCCOM                  ;  Write the command
        CALL    BBCR                    ;  Read the result
        RET                             ;  And return


C.WRCH                                  ;  Raw console write
OSWRCH  PUSH    AF                      ;  Save argument
        LD      A,O.WRCH                ;  Command code
        CALL    BBCCOM                  ;  Write the command
        POP     AF                      ;  Restore argument
        CALL    BBCW                    ;  Write the argument
        RET                             ;  And return


OSCLI   LD      A,O.CLI                 ;  Command code
        CALL    BBCCOM                  ;  Write the command
        CALL    BBCSTR                  ;  Write out the string
        RET                             ;  Return
        LAYOUT
;  Not defined yet  !!

OSBYTE
OSFIND
OSBGET
OSBPUT
OSCLOSE
        LAYOUT
;  BBCCOM
;  ------
;
;    Send a command to the BBC.  We ensure that we are both talking the same
;    language by setting up a handshake first.


BBCCOM  PUSH    AF                      ;  Save command code

BBCC0   LD      A,O.NULL                ;  Null code
        CALL    BBCW                    ;  Write it out
        CALL    BBCR                    ;  Read the reply
        CP      O.NULL                  ;  Null reply?
        JP      NZ,BBCC0                ;  No, so try again

        POP     AF                      ;  Restore command
        CALL    BBCW                    ;  Write the command
        RET                             ;  And return
        LAYOUT
;  BBCSTR
;  ------
;
;    Write out a string to the BBC, starting with the length, and then
;    that number of characters.

BBCSTR  LD      A,(HL)                  ;  Length of string
        CALL    BBCW                    ;  Write it out

BBCS0   OR      A                       ;  Length reached zero yet ?
        RET     Z                       ;  Yes, so return

        INC     HL                      ;  Increment buffer pointer
        DEC     A                       ;  Decrement length
        PUSH    AF                      ;  Save length
        LD      A,(HL)                  ;  Load character
        CALL    BBCW                    ;  Write it out
        POP     AF                      ;  Restore length
        JP      BBCS0                   ;  Loop until finished
        LAYOUT
;  BBCW
;  ----
;
;    Write a byte to the BBC interface.

BBCW    PUSH    AF                      ;  Save byte to be written

BBCW0   IN      A,(B.STAT)              ;  Read status register
        AND     B.TDRF                  ;  Transmit register full?
        JP      NZ,BBCW0                ;  Yes, so loop

        POP     AF                      ;  Restore byte
        OUT     (B.TX),A                ;  Write it out
        RET                             ;  And return
        LAYOUT
;  BBCR
;  ----
;
;    Read a byte from the BBC interface.


BBCR    IN      A,(B.STAT)              ;  Read status register
        AND     B.RDRF                  ;  Receive register full?
        JP      Z,BBCR                  ;  No, so loop

        IN      A,(B.RX)                ;  Read it
        RET                             ;  And return
        LAYOUT
;  IOLIST
;  ------
;
;    List of device names and their associated "findinput" and "findoutput"
;    routines.


        ALIGN

IOLS    DEFW    C.NAME,C.FNDI,C.FNDO    ;  Console handler
        DEFW    F.NAME,F.FNDI,F.FNDO    ;  File handler
        DEFW    0,0,0                   ;  End of list marker


C.NAME  DEFB    "**"                    ;  Name of console device
F.NAME  DEFB    ""                      ;  Default handler
        LAYOUT
        ALIGN

        DEFW    0                       ;  End of global list
        DEFW    G.SARD,SARD             ;  Entry of SARDCH
        DEFW    G.SAWR,SAWR             ;  Entry of SAWRCH
        DEFW    G.INIO,INIO             ;  Entry of INITIO
        DEFW    G.OSRD,OSRD             ;  Entry of OSRDCH
        DEFW    G.OSWR,OSWR             ;  Entry of OSWRCH
        DEFW    G.OSCL,OSCL             ;  Entry of OSCLI
        DEFW    G.IOLS,IOLS             ;  Address of IOLIST
        DEFW    G.MAXG                  ;  HRG
        LAYOUT
INITIOE END


