home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols200 / vol232 / bbcbios.mac < prev    next >
Encoding:
Text File  |  1994-07-13  |  13.1 KB  |  585 lines

  1. .Z80
  2. .COMMENT @
  3.  
  4. ***************************************************************
  5. *                                  *
  6. *    ---   Custom BIOS for CP/M 2.2   ---              *
  7. *                                  *
  8. * Version: 1.0                    28 0ct 1984.  *
  9. *                                  *
  10. * by                        Mark Little.  *
  11. *                                  *
  12. ***************************************************************
  13.  
  14.     Custom BIOS for the Ferguson Big Board I to allow
  15. auto-execution of commands on Cold Boot ONLY.
  16.  
  17. NOTE:
  18. -----
  19.     This has been implemented for a specific system which
  20. uses the parallel port for a Terminal. It also does not have
  21. a printer implemented. You will most likely have to modify
  22. the I/O jumps into the monitor and insert the printer setup in
  23. the Cold Boot routine. The listing of the CBIOS supplied with
  24. the system will show you how to do it. Also, the CBIOS supplied
  25. with the original system modifies the monitor code, preventing
  26. easy monitor modification. This version has eliminated that
  27. problem (without affecting operation).
  28.     The CBIOS uses a portion of the Monitor Work Area to
  29. store its variables and implement its stack. Normally the area
  30. used (0FF7CH - 0FFFFH) is unused once the monitor loses control
  31. and is free for use, so BEWARE if you have software that uses
  32. this area also.
  33.  
  34. INSTALLATION.
  35. -------------
  36.  
  37. (1)    Modify to suit your system.
  38. (2)    Assemble to produce a .HEX file
  39. (3)    DDT CPM60.COM (supplied on original CP/M diskette)
  40. (4)    ICBIOS.HEX (Identify File to use)
  41. (5)    R1E7D (Read in file with offset 1F80H-103H)
  42. (6)    ^C (Exit DDT with changing memory image)
  43. (7)    SYSGEN (RETURN with asked for Source Drive)
  44. (8)    Test your modifications.
  45. (9)    Place a copy of you modifications in Public Domain
  46.  
  47.  
  48.                                   @
  49.  
  50.  
  51. MEMORY_SIZE    EQU    64        ; 64k bytes of RAM
  52. MONITOR_SIZE    EQU    4        ;  4k bytes of Monitor
  53. USER_MEMORY    EQU    MEMORY_SIZE-MONITOR_SIZE
  54. MONITOR        EQU    USER_MEMORY*1024
  55. BIAS        EQU    (USER_MEMORY-20)*1024
  56. CCP        EQU    BIAS+03400H
  57. CBIOS        EQU    CCP+01600H
  58. BDOS        EQU    CCP+00806H    ; BDOS Entry point
  59. STACK        EQU    00000H        ; Stack pointer
  60. IOBYTE        EQU    00003H        ; I/O Byte
  61. CONSOLE_STATUS    EQU    MONITOR+6
  62. CONSOLE_INPUT    EQU    MONITOR+9
  63. LIST_OUTPUT    EQU    MONITOR+15
  64. READ_DEVICE    EQU    MONITOR+21    ; Read device
  65. TIKCNT        EQU    0FF5DH        ; Tick counter
  66. RUN_UNIT    EQU    0FF79H        ; Run unit
  67. DISK_UNIT    EQU    RUN_UNIT+1    ; Disk Unit
  68. TRACK        EQU    DISK_UNIT+1    ; Track
  69. SECTOR        EQU    TRACK+1        ; Sector
  70. DMA_ADDRESS    EQU    SECTOR+1    ; DMA address store
  71. RETRY_COUNT    EQU    DMA_ADDRESS+2    ; Retry count
  72.  
  73. SYDAP        EQU    28        ; System Control Port
  74. MAX_DRIVE    EQU    04H        ; Max No of drives
  75.  
  76. CR        EQU    0DH        ; Carriage return
  77. LF        EQU    0AH        ; Line feed
  78. FF        EQU    0CH        ; Form Feed
  79. TAB        EQU    08H        ; TAB character
  80.  
  81. ;    Set assembly address.
  82.  
  83.     .PHASE    CBIOS
  84.  
  85. ;    Jump Table into CBIOS.
  86.  
  87.     JP    COLD_BOOT        ; Cold Boot Entry
  88.     JP    WARM_BOOT        ; Warm Boot Entry
  89.     JP    CONSOLE_STATUS        ; Console Status
  90.     JP    CONSOLE_INPUT        ; Console Input
  91.     JP    CONSOLE_OUTPUT        ; Console output
  92.     JP    LIST_OUTPUT        ; List output
  93.     JP    PUNCH_DEVICE        ; Punch output
  94.     JP    READ_DEVICE        ; Reader input
  95.     JP    HOME_HEAD        ; Home Disk head
  96.     JP    SELECT_DRIVE        ; Select the drive
  97.     JP    SEEK_TRACK        ; Seek to a sector
  98.     JP    SET_SECTOR        ; Set the sector
  99.     JP    SET_DMA_ADDRESS        ; Set DMA address
  100.     JP    READ_SECTOR        ; Read a sector
  101.     JP    WRITE_SECTOR        ; Write a sector
  102.     JP    LIST_STATUS        ; List status
  103.     JP    TRANSLATE_SECTOR    ; Locate physical
  104.  
  105. ;    Send a character to the Punch Device.
  106.  
  107. PUNCH_DEVICE:
  108.     LD    A,C
  109.     JP    MONITOR+24        ; Go to the monitor
  110.  
  111. ;    Return permanent ready in this version.
  112.  
  113. LIST_STATUS:
  114.     XOR    A            ; Zero register
  115.     DEC    A            ; Reset the 'Z' flag
  116.     RET
  117.  
  118. ;    Console Output routine.
  119.  
  120. CONSOLE_OUTPUT:
  121.     LD    A,C
  122.     JP    MONITOR+12        ; Send to Console
  123.  
  124. ;    Cold Boot CBIOS Routine.
  125.  
  126. COLD_BOOT:
  127.     XOR    A            ; Zero the byte
  128.     LD    (IOBYTE),A        ; Reset I/O byte
  129.     LD    HL,TITLE_MESSAGE    ; Title
  130.     CALL    SHOW_MESSAGE        ; Send to console
  131.     CALL    SET_DEFAULTS        ; Default addresses
  132.     JP    CCP            ; Cold start the CCP
  133.  
  134. ;    Warm Boot CBIOS Routine.
  135.  
  136. WARM_BOOT:
  137.     LD    SP,STACK        ; Monitor stack area
  138.     LD    A,(DISK_UNIT)        ; Get disk unit
  139.     LD    (RUN_UNIT),A        ; Save it
  140.     LD    C,0            ; Select disk 'A'
  141.     CALL    SELECT_DRIVE        ; Select it
  142.     CALL    HOME_HEAD        ; Send to track 0
  143.     LD    HL,CCP            ; Point to the CCP
  144.     LD    BC,00D02H
  145.     CALL    READ_LOOP        ; Even sectors, track 0
  146.     LD    HL,CCP+00080H        ; Update DMA address
  147.     LD    BC,00C03H
  148.     CALL    READ_LOOP        ; Odd sectors, track 1
  149.     LD    C,1
  150.     CALL    SEEK_TRACK        ; Seek track 1
  151.     JR    NZ,FATAL_LOAD_ERROR    ; Oops - Abort it now
  152.  
  153.     LD    HL,BIAS+4080H
  154.     LD    BC,00A01H
  155.     CALL    READ_LOOP        ; Odd sectors, track 1
  156.     LD    HL,BIAS+04100H
  157.     LD    BC,00902H
  158.     CALL    READ_LOOP        ; Even sectors, track 1
  159.     CALL    SET_DEFAULTS        ; Set default values
  160.     JP    CCP+3            ; Warm start CCP
  161.  
  162. ;    Set up Default Values.
  163.  
  164. SET_DEFAULTS:
  165.     LD    A,0C3H            ; Jump command
  166.     LD    (00000H),A        ; Warm start jump
  167.     LD    (00005H),A        ; BDOS jump
  168.     LD    (00038H),A        ; Restart FF jump
  169.     LD    HL,CBIOS+3        ; Routine address
  170.     LD    (00001H),HL        ; Put into position
  171.     LD    HL,BDOS            ; Routine address
  172.     LD    (00006H),HL        ; Put into position
  173.     LD    HL,MONITOR        ; Monitor cold start
  174.     LD    (00039H),HL        ; Put into position
  175.     LD    BC,00080H        ; Default DMA address
  176.     CALL    SET_DMA_ADDRESS        ; Save it
  177.     LD    A,(RUN_UNIT)
  178.     LD    (DISK_UNIT),A
  179.     LD    C,A            ; Put unit into 'C'
  180.     RET
  181.  
  182. ;    Read a series of sectors.
  183.  
  184. READ_LOOP:
  185.     LD    (DMA_ADDRESS),HL    ; Save DMA address
  186.     LD    A,C            ; Get the sector
  187.     LD    (SECTOR),A        ; Save it
  188.     PUSH    HL
  189.     PUSH    BC            ; Save registers
  190.     CALL    READ_SECTOR        ; Read a sector
  191.     POP    BC
  192.     POP    HL            ; Restore 'em
  193.     JR    NZ,FATAL_LOAD_ERROR    ; Oops - Abort now
  194.  
  195.     INC    H            ; Set DMA by 256 bytes
  196.     INC    C
  197.     INC    C            ; Bump sector by 2
  198.     DJNZ    READ_LOOP        ; Read next sector
  199.     RET
  200.  
  201. ;    Show that CP/M was unable to be loaded from Disk.
  202.  
  203. FATAL_LOAD_ERROR:
  204.     LD    HL,FATAL_ERROR        ; Error message
  205.     CALL    SHOW_MESSAGE        ; Tell the user
  206.     IN    A,(SYDAP)        ; Get port status
  207.     OR    01000100B        ; Mask to kill disks
  208.     OUT    (SYDAP),A        ; Send to the port
  209.     HALT                ; Stop the processor
  210.  
  211. ;    Store the Sector number passed.
  212.  
  213. SET_SECTOR:
  214.     LD    A,C            ; Get the sector
  215.     LD    (SECTOR),A        ; Save the Sector
  216.     RET
  217.  
  218. ;    Translate to the Physical Sector.
  219.  
  220. TRANSLATE_SECTOR:
  221.     EX    DE,HL            ; Swap to use
  222.     ADD    HL,BC            ; Point to sector
  223.     LD    L,(HL)            ; Put into L
  224.     LD    H,0            ; Make HL the sector
  225.     RET
  226.  
  227. ;    Set the DMA address.
  228.  
  229. SET_DMA_ADDRESS:
  230.     LD    (DMA_ADDRESS),BC    ; Save it
  231.     RET
  232.  
  233. ;    Select the Drive to use.
  234.  
  235. SELECT_DRIVE:
  236.     LD    HL,0            ; Clear result
  237.     LD    A,C            ; Get drive Number
  238.     CP    MAX_DRIVE        ; Out of bounds?
  239.     RET    NC            ; Yes - Abort
  240.  
  241.     LD    (DISK_UNIT),A        ; Store new drive
  242.     LD    L,A            ; Drive into HL
  243.     ADD    HL,HL            ; Drive*2
  244.     ADD    HL,HL            ; Drive*4
  245.     ADD    HL,HL            ; Drive*8
  246.     ADD    HL,HL            ; Drive*16
  247.     LD    DE,DRIVE_PARAM_HEADER    ; Parameter block
  248.     ADD    HL,DE            ; Point to correct one
  249.     PUSH    HL            ; Save table pointer
  250.     LD    B,0            ; Fastest seek speed
  251.     LD    C,A            ; Load Disk Drive No.
  252.     CALL    MONITOR+27        ; Do monitor routine
  253.     POP    HL            ; Restore table pointer
  254.     RET    Z            ; Return if successful
  255.  
  256.     LD    C,1
  257.     CALL    REPORT
  258.     JR    NZ,SELECT_DRIVE2    ; Jump if abort found
  259.  
  260.     LD    A,(DISK_UNIT)        ; Else try again
  261.     LD    C,A
  262.     JR    SELECT_DRIVE
  263.  
  264. SELECT_DRIVE2:
  265.     LD    HL,0            ; Flag as bad one
  266.     LD    A,(RUN_UNIT)
  267.     LD    (DISK_UNIT),A        ; Restore old drive
  268.     RET
  269.  
  270. ;    Home the Disk Drive's head to Track 0.
  271.  
  272. HOME_HEAD:
  273.     CALL    MONITOR+30        ; Monitor Home routine
  274.     RET    Z            ; Return if OK
  275.  
  276.     LD    C,2
  277.     CALL    REPORT
  278.     JR    Z,HOME_HEAD        ; Retry if error
  279.  
  280.     RET
  281.  
  282. ;    Seek to the selected track.
  283.  
  284. SEEK_TRACK:
  285.     LD    A,C            ; Get the track
  286.     LD    (TRACK),A        ; Save the track
  287. SEEK_TRACK1:
  288.     CALL    MONITOR+33        ; Call the monitor
  289.     RET    Z            ; Return if no error
  290.  
  291.     LD    C,2            ; Type of error
  292.     CALL    REPORT            ; Show the error
  293.     RET    NZ            ; Fatal Error - Abort!
  294.  
  295.     LD    A,(TRACK)        ; Get the track
  296.     LD    C,A
  297.     JR    SEEK_TRACK1        ; Retry
  298.  
  299.  
  300. ;    Read a Sector.
  301.  
  302. READ_SECTOR:
  303.     LD    HL,(DMA_ADDRESS)    ; Get the DMA address
  304.     LD    A,(SECTOR)        ; Get the sector
  305.     LD    C,A
  306.     CALL    MONITOR+36        ; Call the monitor
  307.     RET    Z            ; Return if no error
  308.  
  309.     LD    C,3            ; Type of error
  310.     CALL    REPORT            ; Show the error
  311.     JR    Z,READ_SECTOR        ; Retry
  312.  
  313.     RET                ; Abort
  314.  
  315.  
  316. ;    Write a sector.
  317.  
  318. WRITE_SECTOR:
  319.     LD    HL,(DMA_ADDRESS)    ; Get the DMA address
  320.     LD    A,(SECTOR)        ; Get the sector
  321.     LD    C,A
  322.     CALL    MONITOR+39        ; Call the monitor
  323.     RET    Z            ; Return if no error
  324.  
  325.     LD    C,4            ; Type of error
  326.     CALL    REPORT            ; Show the error
  327.     JR    Z,WRITE_SECTOR        ; Retry
  328.  
  329.     RET                ; Abort
  330.  
  331. ;    Report on the error.
  332.  
  333. REPORT:
  334.     LD    E,A            ; Save error flags
  335.     LD    D,C            ; Save error type
  336.     LD    HL,DISK_MESSAGES    ; Point to messages
  337.     CALL    SHOW_MESSAGE        ; Show the message
  338.     DEC    HL            ; Step back
  339.     LD    B,D            ; Get error class
  340. FIND_MESSAGE:
  341.     CALL    SKIP            ; Find next '$'
  342.     DJNZ    FIND_MESSAGE        ; Move to the message
  343.  
  344.     CALL    SHOW_MESSAGE        ; Show error message
  345.     LD    HL,ERROR_MESSAGE    ; Finish error message
  346.     CALL    SHOW_MESSAGE        ; Show it
  347.  
  348. ;    Determine the nature of the error.
  349.  
  350.     LD    A,E            ; Get the flags
  351.     RLA                ; Test if drive unready
  352.     JR    C,DISK_NOT_READY    ; Yes - Skip this bit
  353.  
  354.     LD    E,A            ; Save the flags
  355.     LD    HL,RW_ERRORS        ; R/W error messages
  356.     LD    A,D            ; Get the error type
  357.     CP    3            ; Sel/Seek or R/W?
  358.     JR    NC,NOT_SEEK_ERRORS    ; Read/Write errors
  359.  
  360.     LD    HL,SEEK_ERRORS        ; Select message set
  361. NOT_SEEK_ERRORS:
  362.     LD    B,5            ; Five bits to test
  363.     RES    0,D            ; Reset comma flag
  364. WHICH_ERROR:
  365.     SLA    E            ; Move it left
  366.     JR    NC,SELECT_MESSAGE    ; Not this one!
  367.  
  368.     LD    A,','            ; Load with comma
  369.     BIT    0,D            ; Print a comma?
  370.     CALL    NZ,MONITOR+12        ; Yes - Do it
  371.  
  372.     CALL    SHOW_MESSAGE        ; Show the error msg
  373.     SET    0,D            ; Make a comma show
  374.     JR    TEST_NEXT_BIT        ; Continue
  375.  
  376. SELECT_MESSAGE:
  377.     CALL    SKIP            ; Move to next message
  378.     RES    0,D            ; Kill comma flag
  379. TEST_NEXT_BIT:
  380.     DJNZ    WHICH_ERROR        ; Test all bits
  381.  
  382.     LD    HL,TRK_SEC_MESSAGE    ; Track/Sector message
  383.     CALL    SHOW_MESSAGE        ; Display it
  384.     LD    A,(TRACK)        ; Get the track number
  385.     CALL    SHOW_HEX_BYTE        ; Show it
  386.     LD    A,'/'            ; Delimiter
  387.     CALL    MONITOR+12        ; Send to console
  388.     LD    A,(SECTOR)        ; get the sector number
  389.     CALL    SHOW_HEX_BYTE        ; Show it
  390. PERM_ERROR:
  391.     LD    A,1            ; Flag permanent error
  392.     OR    A
  393.     RET
  394.  
  395. DISK_NOT_READY:
  396.     LD    HL,DISK_UNREADY        ; Show message
  397.     CALL    SHOW_MESSAGE        ; Show 'em
  398.     CALL    CONSOLE_STATUS        ; Key Pressed?
  399.     JR    Z,WAIT_A_SECOND        ; No - Wait, then retry
  400.  
  401.     CALL    CONSOLE_INPUT        ; Get the character
  402.     CP    'C'-40H            ; Abort it?
  403.     JR    Z,PERM_ERROR        ; Yes!
  404.  
  405. WAIT_A_SECOND:
  406.     LD    A,(TIKCNT)        ; Get the current tick
  407.     LD    B,A            ; Save it
  408. WAIT:
  409.     LD    A,(TIKCNT)        ; Get the time
  410.     CP    B            ; Same?
  411.     JR    Z,WAIT            ; Yes - Wait
  412.  
  413.     XOR    A            ; Flag a retry
  414.     RET
  415.  
  416. ;    Skip a message string.
  417.  
  418. SKIP:
  419.     PUSH    BC            ; Save
  420.     LD    B,255            ; Arbitary large No.
  421.     LD    A,'$'            ; Terminator
  422.     CPIR                ; Block search
  423.     POP    BC            ; Restore
  424.     RET
  425.  
  426. ;    Send a message string to the Console.
  427.  
  428. SHOW_MESSAGE:
  429.     LD    A,(HL)            ; get a character
  430.     CP    '$'            ; EOT?
  431.     INC    HL            ; Step pointer
  432.     RET    Z            ; Yes - Exit
  433.  
  434.     CALL    MONITOR+12        ; Send to console
  435.     JR    SHOW_MESSAGE        ; Continue
  436.  
  437. ;    Send a byte to the screen in HEX format.
  438.  
  439. SHOW_HEX_BYTE:
  440.     PUSH    AF            ; Save byte
  441.     RRA
  442.     RRA
  443.     RRA
  444.     RRA                ; Swap nibbles
  445.     CALL    SHOW_HEX_NIBBLE        ; Show it
  446.     POP    AF            ; Restore byte
  447. SHOW_HEX_NIBBLE:
  448.     AND    00001111B        ; Select lower nibble
  449.     ADD    A,90H
  450.     DAA
  451.     ADC    A,40H
  452.     DAA                ; Convert to hex
  453.     JP    MONITOR+12        ; Send to console
  454.  
  455. ;    Title of the CBIOS.
  456.  
  457. TITLE_MESSAGE:
  458.     DEFB    FF,CR,LF
  459.     DEFM    "Iceworks' CP/M 2.2 Version: 1.0"
  460.     DEFB    CR,LF,'$'
  461.  
  462. ;    Fatal Load Error Message.
  463.  
  464. FATAL_ERROR:
  465.     DEFB    FF,TAB
  466.     DEFM    "UNABLE TO LOAD CP/M"
  467.     DEFB    CR,LF,'$'
  468.  
  469. ;    Disk Error Messages.
  470.  
  471. DISK_MESSAGES:
  472.     DEFB    CR,LF
  473.     DEFM    'BIOS $'
  474.     DEFM    'SELECT $'
  475.     DEFM    'SEEK $'
  476.     DEFM    'READ $'
  477.     DEFM    'WRITE $'
  478.  
  479. ;    Tail of Error Message.
  480.  
  481. ERROR_MESSAGE:
  482.     DEFM    'ERROR $'
  483.  
  484. ;    Seek Error Messages.
  485.  
  486. SEEK_ERRORS:
  487.     DEFM    '$'
  488.     DEFM    '$'
  489.     DEFM    'CANNOT SEEK$'
  490.     DEFM    'BAD CRC$'
  491.     DEFM    'CANNOT RESTORE$'
  492.  
  493. ;    Drive Not Ready Message.
  494.  
  495. DISK_UNREADY:
  496.     DEFB    CR,LF
  497.     DEFM    'Drive not ready -'
  498.     DEFM    CR,LF,'$'
  499.  
  500. ;    Read/Write Errors.
  501.  
  502. RW_ERRORS:
  503.     DEFM    'WRITE PROTECTED$'
  504.     DEFM    'WRITE FAULT$'
  505.     DEFM    'RECORD NOT FOUND$'
  506.     DEFM    'BAD CRC$'
  507.     DEFM    'DATA OVERRUN$'
  508.  
  509. ;    Track/Sector Message.
  510.  
  511. TRK_SEC_MESSAGE:
  512.     DEFM    ' Track/Sector = $'
  513.  
  514. ;    Drive Parameter Headers for a 4 drive system.
  515.  
  516. DRIVE_PARAM_HEADER:
  517.  
  518.     DEFW    SECTAB,00000H        ; Disk Unit 0
  519.     DEFW    00000H,00000H
  520.     DEFW    DIRBUF,DPBLOK
  521.     DEFW    CHECK0,ALLOC0
  522.  
  523.     DEFW    SECTAB,00000H        ; Disk Unit 1
  524.     DEFW    00000H,00000H
  525.     DEFW    DIRBUF,DPBLOK
  526.     DEFW    CHECK1,ALLOC1
  527.  
  528.     DEFW    SECTAB,00000H        ; Disk Unit 2
  529.     DEFW    00000H,00000H
  530.     DEFW    DIRBUF,DPBLOK
  531.     DEFW    CHECK2,ALLOC2
  532.  
  533.     DEFW    SECTAB,00000H        ; Disk Unit 3
  534.     DEFW    00000H,00000H
  535.     DEFW    DIRBUF,DPBLOK
  536.     DEFW    CHECK3,ALLOC3
  537.  
  538. ;    Sector Translation Table (Standard 1 in 6 interleave).
  539.  
  540. SECTAB:
  541.     DEFB    1,7,13,19
  542.     DEFB    25,5,11,17
  543.     DEFB    23,3,9,15
  544.     DEFB    21,2,8,14
  545.     DEFB    20,26,6,12
  546.     DEFB    18,24,4,10
  547.     DEFB    16,22
  548.  
  549. ;    Disk Parameter Block for standard 8" Floppy.
  550.  
  551. DPBLOK:
  552.     DEFW    26            ; Sectors per track
  553.     DEFB    3            ; Block shift constant
  554.     DEFB    7            ; Block mask constant
  555.     DEFB    0            ; Block extent Constatnnt
  556.     DEFW    242            ; Maximum block number
  557.     DEFW    63            ; Maximum Direct. Entry
  558.     DEFB    11000000B        ; Allocation Mask MSB
  559.     DEFB    00000000B        ;    "      "  LSB
  560.     DEFW    16            ; Check size
  561.     DEFW    2            ; Reserved tracks
  562.  
  563. ;    Disk I/O Buffers for BDOS file Handler.
  564.  
  565. DIRBUF:
  566.     DEFS    128            ; Scratch Directory
  567. ALLOC0:
  568.     DEFS    32            ; Allocation Buffer 0
  569. CHECK0:
  570.     DEFS    16            ; Check Vector 0
  571. ALLOC1:
  572.     DEFS    32
  573. CHECK1:
  574.     DEFS    16
  575. ALLOC2:
  576.     DEFS    32
  577. CHECK2:
  578.     DEFS    16
  579. ALLOC3:
  580.     DEFS    32
  581. CHECK3:
  582.     DEFS    16
  583.  
  584.     END    COLD_BOOT
  585.