home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol073 / prom16u.asm < prev    next >
Assembly Source File  |  1984-04-29  |  14KB  |  873 lines

  1. ;
  2. ;****************************************************************
  3. ;*                                *
  4. ;*                                *
  5. ;*        DRIVER UTILITY FOR SD SYSTEMS            *
  6. ;*          PROM-100 EPROM PROGRAMMER            *
  7. ;*        2758  -  2716  -  2732    VERSION            *
  8. ;*                                *
  9. ;*                                *
  10. ;****************************************************************
  11. ;
  12. ;
  13. ;    Modified by :    Bill Bolton
  14. ;            Software Tools
  15. ;            P.O. Box 80
  16. ;            Newport Beach
  17. ;            NSW, 2106
  18. ;
  19. ;    Dec 29, 1979    Initial bugs removed
  20. ;        
  21. ;    Jan  3, 1980    Comments added and minor improvements
  22. ;
  23. ;    Jan  4, 1980    2716 file created from 2708 file
  24. ;
  25. ;    Jan 16,    1980    First PROM address not programmed debug
  26. ;
  27. ;    Jan 22, 1982    8080 version created and SPEED equate added
  28. ;            plus other minor internal changes
  29. ;
  30. WBOOT    EQU    0
  31. BDOS    EQU    00005H        ;BDOS ENTRY ADDRESS
  32. FCB    EQU    0005CH        ;DEFAULT FILE CONTROL BLOCK
  33. OPEN    EQU    15
  34. SETDMA    EQU    26
  35. ATTRIB    EQU    471BH        ;ADM VIDEO ATTRIBUTE LEAD-IN
  36. DATA    EQU    068H        ;PROM-100 DATA PORT
  37. LADD    EQU    069H        ;PROM-100 LOW ADDRESS PORT
  38. HACTL    EQU    06AH        ;PROM-100 CONTROL PORT
  39. SPEED    EQU    6        ;PROCESSOR SPEED IN MHZ
  40. ACR    EQU    0DH        ;ASCII CARRAIGE RETURN
  41. ALF    EQU    0AH        ;ASCII LINE FEED
  42. ;
  43.     TITLE    'PROM16 - 8080 VERSION FOR CP/M'
  44. ;
  45.     MACLIB    MACRO3        ;Use Software Tools special macros
  46. ;
  47.     ORG    0100H
  48. ;
  49. ;
  50.     LXI    SP,SPVAL
  51.     LXI    H,MESG1        ;SIGN ON MESSAGE
  52.     CALL    PTXT        ;PRINT IT
  53.     MVI    A,080H        ;INIT BUFFER COUNT TO FULL
  54.     STA    BUFCNT        ;STORE IT
  55.     XRA    A        ;RESET A TO 0
  56.     STA    OPENFL        ;RESET FILE OPEN FLAG
  57. INITIAL:
  58.     LXI    SP,SPVAL
  59.     XRA    A
  60.     OUT    HACTL        ;INIT PROM-100 BOARD
  61.     CALL    CRLF
  62.     LXI    H,MESG2        ;READY TO LOAD MESSAGE
  63.     CALL    PTXT
  64.     LXI    H,0        ;RESET HL
  65.     SHLD    COUNT        ;RESET COUNT
  66.     CALL    YORN        ;YES OR NO?
  67.     JNC     READ2        ;NO, GO ASK IF A PROM
  68.                 ;IS TO BE READ
  69. ;
  70. FILEOPN:
  71.     CALL    CRLF            
  72.     LDA    OPENFL        ;GET FILE OPEN FLAG
  73.     ORA    A        ;IS FILE OPEN?
  74.     JNZ    FILER        ;YES, CONTINUE TO READ IT
  75.     PUSH    H
  76.     PUSH    D
  77.     PUSH    B
  78.     MVI    C,OPEN        ;OPEN FILE
  79.     LXI    D,FCB        ;FCB ADDRESS
  80.     CALL    BDOS
  81.     POP    B
  82.     POP    D
  83.     POP    H
  84.     CPI    0FFH        ;SUCESSFUL OPEN?
  85.     JNZ    FILER        ;YES, GO READ IT
  86.     LXI    H,MESG7        ;NO, FILE NOT FOUND
  87.     CALL    PTXT
  88.     JMP    EXIT         ;BACK TO CP/M
  89. ;
  90. FILER:
  91.     PUSH    D
  92.     PUSH    B
  93.     MVI    C,SETDMA    ;SET DISK BUFFER
  94.     LXI    D,00080H    ;BUFFER ADDRESS
  95.     CALL    BDOS
  96.     POP    B
  97.     POP    D
  98.     LXI    H,MESG3        ;LOAD & BYTES MESSAGE
  99.     CALL    PTXT
  100.     CALL    SCAN$OP        ;GET OPERANDS FROM KEYBOARD
  101.     LDA    NXCHAR        ;GET FINAL CHARACTER
  102.     CPI    '.'        ;IS IT ENTRY ABORT CHAR?
  103.     JZ     FILEOPN        ;YES, REPROCESS THE LOOP
  104.     LXI    H,MESG9        ;NO, LOAD START MESSAGE
  105.     CALL    PTXT
  106.     LHLD    OPR1        ;POINT TO FIRST OPERAND
  107.     CALL    PADDR        ;PRINT IT IN HEX
  108.     CALL    CRLF
  109.     CALL    HXREC        ;GET START OF NEXT HEX RECORD
  110.     PUSH    H
  111.     LDED    OPR1        ;GET MEM START ADDRESS
  112.     LDA    OPCNT        ;GET NUMBER OF OPS ENTERED
  113.     ANA    A        ;DETERMINE IF ZERO?
  114.     JZ     FILER1        ;YES, LOAD FILE AT OWN ADDRESS
  115.     DSUB            ;FORM LOAD OFFSET INTO MEMORY
  116.     PUSH    H        ;COPY OFFSET
  117.     POP    D        ; INTO DE
  118. FILER1:
  119.     POP    H        ;GET FILE START ADDRESS
  120.     SDED    OFFSET        ;(OFFSET = 0 IF NO OPERAND)
  121.     JMP    FILER3
  122. ;
  123. FILER2:
  124.     CALL    HXREC
  125. FILER3:
  126.     LDED    OFFSET        ;GET LOAD OFFSET
  127.     ORA    A
  128.     DSUB            ;FORM LOAD ADDRESS
  129. LOADLP:
  130.     CALL    HEXBIN        ;GET A BYTE
  131.     MOV    M,A        ;PUT INTO MEMORY
  132.     SHLD    LDPOINT        ;SAVE LOAD ADDRESS POINTER
  133.     INX    H        ;BUMP THE LOAD ADDRESS
  134.     PUSH    H
  135.     LHLD    COUNT
  136.     INX    H        ;BUMP THE LOAD COUNT
  137.     SHLD    COUNT
  138.     POP    H
  139.     DCX    B        ;BC < NUMBER OF BYTES IN HEX RECORD
  140.     MOV    A,B
  141.     ORA    C
  142.     JNZ    LOADLP
  143.     CALL    HEXBIN        ;FETCH HEX RECORD CHECKSUM
  144.     XRA    A        ;RESET A
  145.     ADD    C        ;CHECKSUM ERROR?
  146.     JZ     ENDCHK        ;NO, CHECK FOR END
  147.     PUSH    H        ;YES, SAVE THE ADDRESS
  148.     LXI    H,MESG10    ;CHECKSUM ERROR MESSAGE
  149.     CALL    PTXT
  150.     POP    H        ;RESTORE THE ADDRESS
  151.     CALL    PADDR        ;PRINT ERROR ADDRESS
  152. ENDCHK:
  153.     LHLD    COUNT        ;COUNT OF BYTES LOADED
  154.     LBCD    OPR2        ;NUMBER OF BYTES REQUIRED
  155.     DCX    H
  156.     DCX    B
  157.     ANA    A
  158.     BSUB            ;MORE BYTES TO LOAD?
  159.     JC     FILER2        ;YES, GET THEM
  160. ;
  161. LDEND:
  162.     LXI    H,MESG11    ;LOAD END ADDR MESSAGE
  163.     CALL    PTXT
  164.     LHLD    LDPOINT        ;GET LOAD END ADDRESS
  165.     CALL    PADDR        ;PRINT HEX ADDRESS
  166. ;
  167. PPG10A:
  168.     CALL    CRLF
  169.     LXI    H,MESG4        ;READY TO PROG MESSAGE
  170.     CALL    PTXT
  171.     CALL    YORN        ;YES OR NO?
  172.     JNC     EXIT        ;NO, EXIT
  173. ;
  174. PPG11:
  175.     CALL    CRLF
  176.     LXI    H,MESG5        ;YES, MEM START ETC. MESSAGE
  177.     CALL    PTXT
  178.     CALL    SCAN$OP        ;GET OPERANDS
  179.     LDA    NXCHAR
  180.     CPI    '.'        ;ENTRY ABORT CHARACTER?
  181.     JZ     PPG11        ;YES, REPROCESS LOOP
  182.     JMP    PROG         ;NO, GO PROGRAM EPROM
  183. ;
  184. ;
  185. ; LOOKS FOR START OF A HEX RECORD AND RETURNS
  186. ; FIRST DATA BYTE IN A, BYTE COUNT IN B &
  187. ; RECORD LOAD ADDRESS IN HL
  188. ;
  189. ;
  190. HXREC:
  191.     CALL    BUFFR        ;GET AN ASCII BYTE
  192.     CPI    ':'        ;IS IT HEX RECORD START?
  193.     JNZ    HXREC        ;NO, KEEP LOOKING
  194.     XRA    A        ;RESET A
  195.     MOV    C,A        ;RESET C
  196.     CALL    HEXBIN        ;GET A 'HEX' BYTE
  197.     ANA    A        ;IS IT 0?
  198.     JZ     HXREC1        ;YES, MUST BE AT END
  199.     MOV    B,A        ;NO, # BYTES IN HEX RECORD
  200.     CALL    HEXBIN        
  201.     MOV    H,A        ;HI BYTE OF LOAD
  202.     CALL    HEXBIN
  203.     MOV    L,A        ;LO BYTE OF LOAD
  204.     CALL    HEXBIN        ;GET FIRST DATA BYTE
  205.     RET    
  206. ;
  207. HXREC1:
  208.     POP    PSW
  209.     JMP    LDEND 
  210. ;
  211. ;
  212. ; DETERMINE IF Y, N OR ABORT ANSWER
  213. ;
  214. ;
  215. YORN:
  216.     CALL    ECHO
  217.     CPI    '.'
  218.     JZ     EXIT
  219.     ORA    A
  220.     CPI    'N'
  221.     RZ    
  222.     CPI    'Y'
  223.     JNZ    YORN
  224.     STC 
  225.     RET    
  226. ;
  227. ;
  228. ; CONSOLE STATUS, INPUT AND OUTPUT
  229. ;
  230. ;
  231. CONSTAT:
  232.     PUSH    H
  233.     PUSH    D
  234.     PUSH    B
  235.     MVI    C,11
  236.     CALL    BDOS
  237.     POP    B
  238.     POP    D
  239.     POP    H
  240.     ORA    A
  241.     RET    
  242. ;
  243. CONIN:
  244.     PUSH    H
  245.     PUSH    D
  246.     PUSH    B
  247.     MVI    C,1
  248.     CALL    BDOS
  249.     POP    B
  250.     POP    D
  251.     POP    H
  252.     MOV    C,A        ;NEED A & C TO RETURN CHAR
  253.     RET    
  254. ;
  255. CONOUT:
  256.     PUSH    H
  257.     PUSH    D
  258.     PUSH    B
  259.     MOV    E,C
  260.     MVI    C,2
  261.     CALL    BDOS
  262.     POP    B
  263.     POP    D
  264.     POP    H
  265.     MOV    C,E        ;NEED C TO RETURN CHAR
  266.                 ;SENT
  267.     RET    
  268. ;
  269. ;
  270. ; CLOSE FILE AND EXIT BACK TO CP/M
  271. ;
  272. ;
  273. EXIT:
  274.     XRA    A
  275.     OUT    HACTL
  276.     CALL    CRLF
  277.     LDA    OPENFL
  278.     ORA    A
  279.     JZ     WBOOT
  280.     MVI    C,16
  281.     LXI    D,FCB
  282.     CALL    BDOS
  283.     JMP    WBOOT 
  284. ;
  285. ;
  286. ; PRINT VALUE IN ACCUMULATOR AS AN ASCII 'HEX' VALUE
  287. ;
  288. ;
  289. PADDR:
  290.     MOV    A,H        ;HI BYTE OF ADDRESS
  291.     CALL    PACC        ;PRINT A AS HEX VALUE
  292.     MOV    A,L        ;LO BYTE OF ADDRESS
  293.     JMP    PASP         ;PRINT<A, ' ' CRLF
  294. ;
  295. ;
  296. MESG1:
  297.     DB    ACR,ALF
  298.     DB    'Software Tools PROM-100 Driver utility for 2758/2716/2732 EPROMs'
  299.     DB    ACR,ALF
  300.     DB    'Version 1.13 for '
  301.     DB    SPEED + '0',' MHz Z80/8080, January 1982'
  302.     DB    ACR,ALF
  303.     DB    '$'
  304. ;
  305. MESG2:
  306.     DB    'Ready to load a hex file (Y/N)? '
  307.     DB    '$'
  308. ;
  309. MESG3:
  310.     DB    'Load address, Number of bytes to load : '
  311.     DB    '$'
  312. ;
  313. MESG4:
  314.     DB    'Ready to program a PROM  (Y/N)? '
  315.     DB    '$'
  316. ;
  317. MESG5:
  318.     DB    'Memory start, Memory end, PROM start  : '
  319.     DB    '$'
  320. ;
  321. MESG6:
  322.     DB    'Ready  to  read  a  PROM (Y/N)? '
  323.     DB    '$'
  324. ;
  325. MESG7:
  326.     DB    ACR,ALF
  327.     DW    ATTRIB
  328.     DB    '4'
  329.     DB    ' FILE NOT FOUND '
  330.     DW    ATTRIB
  331.     DB    '0'
  332.     DB    '$'
  333. ;
  334. MESG8:
  335.     DB    ACR,ALF
  336.     DW    ATTRIB
  337.     DB    '4'
  338.     DB    ' Attempting to read past end of disk file '
  339.     DW    ATTRIB
  340.     DB    '0'
  341.     DB    '$'
  342. ;
  343. MESG9:
  344.     DB    ACR,ALF
  345.     DB    'Load start address = '
  346.     DB    '$'
  347. ;
  348. MESG10:
  349.     DW    ATTRIB
  350.     DB    '4'
  351.     DB    'Checksum error at location : '
  352.     DW    ATTRIB
  353.     DB    '0'
  354.     DB    '$'
  355. ;
  356. MESG11:
  357.     DB    'Load end address   = '
  358.     DB    '$'
  359. ;
  360. ;
  361. ; PROM READ SEQUENCE
  362. ;
  363. ;
  364. READ2:
  365.     CALL    CRLF
  366.     LXI    H,MESG6        ;READY TO READ MESSAGE
  367.     CALL    PTXT
  368.     CALL    YORN
  369.     JNC     PPG10A        ;NO, THEN PROGRAM
  370. READ0:
  371.     CALL    CRLF
  372.     LXI    H,MESG5        ;MEM START ETC. MESSAGE
  373.     CALL    PTXT
  374.     CALL    SCAN$OP        ;INPUT PARAMETERS
  375.     LDA    NXCHAR
  376.     CPI    '.'
  377.     JZ     READ0
  378.     MVI    A,040H        ;TURN ON PROM VOLTAGE
  379.     OUT    HACTL    
  380.     LHLD    OPR1        ;MEM START ADDRESS
  381.     LDED    OPR3        ;PROM START ADDRESS
  382. READ1:
  383.     CALL    PREAD        ;READ A BYTE OF PROM
  384.     MOV    M,A        ;SAVE BYTE IN MEMORY
  385.     CALL    ADCMP        ;INC ADDRESS AND COMPARE
  386.     JNZ    READ1        ;IF NOT END, READ NEXT BYTE
  387.     XRA    A        ;TURN OFF PROM
  388.     OUT    HACTL
  389.     JMP    PPG10A         ;PROGRAM SEQUENCE
  390. ;
  391. ;
  392. ; INC HL & DE THEN COMPARE WITH (IX)
  393. ; EXIT WITH ZERO FLAG SET IF EQUAL
  394. ;
  395. ;
  396. ADCMP:
  397.     INX    D        ;INC PROM ADDRESS
  398.     MOV    A,D
  399.     ANI    00FH        ;MAX PROM ADDR =00FFFH
  400.     MOV    D,A
  401.     INX    H
  402.     PUSH    D
  403.     PUSH    H        ;SAVE HL & DE
  404.     LDED    OPR2        ;GET RAM END ADDRESS
  405.     INX    D
  406.     ANA    A
  407.     CPHL            ;COMPARE
  408.     POP    H
  409.     POP    D
  410.     RET    
  411. ;
  412. ;
  413. ; PROGRAMMING SEQUENCE
  414. ;
  415. ;
  416. PROG:
  417.     MVI    A,40
  418.     OUT    HACTL        ;TURN ON PROM VOLTAGE
  419.     LHLD    OPR1        ;MEM START ADDRESS
  420.     LDED    OPR3        ;PROM START ADDRESS
  421. PROG1:
  422.     CALL    PREAD        ;READ A BYTE FROM PROM
  423.     CPI    0FFH        ;ERASED?
  424.     JNZ    PROG2        ;NO, PRINT ERROR
  425. PROG1A:
  426.     CALL    ADCMP        ;INC ADDRESS & CHECK FOR END
  427.     JNZ    PROG1
  428.     JMP    PROG3        ;ALL OK, PROGRAM PROM
  429. ;
  430. PROG2:
  431.     PUSH    H
  432.     LXI    H,MESG13    ;NOT ERASED MESSAGE
  433.     CALL    PTXT
  434.     POP    H
  435.     IN    DATA
  436.     CALL    PRTER        ;PRINT BAD LOCATION
  437.     CALL    ECHO        ;READ CONSOLE
  438.     CPI    '.'        ;ABORT?
  439.     JZ     PROG9
  440.     CPI    'C'        ;CONTINUE?
  441.     JZ     PROG3
  442.     JMP    PROG1A        ;CHECK MORE LOCATIONS
  443. ;
  444. PROG2A:
  445.     MVI    A,000H
  446.     OUT    HACTL
  447.     JMP    INITIAL 
  448. ;
  449. PROG3:
  450.     CALL    CRLF
  451. PROG4:
  452.     LHLD    OPR1        ;MEM START ADDRESS
  453.     LDED    OPR3        ;PROM START ADRESS
  454. PROG5:
  455.     CALL    PPROG        ;PROGRAM ONE BYTE
  456.     CALL    CONSTAT
  457.     JZ     PROG5A
  458.     CALL    CONIN
  459.     CPI    '.'
  460.     JZ     PROG9
  461. PROG5A:
  462.     CALL    ADCMP        ;INC ADDRESS & CHECK FOR END
  463.     JNZ    PROG5        ;FINISH THIS LOOP
  464. ;
  465. PROG6:
  466.     MVI    A,0
  467.     OUT    HACTL        ;TURN OFF ALL CONTROL LINES
  468. PROG6A:
  469.     LHLD    OPR1        ;MEM START ADDRESS
  470.     LDED    OPR3        ;PROM START ADDRESS
  471. PROG7:
  472.     CALL    PREAD        ;READ PROM DATA
  473.     CMP    M        ;COMPARE TO MEMORY DATA
  474.     JNZ    PROG8        ;ERROR IF NOT MATCHED
  475. PROG7A:
  476.     CALL    ADCMP        ;INC ADDRESS & CHECK FOR END
  477.     JNZ    PROG7
  478.     JMP    PROG2A        ;EXIT, COMPLETE
  479. ;
  480. PROG8:
  481.     PUSH    PSW
  482.     PUSH    H
  483.     LXI    H,MESG14    ;BAD LOCATION MESSAGE
  484.     CALL    PTXT
  485.     POP    H
  486.     CALL    CONSTAT
  487.     JZ     PROG8A
  488.     CALL    CONIN
  489.     CPI    '.'        ;ABORT?
  490.     JZ     PROG9
  491. PROG8A:
  492.     POP    PSW
  493.     CALL    PRTER        ;PRINT THE ERROR MESSAGE
  494.     JMP    PROG7A        ;CHECK MORE LOCATIONS
  495. ;
  496. PROG9:
  497.     LXI    H,MESG15    ;ABORTED MESSAGE
  498.     CALL    PTXT
  499.     JMP    PROG2A
  500. ;
  501. ;
  502. ; PULSE ONE PROM LOCATION
  503. ;
  504. ;
  505. PPROG:
  506.     CALL    PADD        ;LATCH LSB OF ADDRESS
  507.     MOV    A,D
  508.     ANI    00FH        ;MAX ROM ADDRESS =00FFFH
  509.     ORI    0C0H
  510.     OUT    HACTL
  511.     MOV    A,M        ;FETCH DATA
  512.     OUT    DATA        ;OUTPUT TO PROM
  513.     MOV    A,D
  514.     ORI    0E0H        ;TURN ON PROGRAMING PULSE
  515.     OUT    HACTL
  516.     MVI    A,50
  517.     CALL    DELAY        ;1 MILLISEC DELAY
  518.     MOV    A,D
  519.     ORI    0C0H
  520.     ANI    0C7H        ;TURN OFF PROGRAMING PULSE
  521.     OUT    HACTL
  522.     RET    
  523. ;
  524. DELAY:
  525.     LXI    B,26 * SPEED    ;DELAY COUNT DEPENDS ON PROC SPEED
  526.     PUSH    PSW
  527. DELAY1:
  528.     DCX    B        ;ADJUST INNER COUNT
  529.     MOV    A,B
  530.     ORA    C        ;DONE?
  531.     JNZ    DELAY1         ;NO
  532.     POP    PSW        ;YES
  533.     DCR    A        ;ADJUST OUTER COUNT
  534.     JNZ    DELAY
  535.     RET    
  536. ;
  537. ;
  538. ; READ ONE LOCATION OF PROM
  539. ;
  540. ;
  541. PREAD:
  542.     CALL    PADD        ;LATCH LSB OF ADDRESS
  543.     MOV    A,D
  544.     ORI    40H
  545.     OUT    HACTL
  546.     IN    DATA
  547.     RET    
  548. ;
  549. ;
  550. ; LATCH LOWER 8 BITS OF PROM ADDRESS
  551. ;
  552. ;
  553. PADD:
  554.     MOV    A,E
  555.     OUT    LADD
  556.     RET    
  557. ;
  558. ;
  559. ; PRINTS ADDRESS, BAD DATA, GOOD DATA
  560. ; OF ERROR LOCATION
  561. ;
  562. ;
  563. PRTER:
  564.     MOV    B,A
  565.     MOV    A,D
  566.     CALL    PACC        ;PRINT MSB OF ADDRESS
  567.     MOV    A,E
  568.     CALL    PACC        ;PRINT LSB
  569.     MVI    C,' '
  570.     CALL    CONOUT
  571.     MOV    A,B
  572.     CALL    PACC        ;PRINT BAD DATA
  573.     MVI    C,' '
  574.     CALL    CONOUT
  575.     MOV    A,M
  576.     CALL    PACC        ;PRINT GOOD DATA
  577.     CALL    CRLF
  578.     RET    
  579. ;
  580. ;
  581. MESG13:
  582.     DW    ATTRIB
  583.     DB    '4'
  584.     DB    'Not Erased'
  585.     DW    ATTRIB
  586.     DB    '0'
  587.     DB    ' : '
  588.     DB    '$'
  589. ;
  590. MESG14:
  591.     DW    ATTRIB
  592.     DB    '4'
  593.     DB    'Bad location'
  594.     DW    ATTRIB
  595.     DB    '0'
  596.     DB    ' : '
  597.     DB    '$'
  598. ;
  599. MESG15:
  600.     DW    ATTRIB
  601.     DB    '4'
  602.     DB    ' ABORTED '
  603.     DW    ATTRIB
  604.     DB    '0'
  605.     DB    ACR,ALF
  606.     DB    '$'
  607. ;
  608. ;
  609. ; GET A BYTE FROM AN INTEL 'HEX' FORMAT FILE
  610. ; AND RETURN WITH IT IN BINARY FORM IN A
  611. ;
  612. ;
  613. HEXBIN:
  614.     CALL    BUFFR        ;GET AN ASCII BYTE
  615.     CALL    ASBIN        ;MAKE IT BINARY
  616.     RLC 
  617.     RLC 
  618.     RLC 
  619.     RLC 
  620.     PUSH    B
  621.     MOV    C,A
  622.     CALL    BUFFR
  623.     CALL    ASBIN
  624.     ORA    C
  625.     POP    B
  626.     PUSH    PSW
  627.     ADD    C
  628.     MOV    C,A
  629.     POP    PSW
  630.     RET    
  631. ;
  632. ;
  633. ; ASCII TO BINARY CONVERSION
  634. ;
  635. ;
  636. ASBIN:
  637.     SUI    '0'
  638.     CPI    10
  639.     RM    
  640.     SUI    007H
  641.     RET    
  642. ;
  643. ;
  644. ; UTILITY PRINT ROUTINES
  645. ;
  646. ;
  647. PASP:
  648.     PUSH    B
  649.     CALL    PACC
  650.     CALL    SPACE
  651.     CALL    CRLF
  652.     POP    B
  653.     RET    
  654. ;
  655. CRLF:
  656.     MVI    C,ACR
  657.     CALL    CONOUT
  658.     MVI    C,ALF
  659.     JMP    CONOUT 
  660. ;
  661. SPACE:
  662.     MVI    C,' '
  663.     JMP    CONOUT 
  664. ;
  665. PTXT:
  666.     MOV    A,M        ;FETCH A BYTE
  667.     CPI    '$'
  668.     RZ    
  669.     MOV    C,A
  670.     CALL    CONOUT
  671.     INX    H
  672.     JMP    PTXT 
  673. ;
  674. PACC:
  675.     PUSH    PSW
  676.     RRC 
  677.     RRC 
  678.     RRC 
  679.     RRC 
  680.     CALL    PRVAL
  681.     POP    PSW
  682. PRVAL:
  683.     ANI    00FH
  684.     ADI    090H
  685.     DAA
  686.     ACI    040H
  687.     DAA
  688.     MOV    C,A
  689.     JMP    CONOUT 
  690. ;
  691. ;
  692. ; CHECK FOR VALID ASCII 'HEX' CHARACTER
  693. ;
  694. ;
  695. AORN:
  696.     CPI    '0'
  697.     JC     AORN2
  698.     CPI    '9'+1
  699.     JC     AORN1
  700.     CPI    'A'-1
  701.     JC     AORN2
  702.     CPI    'F'+1
  703.     JNC     AORN2
  704. AORN1:
  705.     XRA    A
  706.     RET    
  707. ;
  708. AORN2:
  709.     XRA    A
  710.     INR    A
  711.     RET    
  712. ;
  713. ;
  714. ; CHECK FOR ENTRY TERMINATOR:
  715. ;
  716. ; SPACE, COMMA OR CARRIAGE RETURN
  717. ;
  718. ;
  719. TERMCHK:
  720.     CPI    ' '
  721.     RZ    
  722.     CPI    ','
  723.     RZ    
  724.     CPI    '.'
  725.     JZ     TCHK0
  726.     CPI    00DH
  727.     RNZ    
  728. TCHK0:
  729.     PUSH    B
  730.     CALL    CRLF
  731.     POP    B
  732.     XRA    A
  733.     RET    
  734. ;
  735. ;
  736. ; SCAN FOR OPERAND FROM CONSOLE
  737. ;
  738. ; EXIT WITH DATA IN HL, TERMINATOR
  739. ; IN C. IF VALID DATA, RETURN WITH
  740. ; ZERO FLAG SET. B CONTAINS NUMBER
  741. ; OF CHARACTERS ENTERED
  742. ;
  743. ;
  744. KEYIN:
  745.     LXI    H,0
  746.     MOV    B,L
  747. KEY1:
  748.     CALL    ECHO
  749.     INR    B        ;INC CHARACTER COUNT
  750.     CALL    TERMCHK        ;TERMINATOR?
  751.     RZ    
  752.     CALL    AORN        ;CHECK FOR VALID DATA
  753.     RNZ    
  754.     MOV    A,C
  755.     CALL    ASBIN        ;CONVERT TO BINARY
  756.     DAD    H
  757.     DAD    H
  758.     DAD    H
  759.     DAD    H        ;SHIFT 4 BITS
  760.     ADD    L
  761.     MOV    L,A
  762.     JMP    KEY1 
  763. ;
  764. ECHO:
  765.     JMP    CONIN         ;CP/M DOES ITS OWN ECHO
  766. ;
  767. INVCMD:
  768.     MVI    C,'?'
  769.     CALL    CONOUT
  770.     MVI    A,'.'
  771.     STA    NXCHAR
  772.     RET    
  773. ;
  774. SCAN$OP:
  775.     XRA    A        ;INITIALISE
  776.     STA    OPCNT
  777.     LXI    H,OPR1        ;CLEAR OPERANDS
  778.     SHLD    OP$POINT$
  779.     MOV    M,A        ;RESET HL
  780.     LXI    B,9
  781.     LXI    D,OPRS+1
  782. SCLOOP:
  783.     MOV    A,M        ;GET A BYTE
  784.     STAX    D        ;PUT A BYTE
  785.     INX    H        ;BUMP POINTERS
  786.     INX    D
  787.     DCX    B        ;ADJUST COUNT
  788.     MOV    A,B
  789.     ORA    C        ;DONE?
  790.     JNZ    SCLOOP        ;NO
  791. SCAN1:
  792.     CALL    KEYIN        ;GET 1 OPERAND FROM CONSOLE
  793.     JNZ     INVCMD
  794.     MOV    A,C
  795.     STA    NXCHAR
  796.     CPI    ' '
  797.     JZ     SCAN2
  798.     CPI    ','
  799.     JZ     SCAN2
  800.     DCR    B
  801.     RZ            ;RETURN IF NO DATA
  802. SCAN2:
  803.     PUSH    D        ;PRESERVE CONTENTS OF D
  804.     XCHG            ;DE < DATA
  805.     LHLD    OP$POINT    ;GET POINTER
  806.     MOV    M,E        ;PUT LOW BYTE
  807.     INX    H
  808.     MOV    M,D        ;PUT HIGH BYTE
  809.     INX    H
  810.     SHLD    OP$POINT    ;STORE POINTER
  811.     POP    D
  812.     LDA    OPCNT
  813.     INR    A        ;BUMP OPERAND COUNT
  814.     STA    OPCNT
  815.     MOV    A,C
  816.     CPI    ' '
  817.     JZ     SCAN1
  818.     CPI    ','
  819.     JZ     SCAN1
  820.     RET    
  821. ;
  822. BUFFR:
  823.     PUSH    H        ;SAVE,
  824.     PUSH    D        ;THE,
  825.     PUSH    B        ;ENVIRONMENT
  826.     LDA    BUFCNT        ;GET POS OF LAST BYTE
  827.                 ;READ FROM BUFFER
  828.     CPI    080H        ;AT END OF THE RECORD?
  829.     JNZ    BUFFR1        ;NO, GET NEXT BYTE
  830.     MVI    C,20        ;READ NEXT FILE RECORD
  831.     LXI    D,FCB        ;FCB ADDRESS
  832.     CALL    BDOS
  833.     ORA    A        ;SUCESSFUL READ?
  834.     JNZ    ERROR        ;NO, FINALISE THEN EXIT
  835.     XRA    A        ;YES, RESET A
  836. BUFFR1:
  837.     LXI    H,00080H    ;START OF DISK BUFFER
  838.     MOV    E,A        ;GET OFFSET TO LAST BYTE
  839.                 ;READ FROM BUFFER
  840.     INR    A        ;BUMP TO NEXT BYTE
  841.     STA    BUFCNT        ;SAVE NEW LOCATION
  842.     MVI    D,0        ;RESET DE
  843.     DAD    D        ;FORM ACTUAL ADDRESS
  844.     MOV    A,M        ;GET BYTE
  845.     POP    B        ;RESTORE
  846.     POP    D        ; THE
  847.     POP    H        ; ENVIRONMENT
  848.     RET    
  849. ;
  850. ERROR:
  851.     POP    B
  852.     POP    D
  853.     POP    H
  854.     LXI    H,MESG8        ;READ PAST EOF MESSAGE
  855.     CALL    PTXT
  856.     JMP    EXIT 
  857. ;
  858. COUNT:    DW    0
  859. OFFSET:    DB    0
  860. OPCNT:    DB    0
  861. NXCHAR:    DB    0
  862. OPENFL:    DB    0
  863. BUFCNT:    DB    0
  864. LDPOINT    DW    0
  865. OP$POINT DW    0
  866. OPRS:    DS    6
  867. OPR1    EQU    OPRS
  868. OPR2    EQU    OPRS+2
  869. OPR3    EQU    OPRS+4
  870. SPVAL    EQU    OPRS+100H
  871. ;
  872.     END
  873.