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