home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource3 / 115_01 / c80lib < prev    next >
Text File  |  1979-12-31  |  19KB  |  1,241 lines

  1. #asm
  2. ;
  3. ;
  4. ;------------------------------------------------------------------
  5. ;    Small-C  Run-time Library
  6. ;
  7. ;
  8. ;    V3b    As of June 9, 1980 12pm (rj)
  9. ;           corrected cp to chp in @gets
  10. ;           changed lower case to hex constants in @fopen and fcb
  11. ;    V4    As of June 26, 1980 12:15pm (gtf)
  12. ;           Changed all @'s and ?'s to "QZ" for ASM compatibility
  13. ;    V4b    As of July 7, 1980 3:00 pm (gtf)
  14. ;              Changed putc() to test code returned by cput()
  15. ;    V4c    As of July 9, 1980 9:15 pm (gtf)
  16. ;           Fixed bug in CPMIO which returned wrong error status.
  17. ;           Added PUTS() function
  18. ;           Un-hardwired I/O buffer count.
  19. ;           Made GETCHAR() print LF after reading CR.
  20. ;           Made GETCHAR() return -1 on EOF (=CTRL-Z)
  21. ;           Added EOL and LF equates, instead of magic numbers
  22. ;    V4d    As of July 16, 1980  9:00 pm (gtf)
  23. ;           Added EXIT() function
  24. ;------------------------------------------------------------------
  25. ;
  26. ; Runtime library initialization.  Set up default drive for CP/M.
  27. CCGO:    MVI    C,QUERY        ;get logged-in disk
  28.     CALL    BDOS
  29.     INR    A        ;make it so it will work in fcb
  30.     STA    DFLTDSK
  31.     RET
  32. ;Fetch a single byte from the address in HL and
  33. ; sign extend into HL
  34. CCGCHAR: MOV    A,M
  35. CCSXT:    MOV    L,A
  36.     RLC
  37.     SBB    A
  38.     MOV    H,A
  39.     RET
  40. ;Fetch a full 16-bit integer from the address in HL
  41. CCGINT:    MOV    A,M
  42.     INX    H
  43.     MOV    H,M
  44.     MOV    L,A
  45.     RET
  46. ;Store a single byte from HL at the address in DE
  47. CCPCHAR: MOV    A,L
  48.     STAX    D
  49.     RET
  50. ;Store a 16-bit integer in HL at the address in DE
  51. CCPINT:    MOV    A,L
  52.     STAX    D
  53.     INX    D
  54.     MOV    A,H
  55.     STAX    D
  56.     RET
  57. ;Inclusive "or" HL and DE into HL
  58. CCOR:    MOV    A,L
  59.     ORA    E
  60.     MOV    L,A
  61.     MOV    A,H
  62.     ORA    D
  63.     MOV    H,A
  64.     RET
  65. ;Exclusive "or" HL and DE into HL
  66. CCXOR:    MOV    A,L
  67.     XRA    E
  68.     MOV    L,A
  69.     MOV    A,H
  70.     XRA    D
  71.     MOV    H,A
  72.     RET
  73. ;"And" HL and DE into HL
  74. CCAND:    MOV    A,L
  75.     ANA    E
  76.     MOV    L,A
  77.     MOV    A,H
  78.     ANA    D
  79.     MOV    H,A
  80.     RET
  81. ;Test if HL = DE and set HL = 1 if true else 0
  82. CCEQ:    CALL    CCCMP
  83.     RZ
  84.     DCX    H
  85.     RET
  86. ;Test if DE ~= HL
  87. CCNE:    CALL    CCCMP
  88.     RNZ
  89.     DCX    H
  90.     RET
  91. ;Test if DE > HL (signed)
  92. CCGT:    XCHG
  93.     CALL    CCCMP
  94.     RC
  95.     DCX    H
  96.     RET
  97. ;Test if DE <= HL (signed)
  98. CCLE:    CALL    CCCMP
  99.     RZ
  100.     RC
  101.     DCX    H
  102.     RET
  103. ;Test if DE >= HL (signed)
  104. CCGE:    CALL    CCCMP
  105.     RNC
  106.     DCX    H
  107.     RET
  108. ;Test if DE < HL (signed)
  109. CCLT:    CALL    CCCMP
  110.     RC
  111.     DCX    H
  112.     RET
  113. ;Common routine to perform a signed compare
  114. ; of DE and HL
  115. ;This routine performs DE - HL and sets the conditions:
  116. ;    Carry reflects sign of difference (set means DE < HL)
  117. ;    Zero/non-zero set according to equality.
  118. CCCMP:    MOV    A,E
  119.     SUB    L
  120.     MOV    E,A
  121.     MOV    A,D
  122.     SBB    H
  123.     LXI    H,1    ;preset true condition
  124.     JM    CCCMP1
  125.     ORA    E    ;"OR" resets carry
  126.     RET
  127. CCCMP1:    ORA    E
  128.     STC        ;set carry to signal minus
  129.     RET
  130. ;
  131. ;Test if DE >= HL (unsigned)
  132. CCUGE:    CALL    CCUCMP
  133.     RNC
  134.     DCX    H
  135.     RET    
  136. ;
  137. ;Test if DE < HL (unsigned)
  138. CCULT:    CALL    CCUCMP
  139.     RC
  140.     DCX    H
  141.     RET
  142. ;
  143. ;Test if DE > HL (unsigned)
  144. CCUGT:    XCHG
  145.     CALL    CCUCMP
  146.     RC
  147.     DCX    H
  148.     RET
  149. ;
  150. ;Test if DE <= HL (unsigned)
  151. CCULE:    CALL    CCUCMP
  152.     RZ
  153.     RC
  154.     DCX    H
  155.     RET
  156. ;
  157. ;Common routine to perform unsigned compare
  158. ;carry set if DE < HL
  159. ;zero/nonzero set accordingly
  160. CCUCMP:    MOV    A,D
  161.     CMP    H
  162.     JNZ    $+5
  163.     MOV    A,E
  164.     CMP    L
  165.     LXI    H,1
  166.     RET
  167. ;
  168. ;Shift DE arithmetically right by HL and return in HL
  169. CCASR:    XCHG
  170.     MOV    A,H
  171.     RAL
  172.     MOV    A,H
  173.     RAR
  174.     MOV    H,A
  175.     MOV    A,L
  176.     RAR
  177.     MOV    L,A
  178.     DCR    E
  179.     JNZ    CCASR+1
  180.     RET
  181. ;Shift DE arithmetically left by HL and return in HL
  182. CCASL:    XCHG
  183.     DAD    H
  184.     DCR    E
  185.     JNZ    CCASL+1
  186.     RET
  187. ;Subtract HL from DE and return in HL
  188. CCSUB:    MOV    A,E
  189.     SUB    L
  190.     MOV    L,A
  191.     MOV    A,D
  192.     SBB    H
  193.     MOV    H,A
  194.     RET
  195. ;Form the two's complement of HL
  196. CCNEG:    CALL    CCCOM
  197.     INX    H
  198.     RET
  199. ;Form the one's complement of HL
  200. CCCOM:    MOV    A,H
  201.     CMA
  202.     MOV    H,A
  203.     MOV    A,L
  204.     CMA
  205.     MOV    L,A
  206.     RET
  207. ;Multiply DE by HL and return in HL
  208. CCMULT:    MOV    B,H
  209.     MOV    C,L
  210.     LXI    H,0
  211. CCMULT1: MOV    A,C
  212.     RRC
  213.     JNC    $+4
  214.     DAD    D
  215.     XRA    A
  216.     MOV    A,B
  217.     RAR
  218.     MOV    B,A
  219.     MOV    A,C
  220.     RAR
  221.     MOV    C,A
  222.     ORA    B
  223.     RZ
  224.     XRA    A
  225.     MOV    A,E
  226.     RAL
  227.     MOV    E,A
  228.     MOV    A,D
  229.     RAL
  230.     MOV    D,A
  231.     ORA    E
  232.     RZ
  233.     JMP    CCMULT1
  234. ;Divide DE by HL and return quotient in HL, remainder in DE
  235. CCDIV:    MOV    B,H
  236.     MOV    C,L
  237.     MOV    A,D
  238.     XRA    B
  239.     PUSH    PSW
  240.     MOV    A,D
  241.     ORA    A
  242.     CM    CCDENEG
  243.     MOV    A,B
  244.     ORA    A
  245.     CM    CCBCNEG
  246.     MVI    A,16
  247.     PUSH    PSW
  248.     XCHG
  249.     LXI    D,0
  250. CCDIV1:    DAD    H
  251.     CALL    CCRDEL
  252.     JZ    CCDIV2
  253.     CALL    CCCMPBCDE
  254.     JM    CCDIV2
  255.     MOV    A,L
  256.     ORI    1
  257.     MOV    L,A
  258.     MOV    A,E
  259.     SUB    C
  260.     MOV    E,A
  261.     MOV    A,D
  262.     SBB    B
  263.     MOV    D,A
  264. CCDIV2:    POP    PSW
  265.     DCR    A
  266.     JZ    CCDIV3
  267.     PUSH    PSW
  268.     JMP    CCDIV1
  269. CCDIV3:    POP    PSW
  270.     RP
  271.     CALL    CCDENEG
  272.     XCHG
  273.     CALL    CCDENEG
  274.     XCHG
  275.     RET
  276. CCDENEG: MOV    A,D
  277.     CMA
  278.     MOV    D,A
  279.     MOV    A,E
  280.     CMA
  281.     MOV    E,A
  282.     INX    D
  283.     RET
  284. CCBCNEG: MOV    A,B
  285.     CMA
  286.     MOV    B,A
  287.     MOV    A,C
  288.     CMA
  289.     MOV    C,A
  290.     INX    B
  291.     RET
  292. CCRDEL:    MOV    A,E
  293.     RAL
  294.     MOV    E,A
  295.     MOV    A,D
  296.     RAL
  297.     MOV    D,A
  298.     ORA    E
  299.     RET
  300. CCCMPBCDE: MOV    A,E
  301.     SUB    C
  302.     MOV    A,D
  303.     SBB    B
  304.     RET
  305. ;
  306. ; ========================================
  307. ;  I/O subroutines for CP/M
  308. ;      By Glen Fisher
  309. ;       The Code Works(tm)
  310. ; ========================================
  311. ;
  312. NULL    EQU    0    ;pointer to nothing
  313. FCBSIZE    EQU    36    ;size, in bytes, of an FCB
  314. NEXTP    EQU    0    ;offset to next-character pointer in I/O structure
  315. UNUSED    EQU    2    ;offset to unused-positions-count in I/O structure
  316. BUFFER    EQU    4    ;offset to disk sector buffer in I/O structure
  317. FLAG    EQU    33    ;file-type flag byte (in unused part of FCB)
  318. FREEFLG    EQU    128    ;This I/O structure is available for the taking
  319. EOFFLG    EQU    2    ;The end of this file has been hit
  320. WRTFLG    EQU    1    ;This file open for writing
  321. BUFSIZ    EQU    128    ;how long the sector buffer is
  322. NBUFS    EQU    4    ;number of I/O buffers (change buffer declarations, too)
  323.     ; CP/M system call codes
  324. CLOSE    EQU    16    ;close a file
  325. CREATE    EQU    22    ;make a file
  326. DMA    EQU    26    ;set DMA (I/O address)
  327. DELETE    EQU    19    ;delete a file
  328. GETCH    EQU    1    ;read character from console
  329. GETSTR    EQU    10    ;read string from console
  330. OPEN    EQU    15    ;open a file
  331. PUTCH    EQU    2    ;write character to console
  332. QUERY    EQU    25    ;get logged-in drive id
  333. READ    EQU    20    ;read a sector
  334. SELECT    EQU    14    ;log-in a drive
  335. WRITE    EQU    21    ;write a sector
  336. LF    EQU    10    ;line feed
  337. EOL    EQU    13    ;end-of-line character (=carriage return)
  338. CTRLZ    EQU    26    ;end-of-file mark for text files
  339. TBUFF    EQU    80H    ;address of default I/O address
  340. DFLTDSK    DS    1    ;drive to use if no drive is named
  341. UNIT    DS    2    ;I/O structure address to act on
  342. IP    DS    2    ;int *ip;
  343. CHP    DS    2    ;char *chp;
  344. DP    DS    2    ;char *dp;
  345. FILE    DS    2    ;file name
  346. MODE    DS    2    ;char *mode;(read or write)
  347. ZCH    DS    2    ;char ch;
  348. ZT    DS    2    ;int t;
  349. FN    DS    2    ;int fn;    i/o function (for cpmio)
  350. ;
  351. ;    exit()
  352. ;
  353. ;    Stop execution of the program,
  354. ;    restore the logged-in drive,
  355. ;    and re-boot CP/M
  356. ;
  357. QZEXIT:
  358.     LDA    DFLTDSK        ; Grab orig. logged-in disk
  359.     MOV    E,A
  360.     DCR    E        ; (cvt. back to 0-n)
  361.     MVI    C,SELECT    ; and log it in again
  362.     CALL    BDOS
  363.     JMP    0        ; Our work is complete.
  364. ;
  365. ;    cpm(bc,de)
  366. ;
  367. ;    fill BC and DE, and then call CP/M
  368. ;
  369. ;    return whatever is in A
  370. ;
  371. BDOS    EQU    5
  372.  
  373. QZCPM:
  374.     POP    H    ;grab the arguments
  375.     POP    D
  376.     POP    B
  377.     PUSH    B    ;restore the size of the stack
  378.     PUSH    D
  379.     PUSH    H
  380.     CALL    BDOS    ;go to daddy
  381.     JMP    CCSXT    ;hand the answer back
  382. ;
  383. ;    grabio()
  384. ;
  385. ;    find an input buffer, and return its address.
  386. ;    if there isn't one, return a NULL.
  387. ;
  388. GRABIO:                            ;6 May 80 rj
  389.     MVI    B,NBUFS
  390.     LXI    H,IOBUFS+FLAG
  391.     LXI    D,FCBSIZE+BUFFER+BUFSIZ
  392.     MVI    A,FREEFLG
  393.  
  394. GRAB2:    CMP    M            ;flag byte == freeflg?
  395.     JZ    GRAB3            ;if so, found a free buffer
  396.     DAD    D            ;on to next buffer
  397.     DCR    B
  398.     JNZ    GRAB2            ;if there is one...
  399.     LXI    H,NULL            ;there ain't
  400.     RET                ;give up
  401.  
  402. GRAB3:    MVI    M,0            ;mark buffer as taken
  403.     LXI    D,-FLAG            ;back up to buffer start
  404.     DAD    D     
  405.     RET                ;and hand it back
  406. ;
  407. ;    freeio(unit)
  408. ;
  409. ;    mark a buffer as free.
  410. ;
  411. FREEIO:                    ;Mod  6 May 80 rj
  412.     POP    B            ;save rtn addr
  413.     POP    H            ;get buffer addr
  414.     PUSH    H            ;put the stack back together
  415.     PUSH    B
  416.     LXI    D,FLAG            ;find flag byte
  417.     DAD    D
  418.     MVI    M,FREEFLG        ;mark buffer as 'free'
  419.     LXI    H,NULL            ;return something
  420.     RET
  421.  
  422. IOBUFS:
  423.     DS    FCBSIZE-3
  424.     DB    FREEFLG,0,0
  425.     DS    BUFFER+BUFSIZ
  426.  
  427.     DS    FCBSIZE-3
  428.     DB    FREEFLG,0,0
  429.     DS    BUFFER+BUFSIZ
  430.  
  431.     DS    FCBSIZE-3
  432.     DB    FREEFLG,0,0
  433.     DS    BUFFER+BUFSIZ
  434.  
  435.     DS    FCBSIZE-3        ;mod 4 May 80 rj
  436.     DB    FREEFLG,0,0
  437.     DS    BUFFER+BUFSIZ
  438. ;
  439. ;    fopen(name,mode)
  440. ;
  441. QZFOPEN:
  442.     POP    B            ;get args
  443.     POP    H            ;mode
  444.     SHLD    MODE
  445.     POP    D
  446.     XCHG
  447.     SHLD    FILE
  448.     PUSH    H
  449.     PUSH    D
  450.     PUSH    B
  451.     CALL    GRABIO            ; unit = grabio();
  452.     SHLD    UNIT
  453.     MOV    A,H