home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / OSBORNE / OSBZMP.ARK / ZMOOS01.Z80 < prev    next >
Text File  |  1989-09-27  |  19KB  |  791 lines

  1. ;    OSBORNE 1 Overlay for ZMP (Z-Modem Program)
  2.  
  3. ;    Name    ZMOOS01.Z80
  4. ;    Dated   20 NOV 1990
  5.  
  6. ;    Written by -
  7. ;      Klaus Schauer
  8. ;      Auf den Kempen 31
  9. ;      4052 Korschenbroich 2
  10. ;      Germany (West) 
  11.  
  12. ; global informations
  13.  
  14. ; set baud rate to 300, 600, 1200 or 2400
  15.  
  16. ; The  OSBORNE  1 switchs between 300/1200 and 600/1200  Baud  with
  17. ; software.  If  you  would use three or four baud rates you  must
  18. ; build in a hardware switch. See OSBORNE 1 technical notes.
  19. ; I  made  an  hardware extention for the MODEM  port  that  switch
  20. ; between the four baud rate.
  21. ; Also it generate an correct RS-232 interface.
  22. ; NOTE:  The  extention works with TRANS-MODEM 2400 or modems  with
  23. ; the INTEL Modem Chip Set 89024. For other modems: it is nessecary
  24. ; that  the  modem  send HS (PIN 12) for a short  time  after  the
  25. ; command ATZ from the OSBORNE 1.
  26.  
  27. ; using the MODEM port
  28.  
  29. ; To use the  MODEM port  an  hardware  extention  is  needed.
  30. ; Contact  me  for  the schematics and layout.
  31. ; BREAK, drops  RTS (used for DISCONNECT) and the  automatic  baud
  32. ; selection (300, 600, 1200, 2400 bps) are only available on the MODEM
  33. ; port.
  34.  
  35. ; global constants
  36.  
  37. false    equ    0
  38. true    equ    not false
  39.  
  40. LF    equ    0Ah        ; Linefeed
  41. CR    equ    0Dh        ; Carriage Return
  42. CLRSCR    equ    1Ah        ; Clear Screen
  43. ESC    equ    1Bh        ; Escape
  44. ctrlq    equ    11h
  45.  
  46. ; BDOS constants
  47.  
  48. CONOUT    equ    2        ; Console Char Out    
  49. INOUT    equ    6        ; Direct Input/Output
  50.  
  51. brkbit    equ    01100000b    ; bits to set to send break
  52.  
  53. ; User-set variables 
  54.  
  55. clkspd    equ    4        ; Processor clock speed in MHz
  56. debug    equ    false        ; to allow debugging of overlay with Z8E etc.
  57.  
  58. overdrive    equ    'A'    ; Drive to find overlay files on ('A'-'P')
  59. overuser    equ    0    ; User area to find files
  60.  
  61. ; NOT user-set variables
  62.  
  63. boot    equ    0000        ; CP/M Boot address
  64. jtabl    equ    boot+1         ; CP/M Jump Table address
  65. bdos    equ    0005
  66. mspeed    equ    003Ch        ; location of current baud rate. 
  67. tpa    equ    0100h
  68. start    equ    010Bh        ; ZMP's start address
  69. userdef    equ    0145h        ; origin of this overlay
  70.                 ; This address should not change with
  71.                 ; subsequent revisions.
  72. ovsize    equ    0400h        ; max size of this overlay
  73.  
  74. mdctlp    equ    2A00h        ; Status Register for Serial Port
  75. mddatp    equ    mdctlp+1    ; Data Register for Serial Port
  76. curs    equ    0EF5Ah        ; CBIOS addr for current cursor position
  77.                 ;  (curs+1)  (curs)
  78.                 ;  -------- --------
  79.                 ;  1111RRRR RCCCCCCC    R = row, C = column
  80.  
  81.     .z80            ; use z80 code
  82.     aseg            ; absolute
  83.  
  84.     org    tpa        
  85.     jp    initmd        ;init the modem routines
  86.  
  87.      if    debug
  88.     org    100h        ; so you can debug it with cebug, zsid, etc
  89.      else
  90.     org    userdef
  91.      endif
  92.  
  93. codebgn    equ    $
  94.  
  95. ;Jump table for the overlay: do NOT change this
  96. jump_tab:
  97.     jp    scrnpr        ; screen print
  98.     jp    mrd        ; modem read with timeout
  99. mchin:    jp    $-$        ; get a character from modem
  100.                 ; patched to OSIN by INITMD
  101. mchout:    jp    $-$        ; send a character to the modem
  102.                 ; patched to OSOUT by INITMD
  103.     jp    mordy        ; test for tx buffer empty
  104.     jp    mirdy        ; test for character received
  105.     jp    sndbrk        ; send break
  106.     jp    cursadd        ; cursor addressing
  107.     jp    cls        ; clear screen
  108.     jp    invon        ; inverse video on
  109.     jp    invoff        ; inverse video off
  110.     jp    hide        ; hide cursor
  111.     jp    show        ; show cursor
  112.     jp    savecu        ; save cursor position
  113.     jp    rescu        ; restore cursor position
  114.     jp    mint        ; service modem interrupt
  115.     jp    invec        ; initialise interrupt vectors
  116.     jp    dinvec        ; de-initialise interrupt vectors
  117.     jp    mdmerr        ; test uart flags for error
  118.     jp    dtron        ; turn DTR on
  119.     jp    dtroff        ; turn DTR OFF
  120.     jp    init        ; initialise uart
  121.     jp    wait        ; wait seconds
  122.     jp    mswait        ; wait milliseconds
  123.     jp    userin        ; user-defined entry routine
  124.     jp    userout        ; user-defined exit routine
  125.     jp    getvars        ; get system variables
  126.     jp    setport        ; set port (0 or 1)
  127.  
  128. ; Spare jumps for compatibility with future versions
  129.     jp    spare        ; spare for later use
  130.     jp    spare        ; spare for later use
  131.     jp    spare        ; spare for later use
  132.     jp    spare        ; spare for later use
  133.     jp    spare        ; spare for later use
  134.     jp    spare        ; spare for later use
  135.  
  136.  
  137. ; Main code starts here
  138.  
  139. ; Overlay data
  140.  
  141. modctb:    DEFB    15H        ; Modem control byte
  142.                 ; MODEM port 8N1
  143.                 ; 16H = 300 bps / 600 bps
  144.                 ; 15H = 1200 bps / 2400 bps
  145.                 ; RS-232 port (V.24) 8N1
  146.                 ; 56H = 300 bps / 600 bps
  147.                 ; 55H = 1200 bps / 2400 bps    
  148. port:    ds    1        ; (port) = 0: Modem port active
  149.                 ; (port) = 1: RS-232 port active    
  150.  
  151. ; Init modem port routines before running ZMP
  152.  
  153. initmd:    LD    HL,(BDOS+1)    ; FIND START OF BDOS
  154.     LD    DE,-0100H    ; GO TO FIRST PAGE AHEAD OF BDOS
  155.     ADD    HL,DE        ; HL NOW POSITIONED ONE PAGE BELOW BDOS
  156.     PUSH    HL        ; SAVE THE ADDRESS
  157.     LD    DE,BDJ        ; POINT TO OUR ROUTINE TO PUT THERE
  158.     LD    BC,CDLEN+2    ; SET LENGTH OF CODE
  159.     EX    DE,HL
  160.     LDIR            ; copy BDJ:, OSIN:, OSOUT: and OSTAT
  161.                 ; under BDOS. These routines must in a memory 
  162.                 ; location above 4000h
  163.     LD    HL,(BDOS+1)    ; GET BDOS ADDRESS BACK ONCE MORE
  164.     POP    DE        ; GET THE STARTING ADDRESS OFF STACK
  165.     PUSH    DE        ; PUT IT BACK ON THE STACK
  166.     INC    DE        ; POINT TO ADDRESS POSITION
  167.     EX    DE,HL        ; PUT INTO 'HL'
  168.     LD    (HL),E        ; STORE 'LSP' ADDRESS
  169.     INC    HL        ; GET 'LSP' LOCATION
  170.     LD    (HL),D        ; STORE 'MSP' ADDRESS
  171.     POP    HL        ; GET THE ADDRESS BACK ONCE MORE
  172.     LD    (BDOS+1),HL    ; NEW ADDRESS TO PROTECT FOR OVERWRITE
  173.  
  174.     LD    DE,OSIN-BDJ    ; GET THE LENGTH OF ROUTINE TO MOVE
  175.     ADD    HL,DE        ; COMUTE ADDRESS OF THE 'OSIN' ROUTINE
  176.     LD    (mchin+1),HL    ; PATCH CALL FOR "GET CHAR." ROUTINE
  177.  
  178.     LD    DE,OSOUT-OSIN
  179.     ADD    HL,DE
  180.     LD    (mchout+1),HL    ; PATCH jump to "SEND CHAR." ROUTINE
  181.  
  182.     LD    DE,osout1-OSOUT
  183.     ADD    HL,DE
  184.     LD    (smcall+1),HL    ; PATCH jump to "SEND CHAR." ROUTINE
  185.  
  186.     LD    DE,OSTAT-OSOUT1
  187.     ADD    HL,DE
  188.     LD    (mordy+1),HL    ; PATCH CALL FOR "GET STATUS" ROUTINE
  189.     ld    (mirdy+1),HL
  190.     ld    (mdmerr+1),HL
  191.     ld    (smsend+1),HL
  192.     JP    START        ; Run ZMP
  193.  
  194. ;Screen print function
  195. scrnpr:
  196.     ret
  197. spare:
  198.     ret
  199.  
  200. ; User-defined entry routine: leave empty if not needed
  201. userin:
  202.     ret
  203.  
  204. ; User-defined exit routine: leave empty if not needed
  205. userout:
  206.     ret
  207.  
  208. ;Test for output ready: return TRUE (1) in HL if ok
  209.  
  210. mordy:    call    $-$        ; get port status
  211.                 ; patched to OSTAT by INITMD
  212.     and    00000010b    ; extract bit 1
  213.     rrca            ; move bit 1 in bit 0
  214.     ld    l,a
  215.     ld    h,0
  216.     or    a        ; set/clear Z-flag
  217.     ret
  218.  
  219. ;Test for character at modem: return TRUE (1) in HL if so
  220.  
  221. mirdy:    call    $-$        ; get port status
  222.                 ; patched to OSTAT by INITMD
  223.     and    00000001b    ; extract bit 0
  224.     ld    l,a
  225.     ld    h,0
  226.     or    a        ; set/clear Z-flag
  227.     ret
  228.  
  229. ;Send a BREAK to the modem
  230.  
  231. sndbrk:    ld    a,(port)
  232.     or    a
  233.     jr    nz,nobrk    ; jump if Port B is active (RS-232)
  234.     ld    a,(modctb)    ; load Modem Control Byte
  235.     or    brkbit        ; set Break bits
  236.     call    oset
  237.     ld    hl,300        ; wait 300 mS
  238.     call    waitms
  239.     ld    a,(modctb)
  240.     jp    oset
  241.  
  242. nobrk:    call    print        ; no Break on RS-232 port
  243.     CR,LF,'No ',0
  244.     ret
  245.  
  246. ;Test UART flags for error: return TRUE (1) in HL if error.
  247.  
  248. mdmerr:    call    $-$        ; get port status
  249.                 ; patched to OSTAT by INITMD
  250.     and    01110000b    ; extract error bits
  251.                 ; bit 4: Framing Error (FE)
  252.                 ; bit 5: Receiver Overrun (OVRN)
  253.                 ; bit 6: Parity Error (PE)
  254.     ld    h,0
  255.     ld    l,0
  256.     ret    z        ; return if no error (Z-flag = High)
  257.     ld    l,1
  258.     ret            ; return with error (Z-flag = Low)
  259.  
  260. ;Turn DTR ON
  261.  
  262. dtron:    ld    a,(port)
  263.     or    a
  264.     ret    nz        ; return if Port B is selected (RS-232)
  265.                 ; RS-232 port only active if /RTS = high
  266.     ld    a,(modctb)
  267.     res    6,a        ; 6850 ACIA's /RTS = low 
  268.     jp    oset 
  269.  
  270. ;Turn DTR OFF
  271.  
  272. dtroff: ld    a,(modctb)
  273.     set    6,a        ; 6850 ACIA's /RTS = high
  274.     jp    oset
  275.  
  276. ;Initialise the uart
  277.  
  278. init:    ld    hl,2        ; get parameters
  279.     add    hl,sp
  280.     ex    de,hl
  281.     call    getparm        ; in HL
  282.     ld    (brate),hl    ; baud rate
  283.     call    getparm
  284.     ld    (parity),hl    ; parity
  285.     call    getparm
  286.     ld    (data),hl    ; data bits (BINARY 7 or 8)
  287.     call    getparm
  288.     ld    (stop),hl    ; stop bits (BINARY 1 or 2)
  289.  
  290.     ld    a,(data)    ; load data bits
  291.     cp    7        ; seven data bits ?
  292.     ld    c,0
  293.     jr    z,data7
  294.     set    4,c        ; set data length to 8
  295.     ld    a,(parity)    ; load parity 
  296.     cp    'N'        ; no parity ?
  297.     jr    nz,par1
  298.     ld    a,(stop)    ; load stop bits
  299.     cp    1        ; one stop bit ?
  300.     jr    nz,sbaud    ; control byte now: xxx100xxb (8N2)
  301.     set    2,c
  302.     jr    sbaud        ; control byte now: xxx101xxb (8N1)
  303.  
  304. par1:    cp    'O'        ; odd parity ?
  305.     jr    nz,par2
  306.     set    2,c        ; set odd parity
  307. par2:    ld    a,(stop)    ; load stop bits
  308.     cp    1        ; one stop bit ?
  309.     jp    nz,seterr    ; print Error: (8E2) and (8O2) not supported
  310.     set    3,c
  311.     jr    sbaud        ; control byte now: xxx110xxb (8E1)
  312.                 ;        or: xxx111xxb (8O1)
  313. data7:    ld    a,(stop)    ; load stop bits
  314.     cp    1        ; one stop bit ?
  315.     jr    nz,par3        ; jump if two stop bits
  316.     set    3,c        ; set one stop bit
  317. par3:    ld    a,(parity)    ; load parity
  318.     cp    'N'        ; no parity ?
  319.     jp    z,seterr    ; print Error: (7N1) and (7N2) not supported
  320.     cp    'O'        ; odd parity ?
  321.     jr    nz,sbaud    ; jump if even parity
  322.                 ; control byte now: xxx000xxb (7E2)
  323.                 ;        or: xxx010xxb (7E1)
  324.     set    2,c        ; set odd parity
  325.                 ; control byte now: xxx001xxb (7O2)
  326.                 ;        or: xxx011xxb (7O1)
  327. sbaud:    ld    a,(port)
  328.     or    a
  329.     ld    a,(brate)
  330.     jp    z,nbaud        ; jump if port A is selected
  331.  
  332. ; set baud rate on RS-232 port
  333. ; user must toggle 300 <> 600 and 1200 <> 2400 bps with hardware switch
  334.  
  335.     ld    e,a        ; set baud rate
  336.     ld    d,0
  337.     ld    hl,bratev    ; load bratev address in HL
  338.     add    hl,de        ; add (brate): HL pointed to baud code
  339.     ld    a,(hl)        ; baud rate bits in A, A = 0 if not supp.
  340.     or    a    
  341.     ret    z        ; return with Error: baud rate not supported
  342.     ld    b,a
  343.     ld    a,(modctb)
  344.     and    11100000b    ; strip out baud rate data, parity and
  345.                 ; stop bits
  346.     or    c        ; set data, parity and stop bits
  347.     or    b        ; set baud rate bits
  348.     ld    (modctb),a
  349.     call    oset        ; send new status byte to the serial port
  350.     ld    a,(brate)    ; load mspeed with the current brate value
  351.     ld    (mspeed),a    ; if the new rate is valid. 
  352.                 ; See table of values below.
  353.     ret
  354.  
  355. seterr:    call    print
  356.     db    ' ## Entry Error ##',0
  357.     ld    hl,2
  358.     call    waithls
  359.     ret
  360.  
  361. smres:    db    'ATZ',CR,0
  362. smdp1:    db    'AT&P1',CR,0
  363.  
  364. stop:    dw    1        ; stop bits
  365. parity:    dw    'N'        ; parity
  366. data:    dw    8        ; data bits
  367. brate:    dw    6        ; baud rate
  368.  
  369. ;Values of brate for each baud rate
  370. ;
  371. ; baud rate    brate
  372. ;
  373. bratev:    db    0        ;   110         0
  374.     db    00000010b    ;   300         1
  375.     db    0        ;   450         2
  376.     db    00000010b    ;   600         3
  377.     db    0        ;   710         4
  378.     db    00000001b    ;  1200         5
  379.     db    00000001b    ;  2400         6
  380.     db    0        ;  4800         7
  381.     db    0        ;  9600         8
  382.     db    0        ; 19200         9
  383.     db    0        ; 38400        10
  384.     db    0        ; 57600         11
  385.     db    0        ; 76800         12
  386.  
  387. ; set baud rate an Modem port (with hardware extention) 
  388.  
  389. nbaud:    LD    HL,MSPEED    ; HL = mspeed 
  390.     CP    (HL)        ; ? (brate) = (MSPEED)
  391.     jp    Z,stend        ; if equeal return
  392.     CP    1        ; 300 bps ?
  393.     JR    Z,OK300
  394.     cp    3        ; 600 bps ?
  395.     jr    z,ok600
  396.     CP    5        ; 1200 bps ?
  397.     JR    Z,OK1200
  398.     CP    6        ; 2400 bps ?
  399.     JR    Z,OK2400
  400.     XOR    A        ; Entry error, clear A and flags
  401.     or    a        ; set Z-flag, ZMP prints Error message
  402.     RET
  403.  
  404. OK2400:    CALL    ST2400
  405.     JP    STBAUD
  406.  
  407. OK300:    CALL    ST2400
  408.     CALL    ST300
  409.     CALL    PAUSE        ; pause
  410.     JP    STBAUD
  411.  
  412. ok600:    call    st2400
  413.     LD    A,(MODCTB)    ; Last 6850 control byte
  414.     and    11111100b    ; strip out baud rate bits
  415.     or    00000010b    ; set baud rate bits to 300 bps
  416.     LD    (MODCTB),A    ; set new baud rate
  417.     CALL    OSET        ; set OSBORNE 1 to 600 bps
  418.     CALL    PAUSE        ; pause    
  419.     jp    stbaud
  420.  
  421. OK1200:    CALL    ST2400
  422.     CALL    ST300
  423.     LD    A,(MODCTB)    ; Last 6850 control byte
  424.     and    11111100b    ; strip out baud rate bits
  425.     or    00000001b    ; set baud rate bits to 1200 bps
  426.     LD    (MODCTB),A    ; set new baud rate
  427.     CALL    OSET        ; set OSBORNE 1 to 1200 bps
  428.     CALL    PAUSE        ; pause    
  429.                 ; fall in STBAUD
  430. STBAUD:    CALL    MODP1        ; set puls dialing mode
  431. stend:    xor    a        ; clear A and flags
  432.     LD    A,(brate)
  433.     RET
  434.  
  435. ST2400:    LD    (MSPEED),A    ; save new baud rate
  436.     LD    A,(MODCTB)    ; Last 6850 control byte
  437.     and    11100000b    ; strip out baud rate data, parity and
  438.                 ; stop bits
  439.     or    c        ; set data, parity and stop bits
  440.     or    00000001b    ; set baud rate bits to 1200 bps
  441.     LD    (MODCTB),A    ; set new baud rate
  442.     CALL    OSET        ; set OSBORNE 1 to 1200 bps
  443.     CALL    MDRES        ; first modem reset + pause
  444.     JP    MDRES        ; second modem reset
  445.                 ; set OSBORNE 1 to 2400 bps (hardware switch) 
  446.  
  447. ST300:    LD    A,(MODCTB)    ; Last 6850 control byte
  448.     and    11111100b    ; strip out baud rate bits
  449.     or    00000010b    ; set baud rate bits to 300 bps
  450.     LD    (MODCTB),A    ; set new baud rate
  451.     CALL    OSET        ; set OSBORNE 1 to 300 bps
  452.                 ; fall in modem reset + pause
  453.  
  454. MDRES:    LD    HL,SMRES    ; modem reset (send ATZ to modem)
  455.     CALL    SMSEND
  456.                 ; fall in PAUSE
  457. PAUSE:    LD    hl,1500        ; wait 1500 ms (1.5 sec)
  458.     jp    waitms        ; and return
  459.  
  460. MODP1:    LD    HL,SMDP1    ; send AT&P1 to Modem
  461.     CALL    SMSEND
  462.     JP    PAUSE        ; pause
  463.  
  464. ; Smartmodem utility routine: send string to modem
  465.  
  466. SMSEND:    CALL    $-$        ; get port status
  467.     bit    1,a        ; test flag Transmit Data Reg. Empty (TDRE)
  468.     JR    Z,smsend    ; wait for modem send ready
  469.     LD    A,(HL)        ; FETCH NEXT CHARACTER
  470.     INC    HL
  471.     OR    A        ; END?
  472.     RET    Z        ; DONE IF SO
  473. smcall:    CALL    $-$        ; send char to serial port
  474.                 ; patched to OSOUT1 by INITMD
  475.     JR    SMSEND
  476.  
  477. setport:
  478.     ld    hl,2        ; get port number
  479.     add    hl,sp
  480.     ex    de,hl
  481.     call    getparm        ; in HL (values are 0 and 1)
  482.     ld    a,l
  483.     ld    (port),a
  484.     or    a
  485.     ld    a,(modctb)
  486.     jr    nz, v24        ; jump if port 1 requested
  487.     res    6,a        ; 6850 ACIA's /RTS = low: Modem port active
  488.     ld    (modctb),a
  489.     jp    oset
  490.  
  491. v24:    set    6,a        ; 6850 ACIA's /RTS = high: RS-232 port active
  492.     ld    (modctb),a
  493.     jp    oset
  494.  
  495. ;Video terminal sequences
  496.  
  497. ;Cursor addressing
  498.  
  499. cursadd:
  500.     ld    hl,2        ; get parameters
  501.     add    hl,sp
  502.     ex    de,hl
  503.     call    getparm        ; in HL
  504.     ld    (row),hl    ; row
  505.     call    getparm
  506.     ld    (col),hl    ; column
  507.     ld    a,ESC
  508.     call    cout
  509.     ld    a,'='
  510.     call    cout
  511.     ld    a,(row)        ; row first
  512.     add    a,' '        ; add offset
  513.     call    cout
  514.     ld    a,(col)        ; sane for column
  515.     add    a,' '
  516.     jp    cout        ; print column and return
  517.  
  518. row:    ds    2        ; row
  519. col:    ds    2        ; column
  520.  
  521. ;Clear screen
  522.  
  523. cls:    ld    a,CLRSCR
  524.     jp    cout        ; clear screen and return
  525.  
  526. ;Dim video
  527.  
  528. invon:    ld    a,ESC
  529.     call    cout
  530.     ld    a,')'
  531.     jp    cout        ; print and return
  532.  
  533. ;Bright video
  534.  
  535. invoff:    ld    a,ESC
  536.     call    cout
  537.     ld    a,'('
  538.     jp    cout        ; print and return
  539.  
  540. ;Turn off cursor:
  541.  
  542. hide:    ret
  543.  
  544. ;Turn on cursor:
  545.  
  546. show:    ret
  547.  
  548. ;Save cursor position:
  549.  
  550. savecu:    LD    HL,(CURS)    ; load curent cursor position
  551.                 ;    H          L    
  552.                 ; -------- --------
  553.                 ; 1111RRRR RCCCCCCC  R=row, C=column
  554.     LD    A,H
  555.     AND    0FH        ; Strip out bits 4-7
  556.     OR    A        ; Clear C-flag
  557.     RL    L        ; Bit 7 in C-flag, bit 0 = 0
  558.     RLA            ; Now bit 7 from L in bit 0
  559.     RRC    L        ; L = 0CCCCCCC    C=column
  560.     LD    H,A        ; H = 000RRRRR    R=row
  561.     LD    (ccurs),HL    ; Store curent cursor position in CCURS
  562.     ret
  563.  
  564. ccurs:     db    0,0        ; saved cursur position
  565.                 ; (ccurs) = column position
  566.                 ; (ccurs+1) = row position
  567.  
  568. ;Restore cursor position:
  569.  
  570. rescu:    ld    a,ESC
  571.     call    cout
  572.     ld    a,'='
  573.     call    cout
  574.     ld    a,(ccurs+1)    ; row first
  575.     add    a,' '        ; add offset
  576.     call    cout
  577.     ld    a,(ccurs)    ; sane for column
  578.     add    a,' '
  579.     jp    cout        ; print column and return
  580.  
  581. ;Service modem interrupt:
  582.  
  583. mint:    ret            ; my system doesn't need this
  584.  
  585. ;Initialise interrupt vectors:
  586.  
  587. invec:    ret            ; ditto
  588.  
  589. ;De-initialise interrupt vectors:
  590.  
  591. dinvec:    ret            ; ditto
  592.  
  593. ; End of user-defined code
  594. ; Do not change anything below here.
  595.  
  596. ;Modem character test for 100 ms
  597.  
  598. mrd:    push    bc        ; save bc
  599.     ld    bc,100        ; set limit
  600. mrd1:
  601.     call    mirdy        ; char at modem?
  602.     jr    nz,mrd2        ; yes, exit
  603.     ld    hl,1        ; else wait 1ms
  604.     call    waitms
  605.     dec    bc        ; loop till done
  606.     ld    a,b
  607.     or    c
  608.     jr    nz,mrd1
  609.     ld    hl,0        ; none there, result=0
  610.     xor    a
  611. mrd2:
  612.     pop    bc
  613.     ret
  614.  
  615. ; Inline print routine: destroys A and HL
  616.  
  617. print:
  618.     ex    (sp),hl        ; get address of string
  619. ploop:
  620.     ld    a,(hl)        ; get next
  621.     inc    hl        ; bump pointer
  622.     or    a        ; done if zero
  623.     jr    z,pdone
  624.     call    cout        ; else print
  625.     jr    ploop        ; and loop
  626. pdone:
  627.     ex    (sp),hl        ; restore return address
  628.     ret            ; and quit
  629.  
  630. ;
  631. ;Output a character in A to the console
  632. ;
  633. cout:
  634.     push    bc        ; save regs
  635.     push    de
  636.     push    hl
  637.     ld    e,a        ; character to E
  638.     ld    c,2
  639.     call    bdos        ; print it
  640.     pop    hl
  641.     pop    de
  642.     pop    bc
  643.     ret
  644.  
  645. ;Wait(seconds)
  646. wait:
  647.     ld    hl,2
  648.     add    hl,sp
  649.     ex    de,hl        ; get delay size
  650.     call    getparm
  651.                 ; fall thru to..
  652. ;Wait seconds in HL
  653. waithls:
  654.     push    bc        ; save bc
  655.     push    de        ; de
  656.     push    ix        ; and ix
  657.     ld    ix,0        ; then point ix to 0
  658.                 ; so we don't upset memory-mapped i/o
  659.  
  660. ;Calculate values for loop constants. Need to have two loops to avoid
  661. ;   16-bit overflow with clock speeds above 9 MHz.
  662.  
  663. outerval    equ    (clkspd / 10) + 1
  664. innerval    equ    (6667 / outerval) * clkspd
  665.  
  666. wait10:
  667.     ld    b,outerval
  668.  
  669. wait11:
  670.     ld    de,innerval
  671.  
  672. wait12:
  673.     bit    0,(ix)        ; time-wasters
  674.     bit    0,(ix)
  675.     bit    0,(ix)        ; 20 T-states each
  676.     bit    0,(ix)
  677.     bit    0,(ix)
  678.     bit    0,(ix)
  679.     dec    de
  680.     ld    a,e
  681.     ld    a,d
  682.     or    e
  683.     jr    nz,wait12    ; 150 T-states per inner loop
  684.     djnz    wait11        ; decrement outer loop
  685.     dec    hl        ; ok, decrement count in hl
  686.     ld    a,h
  687.     or    l
  688.     jr    nz,wait10
  689.     pop    ix        ; done -- restore ix
  690.     pop    de        ; de
  691.     pop    bc        ; and bc
  692.     ret
  693.  
  694. ;Wait milliseconds
  695. mswait:
  696.     ld    hl,2
  697.     add    hl,sp
  698.     ex    de,hl        ; get delay size
  699.     call    getparm
  700.                 ; fall thru to..
  701. ;Wait milliseconds in HL
  702. waitms:
  703.     push    de
  704. w1ms0:
  705.     ld    de,39 * clkspd
  706. w1ms1:
  707.     dec    de
  708.     ld    a,d
  709.     or    e
  710.     jr    nz,w1ms1
  711.     dec    hl
  712.     ld    a,h
  713.     or    l
  714.     jr    nz,w1ms0
  715.     pop    de
  716.     ret
  717.  
  718. ;Get next parameter from (de) into hl
  719. getparm:
  720.     ex    de,hl        ; get address into hl
  721.     ld    e,(hl)        ; get lo
  722.     inc    hl
  723.     ld    d,(hl)        ; then hi
  724.     inc    hl        ; bump for next
  725.     ex    de,hl        ; result in hl, address still in de
  726.     ret
  727.  
  728. ;Get address of user-defined variables
  729.  
  730. getvars:
  731.     ld    hl,uservars
  732.     ret
  733.  
  734. uservars:
  735.     dw    overdrive    ; .OVR etc. drive/user
  736.     dw    overuser
  737.  
  738. ; Osborne Serial Port Input/Output routines
  739.  
  740. ; stuff the control register on the 6850
  741.  
  742. OSET:    LD    C,A
  743.     LD    HL,(JTABL)    ; load BIOS+3 adress,  C = (MODCTB)
  744.     LD    L,3CH        ; SPECIAL OSBORNE ROUTINE (SBAUD: E13C)
  745.     JP    (HL)        ; BRANCH TO IT
  746.  
  747. ; ROUTINES THAT GET PLACED JUST UNDER 'BDOS' OVERLAYING 'CCP'
  748.  
  749. BDJ:    JP    $-$        ; THIS GETS PATCHED TO JUMP TO BDOS ENTRY
  750.  
  751. ;Get a character from the modem: return in HL
  752.  
  753. osin:    DI            ; DISABLE INTERRUPTS
  754.     OUT    (0),A        ; SWITCH TO ALTERNATE PAGE
  755.     LD    A,(MDDATP)    ; GET DATA BYTE
  756.     OUT    (1),A        ; SWITCH PAGES BACK
  757.     EI            ; RE-ENABLE INTERRUPTS
  758.     ld    l,a        ; put in HL
  759.     ld    h,0
  760.     or    a        ; set/clear Z
  761.     RET
  762.  
  763. ;Send a character to the modem
  764.  
  765. osout:    ld    hl,2        ; get the character
  766.     add    hl,sp
  767.     ld    a,(hl)
  768. osout1:    DI            ; DISABLE INTERRUPTS
  769.     OUT    (0),A        ; SWITDH TO ALTERNATE PAGE
  770.     LD    (MDDATP),A    ; SEND DATA BYTE
  771.     OUT    (1),A        ; SWITCH PAGES BACK
  772.     EI            ; RE-ENABLE INTERRUPTS
  773.     RET
  774.  
  775. ;Get status byte from the serial port
  776.  
  777. ostat:    DI            ; DISABLE INTERRUPTS
  778.     OUT    (0),A        ; SWITCH TO ALTERNATE PAGE
  779.     LD    A,(MDCTLP)    ; GET STATUS BYTE
  780.     OUT    (1),A        ; SWITCH PAGES BACK
  781.     EI            ; RE-ENABLE INTERRUPTS
  782.     RET
  783.  
  784. CDLEN    EQU    $-BDJ        ; LENGTH OF CODE TO COPY
  785.  
  786.      if    ($ - codebgn) gt ovsize
  787. toobig:    jp    errval        ; Overlay too large!
  788.      endif
  789.  
  790.     end
  791.