home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 223_02 / ulink.mac < prev    next >
Text File  |  1989-02-23  |  6KB  |  253 lines

  1. ; ulink
  2. ;
  3. ;        Small-C     System Library  Version 1.0
  4. ;
  5. ;                by
  6. ;
  7. ;            Fred A. Scacchitti
  8. ;            25 Glenview Lane
  9. ;            Roch., NY 14609
  10. ;
  11. ;              11 - 24 - 84
  12. ;
  13. ;    This module is a derivative of RUNTIME.MAC by Glen Fisher
  14. ;    and Bill Randle. It contains a minimal implementation of
  15. ;    CP/M hooks to allow proper linking of Small-C programs
  16. ;    compiled by Version 2.08 (and later) of the Small-C compiler.
  17. ;
  18. ;    This module contains the following routines:
  19. ;
  20. ;    -ULINK entry point just like J. E. Hendrix Vers. 2.1
  21. ;
  22. ;    -Initialization of stack, memory buffers, and argument
  23. ;     passing (argv, argc).
  24. ;
  25. ;
  26. ;     call to main()
  27. ;        links to main in user program
  28. ;
  29. ;    -Cleans house and returns to CP/M
  30. ;
  31. ;
  32. ;
  33. ;
  34. ; Now then here's the starting code
  35. ;
  36. ;
  37. ;
  38. ; 1st - Save CPM's stack pointer, establish file i/o constructs    set
  39. ;    new default buffer and establish start of available memory.
  40. ;
  41. ; 2nd - Get the default disk and set stack at base of BDOS or CCP
  42. ;    depending on the status ZZZCCP. 0 = bdos  1 = ccp
  43. ;
  44. ; 3rd - Parse the CPM input line and modify it so that we can pass
  45. ;    the C program  in the argc, argv form that it expects.
  46. ;         HL = pointer to next argv entry
  47. ;         DE = pointer to next character in command line
  48. ;         B  = number of    characters left    in line
  49. ;         C  = argument count (argc)
  50. ;
  51. ; 4th - Call MAIN to commence operation of the user program
  52. ;
  53. ; 5th - Work, work, work and then return to here via exit(), abort()
  54. ;    or normal return from program.
  55. ;
  56. ; 6th - Close any open files (buffers are not flushed)
  57. ;
  58. ; 7th - Restore CP/M's stack pointer, select the disk you entered
  59. ;    with, reset the default buffer and return to CP/M either
  60. ;    via a JMP 0 (ZZZCCP = 0) or RET (ZZZCCP = 1).
  61. ;
  62. ;
  63. CBDOS    EQU    5    ;/* bdos entry point */
  64. CPMARG    EQU    128    ;/* CP/M command line */
  65. MAXARG    EQU    24    ;/* Maximum number of input args */
  66. STDIN    EQU    0
  67. STDOUT    EQU    1
  68. STDERR    EQU    2
  69. STDLST    EQU    4
  70. CBDOS    EQU    5
  71. CLOSE    EQU    16
  72. ;
  73. FCBSIZE    EQU    36    ;size, in bytes, of an FCB
  74. BUFFER    EQU    6    ;offset    to disk    sector buf. in I/O struct.
  75. UNGOT    EQU    5    ;offset to char ungotten by ungetc()
  76. FLAG    EQU    33    ;file-type flag    byte (in unused    part of    FCB)
  77. FREEFLG    EQU    128    ;This I/O structure is available
  78. BUFSIZ    EQU    1024    ;how long the sector buffer is
  79. NBUFS    EQU    8    ;number    of I/O buffers
  80. TBUFSZ    EQU    128    ;size of default disk buffer
  81. ;
  82. EXTRN    MAIN, ZZBUF, ZZZCCP
  83. ;
  84. ;
  85. ULINK::
  86. ;
  87.     LXI    H,0        ; get CPM's stack pointer
  88.     DAD    SP
  89.     SHLD    ZZSTAK        ; save it for later
  90. ;
  91.     MVI    C,26
  92.     LXI    D,ZZBUF
  93.     CALL    CBDOS        ; Set the default buffer out there
  94. ;
  95. SETIO:    
  96.     MVI    B,NBUFS
  97.     LXI    H,ZZBUF+TBUFSZ+FLAG
  98.     LXI    D,FCBSIZE+BUFFER+BUFSIZ
  99.     MVI    A,FREEFLG
  100. SETIO2:    MOV    M,A            ;set all buffers to free
  101.     DAD    D            ;on to next buffer
  102.     DCR    B
  103.     JNZ    SETIO2            ;if there is one...
  104.     SHLD    ZZMEM            ;put it where it belongs
  105. ;
  106.  
  107.     MVI    C,25        ; get logged-in    disk
  108.     CALL    CBDOS    
  109.     INR    A
  110.     STA    ZZDFLT        ; save it
  111. ;
  112.     LDA    CBDOS+2        ; get base of BDOS
  113.     MOV    H,A        ; save page in HL
  114.     MVI    L,0        ; where do we put the stack
  115. ;
  116.     LDA    ZZZCCP        ; let's check
  117.     ORA    A        ;
  118.     JZ    SETSTK        ; just below the BDOS
  119.     MOV    A,H
  120.     SUI    8        ; just below the CCP
  121.     MOV    H,A
  122. ;
  123. SETSTK:
  124.     SPHL            ; set stack pointer
  125. ;
  126.     MVI    C,0    ; Init argc
  127.     LXI    H,ARGV    ; Pointer to first entry of argv array
  128. ;
  129. ; CPM does not tell us what the first word of  the command 
  130. ; line was (the name of pgm), so we fake  it by    pointing it
  131. ; to an ascii string with '*' in it
  132. ;
  133.     LXI    D,PGM    ; Pointer to 'pgmname' string
  134.     CALL    SVARG    ; Save next argument
  135. ;
  136. ; Ok, now for the real stuff.  Set DE pair to point to
  137. ; CPM command line and start searching for arguments
  138.  
  139.     LXI    D,CPMARG ; Pointer to CPM arg line
  140.     LDAX    D    ; Load # character in line
  141.     MOV    B,A    ; Save it in B
  142. NXTSP:    INX    D    ; Point    to next    character
  143.     DCR    B    ; Decrement character count
  144.     JM    ENDCMD    ; End of cmd line
  145.     LDAX    D    ; Load next character in line
  146.     CPI    ' '    ; Space?
  147.     JZ    NXTSP    ; Yes...continue searching
  148.     CALL    SVARG    ; Nope,    save starting point of this arg
  149.  
  150. ; Loop looking for either end of line of a space
  151.  
  152. NXTCH:    INX    D    ; Point    to next    character
  153.     DCR    B    ; Decrement character count
  154.     JM    ENDWRD    ; End of cmd line, but need to end arg
  155.     LDAX    D    ; Load next character in line
  156.     CPI    ' '    ; Space?
  157.     JNZ    NXTCH    ; Nope...keep looking
  158.     MVI    A,0    ; Yes, replace it with a zero byte
  159.     STAX    D
  160.     JMP    NXTSP    ; Look for start of next arg
  161. ENDWRD:    MVI    A,0
  162.     STAX    D
  163. ENDCMD:    MVI    B,0    ; Zero B (BC now is 16 bit argc)
  164.     PUSH    B    ; First    arg to main procedure
  165.     LXI    H,ARGV    ; Point    to argv    array
  166.     PUSH    H    ; Second argument to main procedure
  167.     MVI    A,2    ; Load up the argument count
  168. ;
  169.     CALL    MAIN    ; Transfer to the C world....
  170. ;
  171. ;    anchors
  172. ;        away
  173. ;            my
  174. ;                bo
  175. ;                   y
  176. ;                    y
  177. ;                     y
  178. ;                      y
  179. ;                      y
  180. ;
  181. EXIT::
  182.     MVI    B,NBUFS        ; Prepare to scan for open files
  183.     MVI    C,CLOSE
  184.     LXI    H,ZZBUF+TBUFSZ+FLAG
  185.     LXI    D,FCBSIZE+BUFFER+BUFSIZ
  186. SCANEM:    
  187.     MOV    A,M        ; Get free flag
  188.     CPI    FREEFLG        ; Is it free ?
  189.     JZ    NOPEN        ; Yes - not open, go get next
  190.     PUSH    B        ; No  - prepare to close
  191.     PUSH    D
  192.     PUSH    H
  193.     LXI    D,-FLAG
  194.     DAD    D
  195.     XCHG            ; DE --> Start of FCB
  196.     CALL    CBDOS        ; Close the file
  197.     POP    H        ; Restore scan setup
  198.     POP    D
  199.     POP    B
  200. NOPEN:
  201.     DAD    D        ; Point to next flag
  202.     DCR    B        ; Last one ?
  203.     JNZ    SCANEM        ; No  - keep scanning until done
  204. ;
  205.     MVI    C,26
  206.     LXI    D,80H
  207.     CALL    CBDOS        ; Reset the default buffer
  208. ;
  209.     LHLD    ZZSTAK        ; Load stack pointer
  210.     SPHL
  211.     LDA    ZZZCCP        ; How do we get back ?
  212.         ORA    A
  213.     RNZ            ; this way to CCP
  214. ;
  215. ;                    or
  216. ;
  217. ;                  this way to warm boot
  218. ;
  219.     LDA    ZZDFLT        ; Grab orig. logged-in disk
  220.     MOV    E,A
  221.     DCR    E        ; (cvt.    back to    0-n)
  222.     MVI    C,14        ; and log it in    again
  223.     CALL    CBDOS        ; (mod to cbdos (fas))
  224. ;
  225.     JMP    0
  226. ;
  227. ;
  228. SVARG:    MOV    M,E    ; Save pointer to start    of string
  229.     INX    H
  230.     MOV    M,D
  231.     INX    H
  232.     INR    C    ; Increment argc
  233.     RET
  234. PGM:        DB    '*',0
  235. ;
  236. ARGV:        DS    MAXARG*2
  237. ;
  238. ZZDFLT::    DB    0    ; default disk 
  239. ;
  240. ZZSTAK::    DW    0    ; CP/M's stack
  241. ;
  242. ZZMEM::        DW    0    ; useable memory pointer
  243. ;
  244. ZZTEMP::    DW    0    ; available to anyone
  245. ;
  246. ;
  247. ;
  248.     END    ULINK
  249.  
  250.  
  251.  
  252.  
  253.