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 / ENTERPRS / CPM / UTILS / A / BIOSR4.ARC / CXIO.ASM < prev    next >
Assembly Source File  |  1987-04-26  |  24KB  |  1,279 lines

  1. ; code in this module was modified to set the screen up for 80 col 
  2. ; automaticly, all 40 column code has been deleted.  the label NULL40 is
  3. ; still maintained in the device table as removing it would change
  4. ; the subsequent device numbers, affecting the use of RS-232 (it would
  5. ; require rewrites of all modem programs)
  6. ; code at the label ?rlccp has been added to reset the feel and repeat
  7. ; rate at every warm start, this corrects problems that arise after 
  8. ; terminating a modem program. 
  9. ;
  10. ; Code has been added to allow setting the cursor flash rate and shape,
  11. ; set the temporary drive, and the drive search chain.
  12. ; Code has been added to require a password to be entered before the
  13. ; system finishes initialization, 3 trys are allowed, the system locks
  14. ; up if you fail all three.
  15. ;
  16. ; A label has been added to allow the 6551 init code to install baud
  17. ; rates based on the value in DEVTBL.
  18. ;
  19. ; User assumes _ALL_ liability for the use of this module. Original 
  20. ; Copyright is still maintained by Commodore
  21. ;
  22. ; Code to set cursor and drive chain; Copyright April 26, 1987 by
  23. ;    James W. Waltrip IV
  24. ;
  25.     title    'C128 BIOS, main I/O and sys functions    26 April 87'
  26.  
  27. ;
  28. ;    This module contains CXIO,CXINIT,CXMOVE and CXTIME.
  29. ;
  30.     maclib    cpm3
  31.  
  32.     maclib    z80
  33.  
  34.     maclib    cxequ
  35.  
  36.     maclib    modebaud
  37.  
  38. ;**********************************************************
  39.  
  40.     extrn    repeat            ; repeat rate
  41.  
  42. repeat$amt    equ    3
  43.  
  44.     extrn    delay            ; delay before repeat
  45.  
  46. delay$amt    equ    24
  47.  
  48.  
  49. printnum    equ    08        ; printer device to init
  50.                     ; other printer is 010h (16 decimal)
  51.  
  52. pass        equ    false        ; set to 'false' if password
  53.                      ;protection not wanted
  54.  
  55. pass$word    macro
  56.  
  57.     db    'PASS'                ; password is defined here
  58. ;                                       ; if using lower case letters
  59. ;                    ; use the HEX values rather than
  60. ;                    ; the characters themselves
  61. ;                    ; ie.-> 061h  instead of 'a'
  62.         endm
  63.  
  64. ;*************************************************************
  65.     public    ?init,?ldccp,?rlccp
  66.  
  67.     public    ?user,?di$int
  68.  
  69.     extrn    ?sysint
  70.  
  71. bdos    equ    5    
  72.     
  73.     extrn    @civec,@covec,@aivec,@aovec,@lovec
  74.     extrn     ?bnksl
  75.  
  76.     public    ?cinit,?ci,?co,?cist,?cost
  77.     public    @ctbl
  78.     extrn    ?kyscn
  79.  
  80. ; Utility routines in standard BIOS
  81.     extrn    ?wboot        ; warm boot vector
  82.     extrn    ?pmsg        ; print message @<HL> up to 00
  83.                 ; saves <BC> & <DE>
  84.     extrn    ?pdec        ; print binary number in <A> from 0 to 99.
  85.     extrn    ?pderr        ; print BIOS disk error header
  86.     extrn    ?conin,?cono    ; con in and out
  87.     extrn    ?const        ; get console status
  88.  
  89.     extrn    @hour,@min,@sec,@date,?bnksl
  90.     public    ?time
  91.  
  92.     page
  93. ;
  94. ;    keyboard scanning routine 
  95. ;
  96.     extrn    ?get$key,?int$cia
  97.     extrn    Fx$V$tbl
  98. ;
  99. ;    links to 80 column display
  100. ;
  101.     extrn    ?out80,?int80
  102.  
  103.     extrn    ?pt$i$1101,?pt$o$1,?pt$o$2
  104.  
  105. ;
  106. ;    bios8502 function routines
  107. ;
  108.     public    ?fun65
  109.  
  110. ;
  111. ;
  112. ;
  113.     public    X6551$baud
  114.     extrn    ?int65,?in65,?ins65,?out65
  115.     extrn    @drcha,@drchb,@drchc,@drchd,@tpdrv
  116.  
  117.  
  118.     DSEG
  119. ?fun65:
  120.     sta    vic$cmd            ; save the command passed in A
  121.  
  122. fun$di$wait:
  123.     lda    RS232$status
  124.     ani    01000010b        ; transmitting or receiving ?
  125.     jrnz    fun$di$wait        ; yes, wait for int to clean up
  126.     di
  127.     lda    force$map        ; get current MMU configuration
  128.     push    psw            ; save it
  129.     sta    io$0            ; make I/O 0 current
  130.     
  131.     lxi    d,1            ; D=0,  E=1
  132.     lxi    b,page$1$h
  133.     outp    d
  134.     dcr    c
  135.     outp    e            ; page 1, 0-1
  136.     dcr    c
  137.     outp    d
  138.     dcr    c
  139.     outp    d            ; page 0, 0-0
  140.     call    enable$6502+6        ; go run the 8502
  141.     mvi    c,low(page$1$h)
  142.     outp    e
  143.     dcr    c
  144.     outp    e            ; page 1, 1-1
  145.     dcr    c
  146.     outp    e
  147.     dcr    c
  148.     outp    d            ; page 0, 1-0
  149.  
  150.     pop    psw            ; recover the MMU config.
  151.     sta    force$map        ; restore it
  152.     ei                ; turn interrupts back on
  153.     lda    vic$data        ; get command results
  154.     ora    a            ; set the zero flag if A=0
  155.     ret
  156.  
  157. ?di$int:
  158.     push    psw
  159. di$int$1:
  160.     lda    RS232$status
  161.     ani    01000010b        ; transmitting or receiving ?
  162.     jrnz    di$int$1        ; yes, wait for int to clean up
  163.     pop    psw
  164.     di
  165.     ret
  166.  
  167.     page
  168. ;
  169. ;    set up the MMU for CP/M Plus
  170. ;
  171.     DSEG            ; init done from banked memory
  172. ?init:
  173.     mvi    a,3eh            ; force MMU into I/O space
  174.     sta    force$map        ;
  175.     lxi    h,mmu$table+11-1    ; table of 11 values
  176.     lxi    b,mmu$start+11-1    ; to to MMU registers
  177.     mvi    d,11            ; move all 11 bytes to the MMU
  178.  
  179. init$mmu$loop:
  180.     mov    a,m
  181.     outp    a
  182.     dcx    h
  183.     dcx    b
  184.     dcr    d
  185.     jrnz    init$mmu$loop
  186.  
  187.     mvi    a,1            ; enable track and sector status
  188.     sta    stat$enable        ; on the status line
  189.  
  190. ;    mvi    a,1h            ; no parity, 8 bits, 1 stop bit    
  191.     sta    XxD$config
  192.  
  193.     lxi    h,Fx$V$tbl
  194.     shld    key$FX$function
  195. ;*********************************************************
  196. ;
  197. ; install I/O assignments
  198. ;
  199.     lxi    h,4000h            ; 80 and 40 column drivers
  200.     shld    @covec
  201.     mvi    h,80h
  202.     shld    @civec            ; assign console input to keys
  203.     mvi    h,printnum        ; device # 4
  204.     shld    @lovec            ; assign printer to LPT:
  205.     mvi    h,00h
  206.     shld    @aivec
  207.     shld    @aovec            ; assign rdr/pun port
  208.  
  209. ;
  210. ; init SCB
  211. ;
  212.     mvi    a,4            ; The following instr. set up the
  213.     sta    @drcha            ; Drive Serch Chain, and the Temp. 
  214.     sta    @tpdrv            ; Drive.  This replaces the SETDEF
  215.     mvi    a,1            ; method of setting this up.
  216.     sta    @drchb
  217.     mvi    a,2
  218.     sta    @drchc
  219.     mvi    a,3
  220.     sta    @drchd
  221. ;
  222. ; Where are the bytes for COM/SUB execution?
  223. ;
  224. ; 80 Col. screen cursor attributes
  225. ;
  226.     lxi    b,0D600h    ; 80 col cmd reg
  227.     mvi    a,010        ; reg 10 of 8563 (cursor type, start scan line)
  228.     outp    a        ; tell 8563 you want reg 10
  229. lx1:                
  230.     inp    a        ; get status
  231.     jp    lx1        ; loop until status good
  232.     lxi    b,0D601h    ; 80 col data reg
  233.     mvi    a,01100011b    ; slow cursor, scan line 4 lines from top
  234.     outp    a
  235. ;
  236.     lxi    b,0D600h
  237.     mvi    a,011        ; reg 11 of 8563 (cursor end scan line)
  238.     outp    a
  239. lx2:
  240.     inp    a
  241.     jp    lx2
  242.     lxi    b,0D601h
  243.     mvi    a,00000101b    ; Scan line 5 lines from top
  244.     outp    a
  245.     lxi    b,0D011h    ; Vic controll reg 1
  246.     mvi    a,00001000b    ; turn off Vic
  247.     outp    a
  248. ;
  249.     page
  250. ;
  251. ; print sign on message
  252. ;
  253.     call    prt$msg            ; print signon message
  254.     db    'Z'-'@'            ; home and clear screen (to BG color)
  255.     db    esc,esc,esc,21h,esc,esc,esc,30    ; black back, white char
  256.     db    'Z'-'@'
  257.     db    esc,'=',32+2,32+37,'CP/M 3.0'
  258.     db    esc,'=',32+3,32+31,'On the Commodore 128 '
  259.     db    esc,'=',32+4,32+22,'6 Dec 85 System -*- Modified 26 Apr 87'
  260.     db    cr,lf,lf,lf,lf,0
  261. ;;*********************************************************
  262.     page
  263.  
  264. ;
  265. ;
  266.     mvi    a,-1            ; set block move to NORMAL mode
  267.     sta    source$bnk
  268. ;
  269. ;    install mode 2 page vectors
  270. ;
  271.     mvi    a,JMP
  272.     sta    INT$vector        ; install a JMP at vector location
  273.     lxi    h,?sysint
  274.     shld    INT$vector+1        ; install int$handler adr
  275. ;
  276. ; A software fix is  required for the lack of hardware to force the
  277. ; LSB of the INT vector to 0. If the bus floats INT VECT could be
  278. ; read as 0FFh; thus ADRh=I (I=0FCh) ADRl=FF for first read, and
  279. ; ADRh=I+1 ADRl=00 for second, to ensure that control is retained
  280. ; 0FD00h will also have FDh in it.
  281. ;
  282.     lxi    h,int$block        ; FC00h
  283.     lxi    d,int$block+1        ; FC01h
  284.     lxi    b,256-1+1        ; interrupt pointer block
  285.     mvi    m,INT$vector/256    ; high and low are equal (FD)
  286.     ldir
  287.     mvi    a,INT$block/256
  288.     stai                ; set interrupt page pointer
  289.     im2                ; enable mode 2 interrupts
  290.  
  291.     page
  292. ;
  293. ;
  294.     mvi    a,vicinit        ; null command just to setup BIOS8502
  295.     call    ?fun65
  296. ;
  297. ;
  298. ;
  299.     lda    sys$freq        ; 0=60Hz 0FFh=50Hz
  300.     ani    80h            ; 0=60Hz 080h=50Hz
  301.     mov    l,a            ; save in L
  302.     lxi    b,cia$1+0eh        ; point to CRA
  303.     inp    a            ; get old config
  304.     ani    7fh            ; clear freq bit
  305.     ora    l            ; add in new freq bit
  306.     outp    a            ; set new config
  307.  
  308.     mvi    c,8            ; start RTC
  309.     outp    a
  310.  
  311.     lxi    h,date$hex
  312.     shld    @date            ; set date to system data
  313.  
  314. ;
  315. ;    setup the sound variables
  316. ;
  317.     lhld    key$tbl
  318.     lxi    d,58*4
  319.     dad    d
  320.     mov    e,m
  321.     inx    h
  322.     mov    d,m
  323.     inx    h
  324.     xchg
  325.     shld    sound1            ; H=SID reg 24, L=SID reg 5
  326.     xchg
  327.     mov    e,m
  328.     inx    h
  329.     mov    d,m
  330.     xchg
  331.     shld    sound2            ; H=SID reg 6, L=SID reg 1
  332.     lxi    h,9
  333.     dad    d
  334.     mov    e,m
  335.     inx    h
  336.     mov    d,m
  337.     xchg
  338.     shld    sound3            ; H=SID reg 4 then L=SID reg 4 
  339. ;
  340. ;    set-up key click sound registers
  341. ;
  342.     lxi    b,sid+7
  343.     lxi    h,0040h
  344.     outp    l            ; (sid+7)=40h
  345.     inr    c
  346.     outp    l            ; (sid+8)=40h
  347.     mvi    c,low(sid+12)
  348.     outp    h            ; (sid+12)=0  Attack=2ms, Decay=6ms
  349.     inr    c
  350.     outp    h            ; (sid+13)=0  Sustain=0,  Release=6ms
  351.     mvi    a,6
  352.     sta    tick$vol        ; set keyclick volumn level
  353.  
  354. ;**********************************************
  355. ;  Password protection routine
  356. ;**********************************************
  357. ;
  358. if    pass
  359. ;
  360.     mvi    a,0
  361.     sta    count
  362. loop1:
  363.     lda    count
  364.     inr    a
  365.     sta    count
  366.     cpi    4
  367.     jnz    over
  368.     call    prt$msg
  369.     db    cr,lf,lf,esc,'G2','Password Error,  System Aborting....',0
  370. there:
  371.     jmp    there
  372. over:
  373.     lxi    h,cmp$string
  374.     push    h
  375.     call    prt$msg
  376.     db    cr,lf,'Password: ',0
  377. lz1:
  378.     call    key$board$in
  379.     pop    h
  380.     cmp    m
  381.     jnz    loop1
  382.     inx    h
  383.     push    h
  384.     mov    a,m
  385.     cpi    0
  386.     jnz    lz1
  387.     call    prt$msg
  388.     db    cr,lf,lf,0
  389. ;
  390. endif
  391. ;
  392.     ret
  393. ;
  394. if    pass
  395. ;
  396. cmp$string:
  397.     pass$word        ;password macro
  398.     db    0
  399. count:
  400.     ds    1
  401. ;
  402. endif
  403. ;
  404. ;***************************************************
  405. ;
  406.  
  407. mmu$table:
  408.     mmu$tbl$M
  409.  
  410.     page
  411. ;
  412. ;
  413. ;
  414.     CSEG
  415. prt$msg:
  416.     xthl
  417.     call    ?pmsg
  418.     xthl
  419.     ret
  420.  
  421.  
  422. ;
  423. ;    placed in common memory to keep IO from stepping on this code
  424. ;        always called from bank 0
  425. ;
  426.     CSEG
  427. read$d505:
  428.     sta    io$0            ; enable MMU (not RAM)
  429.     lxi    b,0d505h
  430.     inp    a            ; read 40/80 column screen
  431.     sta    bank$0            ; re-enable RAM
  432.     ret
  433.  
  434.     page
  435. ;
  436. ;
  437. ;
  438.     DSEG
  439. init$RS232:
  440.     di
  441.  
  442.     xra    a
  443.     sta    RS232$status
  444.     lxi    h,RxD$buf$count        ; clear the count
  445.     mvi    m,0
  446.     inr    l            ; point to RxD$buf$put
  447.     mvi    m,low(RxD$buffer)
  448.     inr    l            ; point to RxD$buf$get
  449.     mvi    m,low(RxD$buffer)
  450.     lxi    h,NTSC$baud$table
  451.  
  452. ;***************************************
  453. ; code to check for NTSC or PAL removed here, system now assumes 
  454. ; that you are using a north american 128 at 60 hz.
  455. ; ***************************************
  456.  
  457. use$NTSC:
  458.     lda    RS232$baud
  459.     cpi    baud$1200        ; baud rate less then 1200 baud
  460.     jrc    baud$ok            ; yes, go set it
  461.     mvi    a,baud$1200        ; no, 1200 baud is the max
  462.     sta    RS232$baud        ; (change to 1200 baud)
  463.  
  464. baud$ok:
  465.     mov    e,a
  466.     mvi    d,0
  467.     dad    d            ; +1X
  468.     dad    d            ; +1X
  469.     dad    d            ; +1X = +3X
  470.     mov    e,m
  471.     inx    h
  472.     mov    d,m
  473.     inx    h            ;
  474.     mov    a,m            ; get rate #
  475.     sta    int$rate        ;
  476.  
  477.     lxi    b,CIA1+timer$b$low    ;
  478.     outp    e            ;
  479.     inr    c            ; point to timer$b$high
  480.     outp    d            ;
  481.  
  482.     mvi    a,11h            ;
  483.     mvi    c,CIA$ctrl$b        ; turn on timer B
  484.     outp    a            ;
  485.  
  486.     lxi    b,CIA2+data$b        ; setup user port for RS232
  487.     inp    a            ; get old data
  488.     ori    6            ; set CTS and DTR
  489.     outp    a            ; update it
  490.     ei
  491.     ret
  492.  
  493.     page
  494. ;
  495. ;    NTSC rates (1.02273 MHz)
  496. ;
  497. NTSC$baud$table:
  498.     dw    6818            ; no baud rate     (6666.47)
  499.     db    1
  500.     dw    6818            ; 50    6666.7us (6666.47)
  501.     db    1
  502.     dw    4545            ; 75    4444.4us (4443.99)
  503.     db    1
  504.     dw    3099            ; 110    3030.3us (3030.13)
  505.     db    1
  506.     dw    2544            ; 134    2487.6us (2487.46)
  507.     db    1
  508.     dw    2273            ; 150    2222.2us (2222.48)
  509.     db    2
  510.     dw    1136            ; 300    1111.1us (1110.75)
  511.     db    3
  512.     dw    568            ; 600     555.6us ( 555.38)
  513.     db    6
  514.     dw    284            ; 1200     277.8us ( 277.69)
  515.     db    12
  516.  
  517. ;****************************************************
  518. ; PAL baud table removed from here (redundant, as it is not checked for
  519. ; or used)
  520. ;******************************************************
  521.  
  522.     page
  523. ;
  524. ;
  525. ;
  526. out$RS232:
  527.     lda    RS232$status
  528.     ani    80h
  529.     jrnz    out$RS232
  530.     mov    a,c
  531.     sta    xmit$data        ; get character to send in A
  532.     lxi    h,RS232$status
  533.     setb    7,m            ; set Xmit request bit
  534.     ret
  535.  
  536. ;
  537. ;
  538. ;
  539. out$st$RS232:
  540.     lda    RS232$status
  541.     ani    80h            ; bit 8 set if busy
  542.     xri    80h            ; A cleared if busy (=80h if not)
  543.     rz
  544.     ori    0ffh            ; A=ff if ready (not busy)
  545.     ret
  546.  
  547. ;
  548. ;
  549. ;
  550. in$RS232:
  551.     lda    RS232$status
  552.     ani    1
  553.     jrz    in$RS232
  554.     lda    recv$data
  555.     lxi    h,RS232$status
  556.     res    0,m
  557.     ret
  558.  
  559. ;
  560. ;
  561. ;
  562. in$st$RS232:
  563.     lda    RS232$status
  564.     ani    1
  565.     rz
  566.     ori    0ffh            ; set data ready (-1)
  567.     ret
  568.  
  569.     page
  570. ;
  571. ;    this routine is used to provide the user with a method
  572. ;    of interfacing with low level system functions
  573. ;
  574.     CSEG
  575. ;
  576. ;    input:
  577. ;        all registers except HL and A are passed to function
  578. ;
  579. ;    output:
  580. ;        all resisters from function are preserved
  581. ;
  582. ?user:
  583.     shld    user$hl$temp
  584.     xchg
  585.     shld    de$temp            ; save DE for called function
  586.  
  587.     mov    e,a            ; place function number in E
  588.     mvi    a,num$user$fun-1    ; last legal function number
  589.  
  590.     call    vector            ; function
  591. usr$tb:    dw    read$mem$0        ; 0
  592.     dw    write$mem$0        ; 1
  593.     dw    ?kyscn            ; 2
  594.     dw    do$rom$fun        ; 3  (L=function #)     
  595.     dw    do$6502$fun        ; 4  (L=function #)
  596.     dw    read$d505        ; 5  returns MMU reg in A
  597.     dw    code$error        ; not 0 to 5 ret version number in HL
  598.  
  599. num$user$fun    equ    ($-usr$tb)/2
  600.  
  601.     page
  602. ;
  603. ;    address in DE is read and returned in C
  604. ;    A=0 if no error
  605. ;
  606.     DSEG
  607. read$mem$0:
  608.     ldax    d            ; read location addressed by DE
  609.     mov    c,a            ; value returned in C
  610.     xra    a            ; clear error flag
  611.     ret
  612.  
  613. ;
  614. ;    address in DE is written to with value in C
  615. ;    A=0 if no errors
  616. ;
  617. write$mem$0:
  618.     mvi    a,-1            ; get error flag and 0ffh value
  619.     cmp    d            ; do not allow write from FF00 to FFFF
  620.                     ;   this is 8502 space, MMU direct reg.
  621.     rz
  622.     mov    a,d
  623.     cpi    10h            ; do not allow write from 0000 to 0FFF
  624.                     ;   this is ROM space
  625.     mvi    a,-1            ; get error flag
  626.     rc                ; return if 00h to 0fh
  627.     mov    a,c
  628.     stax    d
  629.     xra    a            ; clear error flag 
  630.     ret
  631.  
  632.     page
  633. ;
  634. ;    This is the function code entry point for direct execution
  635. ;    of driver functions. If the MSB of the function number is
  636. ;    set, the 40 column driver is used; else the 80 column drive 
  637. ;    is used.
  638. ;
  639. do$rom$fun:
  640.     lhld    user$hl$temp        ; get HL (L=fun #)
  641.  
  642.     mvi    a,7eh            ; only allow even functions
  643.     ana    l
  644.     cpi    79h
  645.     jrc    no$hl$req
  646.     lhld    @dma            ; HL will be passed in @dma by
  647.     push    h            ; ..the user
  648. no$hl$req:
  649.     mov    l,a
  650.     rst    5            ; call rom functon (RCALL) L=fun #    
  651.     ret
  652.  
  653. ;    mvi    a,7eh            ; only allow even functions
  654. ;    ana    l
  655. ;    sta    no$hl$req+1
  656. ;    cpi    79h
  657. ;    jrc    no$hl$req
  658. ;    lhld    @dma            ; HL will be passed in @dma by
  659. ;    push    h            ; ..the user
  660. ;no$hl$req:
  661. ;    will be changed to RCALL xx   RET for next release (ROM FN 7A, 7C
  662. ;        and 7E will not function with current code, they expect
  663. ;        a return address on the stack
  664. ;
  665. ;    RJMP    5Eh            ; unused function, real fun# installed
  666.                     ; ..above
  667.  
  668. do$6502$fun:
  669.     lhld    user$hl$temp
  670.     mov    a,l
  671.     jmp    ?fun65
  672. ;
  673. ;
  674. ;
  675. code$error:
  676.     lxi    h,date$hex
  677.     mvi    a,-1
  678.     ret
  679.  
  680.     page
  681. ;
  682. ;
  683. ;
  684.     CSEG
  685. ?rlccp:
  686. ;
  687. ;******************************************************************
  688.     mvi    a,01            ; sets feel, put here to set it
  689.     sta    0fd52h            ; on every warm start
  690.     mvi    a,repeat$amt        ; set at 3
  691.     sta    repeat
  692.     mvi    a,delay$amt        ; set at 24
  693.     sta    delay
  694. ;******************************************************************
  695.     lxi    h,ccp$buffer
  696.     lxi    b,0c80h
  697.  
  698. load$ccp:
  699.     sta    bank$0
  700.     mov    a,m
  701.     sta    bank$1
  702.     lxi    d,-ccp$buffer+100h
  703.     dad    d
  704.     mov    m,a
  705.     lxi    d,ccp$buffer-100h+1
  706.     dad    d
  707.     dcx    b
  708.     mov    a,b
  709.     ora    c
  710.     jrnz    load$ccp
  711.     ret
  712.  
  713.     page
  714. ;
  715. ;
  716. ;
  717.     CSEG
  718. ?ldccp:
  719.     xra    a
  720.     sta    ccp$fcb+15    ; zero extent
  721.     lxi    h,0
  722.     shld    fcb$nr        ; start at beginning of file
  723.     lxi    d,ccp$fcb
  724.     call    open        ; open file containing CCP
  725.     inr    a
  726.     jrz    no$CCP        ; error if no file...
  727.     lxi    d,0100h
  728.     call    setdma        ; start of TPA
  729.     lxi    d,128
  730.     call    setmulti    ; allow up to 16K bytes
  731.     lxi    d,ccp$fcb
  732.     call    read
  733.  
  734.     lxi    h,0100h
  735.     lxi    b,0c80h
  736.     lda    force$map
  737.     push    psw
  738.  
  739. ;
  740. ;
  741. save$ccp:
  742.     sta    bank$1
  743.     mov    a,m
  744.     sta    bank$0
  745.     lxi    d,ccp$buffer-100h
  746.     dad    d
  747.     mov    m,a
  748.     lxi    d,-ccp$buffer+100h+1
  749.     dad    d
  750.     dcx    b
  751.     mov    a,b
  752.     ora    c
  753.     jrnz    save$ccp
  754.  
  755.     pop    psw
  756.     sta    force$map
  757.     ret
  758.  
  759.  
  760.  
  761.     page 
  762. ;
  763. ;
  764. ;
  765. no$CCP:                ; here if we couldn't find the file
  766.     call    prtmsg        ; report this...
  767.     db    cr,lf,'BIOS Err on A: No CCP.COM file',0
  768.     call    ?conin        ; get a response
  769.     jr    ?ldccp        ; and try again
  770.  
  771.  
  772. ;
  773. ; CP/M BDOS Function Interfaces
  774. ;
  775.     CSEG
  776. open:
  777.     mvi    c,15        ; open file control block
  778.  
  779.     db    21h        ; lxi h,(mvi c,26)
  780. setdma:
  781.     mvi    c,26        ; set data transfer address
  782.  
  783.     db    21h        ; lxi h,(mvi c,44)    
  784. setmulti:
  785.     mvi    c,44        ; set record count
  786.  
  787.     db    21h        ; lxi h,(mvi c,20)
  788. read:
  789.     mvi    c,20        ; read records
  790.     jmp    bdos
  791.  
  792. ;               12345678901
  793. ccp$fcb        db    1,'CCP     COM',0,0,0
  794. fcb$rc        db    0
  795.         ds    16
  796. fcb$nr        db    0,0,0
  797.  
  798.  
  799.     page
  800. ;
  801. ;    CXIO.ASM and CXEM.ASM
  802. ;
  803. ;==========================================================
  804. ;        ROUITINE TO VECTOR TO HANDLER
  805. ;==========================================================
  806. ;    CP/M IO routines    b=device : c=output char : a=input char
  807. ;
  808.     CSEG
  809. ;*********************************************************************
  810. ; code in the following vector tables has been altered to null the 40
  811. ; column screen
  812. ;--------------------------------------------------
  813.  
  814. ?cinit:                ; initialize usarts
  815.     mov    b,c
  816.     call    vector$io    ; jump with table adr on stack
  817. number$drivers:
  818.     dw    ?int$cia    ; keys
  819.     dw    ?int80        ; 80col
  820.     dw    rret          ; 40col
  821.     dw    ?pt$i$1101    ; prt1
  822.     dw    ?pt$i$1101    ; prt2
  823.     dw    ?int65        ; 6551
  824.     dw    init$RS232    ; software RS232
  825.     dw    rret        ;
  826. max$devices    equ    (($-number$drivers)/2)-1
  827.  
  828. ;
  829. ;
  830. ;
  831. ?ci:                ; character input
  832.     call    vector$io    ; jump with table adr on stack
  833.     dw    key$board$in    ; keys
  834.     dw    rret        ; 80col
  835.     dw    rret        ; 40col
  836.     dw    rret        ; ptr1
  837.     dw    rret        ; prt2
  838.     dw    ?in65        ; 6551
  839.     dw    in$RS232    ; software RS232
  840.     dw    null$input
  841.  
  842. ;
  843. ;
  844. ;
  845. ?cist:                ; character input status
  846.     call    vector$io    ; jump with table adr on stack
  847.     dw    key$board$stat    ; keys
  848.     dw    rret        ; 80col
  849.     dw    rret        ; 40col
  850.     dw    rret        ; prt1
  851.     dw    rret        ; prt2
  852.     dw    ?ins65        ; 6551
  853.     dw    in$st$RS232    ; software RS232
  854.     dw    rret
  855.  
  856. ;
  857. ;
  858. ;
  859. ?co:                ; character output
  860.     call    vector$io    ; jump with table adr on stack
  861.     dw    rret        ; keys
  862.     dw    ?out80        ; 80col
  863.     dw    rret        ; 40col
  864.     dw    ?pt$o$1        ; prt1
  865.     dw    ?pt$o$2        ; prt2
  866.     dw    ?out65        ; 6551
  867.     dw    out$RS232    ; software RS232
  868.     dw    rret
  869.  
  870. ;
  871. ;
  872. ;
  873. ?cost:                ; character output status
  874.     call    vector$io    ; jump with table adr on stack
  875.     dw    ret$true    ; keys
  876.     dw    ret$true    ; 80col
  877.     dw    ret$true    ; 40col
  878.     dw    ret$true    ; prt1    ?pt$s$1101
  879.     dw    ret$true    ; prt2
  880.     dw    ret$true    ; 6551
  881.     dw    out$st$RS232    ; software RS232
  882.     dw    ret$true
  883.  
  884. ;************************************************************
  885.  
  886.     page
  887. ;
  888. ;    This entry does not care about values of DE
  889. ;
  890. vector$io:
  891.     mvi    a,max$devices    ; check for device # to high
  892.     mov    e,b        ; get devive # in E
  893. ;
  894. ;
  895. ;    INPUT:
  896. ;        Vector # in E, Max device in A
  897. ;        passes value in DE$TEMP in DE
  898. ;        HL has routine's address in it on entering routine
  899. ;
  900. ;    OUTPUT:
  901. ;        ALL registers of returning routine are passed
  902. ;
  903. vector:
  904.     pop    h        ; get address vector list
  905.     mvi    d,0        ; zero out the MSB
  906.     cmp    e        ; is it too high?
  907.     jrnc    exist        ; no, go get the handler address
  908.  
  909.     mov    e,a        ; yes, set to max$dev$handler(last one) 
  910. exist:
  911.     dad    d        ; 
  912.     dad    d        ; point into table
  913.  
  914.      mov    a,m
  915.     inx    h
  916.     mov    h,m
  917.     mov    l,a        ; get routine adr in HL
  918.  
  919.     shld    hl$temp        ; save exec adr
  920.     lxi    h,0
  921.     dad    sp
  922.     lxi    sp,bios$stack
  923.     push    h        ; save old stack
  924.  
  925.     lhld    de$temp
  926.     xchg
  927.     lhld    hl$temp        ; recover exec adr
  928.  
  929.     lda    force$map    ; get current bank
  930.     push    psw        
  931.     sta    bank$0        ; set bank 0 as current
  932.  
  933.     call    ipchl
  934.  
  935.     sta    a$temp        ; save value to return
  936.     pop    psw
  937.     sta    force$map    ; set old bank back
  938.     lda    a$temp        ; recover value to return
  939.  
  940.     shld    hl$temp
  941.     pop    h        ; recover old stack
  942.     sphl            ; set new stack
  943.     lhld    hl$temp
  944.     ret
  945.  
  946. ipchl:
  947.     pchl            ; jmp to handler
  948.  
  949.     ds    30h
  950. bios$stack:
  951.  
  952.  
  953.     page
  954. ;==========================================================
  955. ;        CHARACTER INPUT ROUTINES
  956. ;==========================================================
  957.  
  958.     DSEG
  959. ;
  960. ;
  961. ;
  962. key$board$in:
  963.     call    key$board$stat    ; test if key is available
  964.     jrz    key$board$in    
  965.  
  966.     lda    key$buf
  967.     push    psw        ; save on stack
  968.     xra    a        ; clear key 
  969.     sta    key$buf
  970.     pop    psw        ; recover current key
  971. rret:
  972.     ret
  973.  
  974. ;
  975. ;
  976. ;
  977. null$input:        ; return a ctl-Z for no device
  978.     mvi    a,1Ah
  979.     ret
  980.  
  981.  
  982.     page
  983.  
  984. ;==========================================================
  985. ;    CHARACTER DEVICE INPUT STATUS
  986. ;==========================================================
  987.  
  988.     DSEG
  989. ;
  990. ;
  991. ;
  992. key$board$stat:
  993.     lda    key$buf
  994.     ora    a
  995.     jrnz    ret$true
  996.  
  997.     call    ?get$key
  998.     ora    a        ; =0 if none
  999.     rz            ; return character not advailable
  1000.  
  1001.     sta    key$buf        ; was one, save in key buffer
  1002.  
  1003. ret$true:
  1004.     ori    0ffh        ; and return true
  1005.     ret
  1006.  
  1007.     page
  1008.  
  1009.     cseg
  1010. @ctbl
  1011.     db    'KEYBRD'    ; device 0, internal keyboard
  1012.     db    mb$input
  1013.     db    baud$none
  1014.  
  1015.     db    '80-COL'    ; device 1, 80 column display
  1016.     db    mb$output
  1017.     db    baud$none
  1018.  
  1019.     db    'NULL40'    ; device 2, 40 column display
  1020.     db    mb$output
  1021.     db    baud$none
  1022.  
  1023.     db    'PRT-LQ'    ; device 3, serial bus printer (device 4)
  1024.     db    mb$output
  1025.     db    baud$none
  1026.  
  1027.     db    'PRT-MX'    ; device 4, serial bus printer (device 5)
  1028.     db    mb$output
  1029.     db    baud$none
  1030.  
  1031.     db    '6551  '    ; device 5, EXT CRT
  1032.     db    mb$in$out+mb$serial+mb$softbaud+mb$xonxoff
  1033. X6551$baud:
  1034.     db    baud$9600
  1035.  
  1036.     db    'RS-232'    ; device 6, software RS232 device
  1037.     db    mb$in$out+mb$serial+mb$xonxoff+mb$softbaud
  1038. RS232$baud:
  1039.     db    baud$300
  1040.  
  1041.     db    0        ; mark end of table
  1042.  
  1043.     page
  1044. ;
  1045. ;    TIME.ASM
  1046. ;
  1047.     cseg
  1048. ;
  1049. ;    HL and DE must be presevered
  1050. ;
  1051. ?time:
  1052.     inr    c
  1053.     lxi    b,cia$hours
  1054.     jrz    set$time
  1055. ;
  1056. ;    update SCB time  (READ THE TIME)
  1057. ;
  1058.     inp    a            ; read HR (sets sign flag)
  1059.     jp    is$am            ; jmp if AM (positive)
  1060.     ani    7fh
  1061.     adi    12h            ; noon=24(PM), midnight=12(AM)
  1062.     daa
  1063.     cpi    24h            ; check for noon (12+12 PM)
  1064.     jrnz    set$hr
  1065.     mvi    a,12h
  1066.     jr    set$hr
  1067.  
  1068. is$am:
  1069.     cpi    12h            ; check for midnight (AM)
  1070.     jrnz    set$hr
  1071.     xra    a            ; becomes 00:00
  1072. set$hr:
  1073.     sta    @hour
  1074.     mov    b,a
  1075.     lda    old$hr
  1076.     mov    c,a
  1077.     mov    a,b
  1078.     sta    old$hr
  1079.     cmp    c            ; if @hour<old$hr
  1080.     jrnc    same$day
  1081.  
  1082.     push    h
  1083.     lhld    @date
  1084.     inx    h
  1085.     shld    @date
  1086.     pop    h
  1087.  
  1088. same$day:
  1089.     lxi    b,cia$hours-1
  1090.     inp    a            ; read MIN
  1091.     sta    @min
  1092.  
  1093.     dcr    c
  1094.     inp    a            ; read SEC
  1095.     sta    @sec
  1096.  
  1097.     dcr    c
  1098.     inp    a            ; read 1/10 of SEC (a must to free
  1099.     ret                ; the holding register)
  1100.  
  1101. old$hr:
  1102.     ds    1
  1103.     page
  1104. ;
  1105. ;
  1106. ;
  1107. set$time
  1108.     lda    @hour
  1109.     cpi    12h            ; test for noon
  1110.     jrz    set$as$is
  1111.     ana    a            ; test for 00:xx
  1112.     jrnz    not$zero$hundred
  1113.     mvi    a,80h+12h            ; set to midnight
  1114.     jr    set$as$is
  1115.  
  1116. not$zero$hundred:
  1117.      cpi    11h+1            ; test for 1 to 11 AM
  1118.     jrc    set$as$is
  1119.     sui    12h
  1120.     daa                ; decimal adjust
  1121. set$msb:
  1122.     ori    80h            ; set PM
  1123.  
  1124. set$as$is:
  1125.     outp    a
  1126.     dcr    c
  1127.     lda    @min
  1128.     outp    a
  1129.     dcr    c
  1130.     lda    @sec
  1131.     outp    a
  1132.     dcr    c
  1133.     xra    a
  1134.     outp    a
  1135.     ret
  1136.  
  1137.     page
  1138.  
  1139. ;
  1140.     page
  1141. ;
  1142. ; CXMOVE.ASM
  1143. ;
  1144.     public ?move,?xmove,?bank
  1145.  
  1146. ;
  1147. ;    Move a block of data from DE to HL
  1148. ;    count is in BC (within current bank)
  1149. ;
  1150. ;
  1151.     cseg            ; place code in common
  1152. ?move:
  1153.     xchg            ;*
  1154.     lda    source$bnk    ; =FFh if normal block move 
  1155.     inr    a        ; 
  1156.     jrnz    inter$bank$move
  1157.  
  1158.     LDIR            ;* do block move    
  1159.     xchg            ;*
  1160.     ret
  1161.  
  1162.  
  1163. ;
  1164. ;
  1165. ;
  1166. ?xmove:                ; can be in bank 0    
  1167.     mov    a,c
  1168.     sta    source$bnk
  1169.     mov    a,b
  1170.     sta    dest$bnk
  1171.     ret            ;*
  1172.  
  1173.     page
  1174. ;
  1175. ;
  1176. ;
  1177. inter$bank$move:
  1178.     shld    @buffer        ; save HL TEMP
  1179.     lxi    h,0
  1180.     dad    sp
  1181.     lxi    sp,bios$stack
  1182.     push    h        ; save old stack  ;**1
  1183.     lhld    @buffer
  1184.  
  1185.     mov    a,b        ; get msb of count
  1186.     ora    a
  1187.     jrz    count$less$than$256
  1188.  
  1189.     push    b        ; save the count  ;**2
  1190.     push    d        ; save the dest   ;**3
  1191.     lxi    d,@buffer    ; make buffer the dest
  1192.     lxi    b,256        ; move 256 bytes
  1193.     lda    source$bnk
  1194.     call    ?bank
  1195.     ldir            ; move source to buffer
  1196.  
  1197.     pop    d        ; recover dest    ;**2
  1198.     push    h        ; save updated source ;**3
  1199.     lxi    h,@buffer    ; make the buffer the source
  1200.     lxi    b,256        ; move 256 bytes
  1201.     lda    dest$bnk
  1202.     call    ?bank
  1203.     ldir            ; move buffer to dest
  1204.  
  1205.     pop    h        ; recover updated source ;**2
  1206.     pop    b        ; recover count          ;**1
  1207.     dcr    b        ; subtract 256 from count
  1208.     jr    inter$bank$move
  1209.  
  1210.     page
  1211. ;
  1212. ;
  1213. ;
  1214. count$less$than$256:
  1215.     ora    c        ; BC=0  [A (0) or'ed with C]
  1216.      jrz    exit$move
  1217.  
  1218.     push    d        ; save count for 2nd half  ;**2
  1219.     push    b        ; save dest adr            ;**3
  1220.     lxi    d,@buffer
  1221.     lda    source$bnk
  1222.     call    ?bank
  1223.     ldir            ; move source to buffer
  1224.  
  1225.     pop    b        ; recover count          ;**2
  1226.     pop    d        ; recover dest          ;**1
  1227.     push    h        ; save updated dest      ;**2
  1228.     lxi    h,@buffer
  1229.     lda    dest$bnk
  1230.     call    ?bank
  1231.     ldir            ; move buffer to dest
  1232.     pop    h                        ;**1
  1233.  
  1234. ;
  1235. ;
  1236. ;
  1237. exit$move:
  1238.     xchg
  1239.     mvi    a,-1
  1240.     sta    source$bnk    ; set MOVE back to normal
  1241.     lda    @cbnk
  1242.  
  1243.     shld    @buffer
  1244.     pop    h        ; recover old stack    ;**0
  1245.     sphl
  1246.     lhld    @buffer
  1247.  
  1248. ; call    ?bank        ; set current bank
  1249. ; ret
  1250.  
  1251.     page
  1252. ;
  1253. ;    switch bank to bank number in A
  1254. ;
  1255.     cseg            ; (must be in common)
  1256. ?bank:                
  1257.     ora    a        ; bank 0 ?
  1258.     jrnz    not$bank$0    ; go check for bank 1
  1259.  
  1260.     sta    bank$0        ; set bank 0
  1261.     ret
  1262.  
  1263. ;
  1264. ;
  1265. not$bank$0:
  1266.     dcr    a        ; bank 1 ?
  1267.     rnz            ; if not a valid bank just return
  1268.     sta    bank$1        ; set bank 1
  1269.     ret
  1270.  
  1271.     end
  1272. t
  1273.  
  1274. ;
  1275. ;
  1276. not$bank$0:
  1277.     dcr    a        ; bank 1 ?
  1278.     rnz            ; if not a valid ban