home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol236 / print.mqc / PRINT.MAC
Encoding:
Text File  |  1986-02-11  |  9.6 KB  |  298 lines

  1.         title print program
  2.  
  3.         .comment *
  4.  
  5. This program should be loaded as an 'rsx'. Its function is to print a file on
  6. the standard listing device while, at the same time, the computer can continue
  7. most normal operations.
  8.  
  9. The call is
  10.  
  11. print filename.typ
  12.  
  13. Console read operations are intercepted and listing continues while the main
  14. program waits for input.
  15.  
  16. The program is organized as two coroutines. The first being the code
  17. intercepting the calls to the bios and the second being the listing program.
  18. Switching between the coroutines is carried out by the subroutine 'switch'.
  19.  
  20.                  *
  21.  
  22.                         ; rsx print program
  23.         .z80
  24.  
  25.                         ; standard rsx heading
  26. serial: db 0,0,0,0,0,0
  27.         jp ftest        ; entry point
  28. next:   jp 0            ; jump to next module
  29. prev:   dw 2            ; previous module
  30. remove: db 0            ; set to 0ffh to delete this rsx
  31. nonbnk: db 0            ; no bank flag
  32. name:   db 'print   '   ; name - 8 bits
  33. loader: db 0            ; loader flag
  34.         db 0,0          ; reserved
  35.  
  36.                         ; macros
  37. bdce    macro ?c,?e     ; set c and e, then call bdos
  38.         ld c,?c         ; bdos code
  39.         ld e,?e         ; argument
  40.         call bdos
  41.         endm
  42.  
  43. bdcde   macro ?c,?de    ; set c and de, then call bdos
  44.         ld c,?c         ; bdos code
  45.         ld de,?de       ; argument
  46.         call bdos
  47.         endm
  48.  
  49. ftest:                  ; check if finished
  50.         ld a,(remove)   ; non-zero if finished
  51.         and a           ; set flags
  52.         jr nz,next
  53.  
  54.     ld a,(first)    ; check for first time through (first is set to 0 when
  55.     and a           ; set flags \\ other print instructions are complete.
  56.     jr nz,firstx    ; routine for first time through
  57.  
  58.         ld a,c          ; bdos code
  59.         cp 10           ; buffer read
  60.         jr z,rd
  61.         cp 1            ; check if read
  62.         jr z,rd
  63.         cp 6            ; direct io
  64.     jr nz,next
  65.     ld a,e
  66.     cp 0fdh         ; code for wait for entry
  67.         jr z,rd
  68.         jr next
  69.  
  70. rd:                     ; keep calling pr until console receives input
  71.         push bc         ; must keep bc,de
  72.         push de
  73. rd1:    bdce dcio,0feh  ; to get input status
  74.         and a           ; set flags
  75.         jr nz,exit      ; exit if character waiting
  76.         call switch
  77.         jr rd1          ; keep running printer if waiting for console entry
  78.  
  79. firstx: push bc         ; unconditionally call print coroutine and exit
  80.     push de
  81.     call switch
  82.  
  83. exit:   pop de          ; recover registers
  84.         pop bc
  85.         jr next
  86.  
  87. ;-------------------------------------------------------------------------------
  88.  
  89. pr:                     ; print coroutine
  90.  
  91.                         ; copy file spec
  92.         ld hl,5ch       ; parsed command string file name
  93.         ld de,fcb       ; where it will be stored
  94.         ld bc,33        ; number of bytes to be copied
  95.         ldir            ; block copy
  96.         xor a           ; clear a
  97.         ld hl,fcb
  98.         ld bc,12
  99.         add hl,bc
  100.         ld (hl),a       ; extent
  101.         ld bc,20
  102.         add hl,bc
  103.         ld (hl),a       ; record
  104.                         ; state drive explicitly
  105.         ld a,(fcb)      ; get disk
  106.         and a           ; set flags
  107.         jr nz,drvsp     ; drive specified
  108.         ld c,rcd        ; get current drive
  109.         call bdos
  110.         inc a           ; for fcb, increment by 1
  111.         ld (fcb),a      ; store in fcb
  112. drvsp:
  113.  
  114.                         ; open file
  115.         bdcde open,fcb
  116.         and a           ; set flags
  117.         jp nz,err3      ; exit if file not opened
  118.  
  119.                         ; is another file being printed with print?
  120.         ld hl,(next+1)  ; entry of next routine
  121.     ld (olddma),hl  ; keep in olddma
  122. search: ld hl,(olddma)  ; entry of routine
  123.     ld de,18
  124.     add hl,de       ; points to loader flag
  125.     ld a,(hl)       ; get loader flag
  126.     and a           ; set flags
  127.     jr nz,s4        ; this is the loader - so print not found
  128.     ld de,-8
  129.     add hl,de       ; hl now points to module's name
  130.     ld de,name      ; de points to 'print   '
  131.     ld bc,8         ; number of bytes to be compared
  132. s1:    ld a,(de)       ; get byte from (de)
  133.     cpi             ; compare with byte from (hl), update hl,bc
  134.     inc de          ; advance de
  135.     jr nz,s3        ; not 'print   '
  136.     jp pe,s1        ; cycle if iterations are to continue
  137.     ld hl,(olddma)  ; has found another 'print   ' module
  138.     ld de,8
  139.     add hl,de       ; points to remove flag
  140. s2:    ld a,(hl)       ; remove flag = 0 if module active
  141.     and a           ; set flags
  142.     jr nz,s4        ; continue with program
  143.     push hl         ; keep address
  144.     call switch     ; wait
  145.     pop hl
  146.     jr s2           ; check remove flag
  147.  
  148. s3:    ld hl,(olddma)  ; to get to next module
  149.     ld de,4         ; offset to next module address
  150.     add hl,de       ; points to next module address
  151.     ld e,(hl)       ; get next module address to de
  152.     inc hl
  153.     ld d,(hl)
  154.     ld (olddma),de  ; store it
  155.     jr search
  156.  
  157. s4:     xor a           ; clear a
  158.     ld (first),a    ; clear first time indicator
  159.  
  160. cycle:                  ; read/print cycle
  161.                         ; get current dma
  162.         ld a,03ch       ; offset in scb
  163.         ld (scbpb),a    ; send it to scb parameter block
  164.         bdcde gsscb,scbpb
  165.         ld (olddma),hl  ; keep it
  166.  
  167.                         ; get current multisector count
  168.         ld a,04ah       ; offset in scb
  169.         ld (scbpb),a    ; send it to scb parameter block
  170.         bdcde gsscb,scbpb
  171.         ld (oldcnt),a   ; keep it
  172.  
  173.                         ; get current multisector error mode
  174.         ld a,04bh       ; offset in scb
  175.         ld (scbpb),a    ; send it to scb parameter block
  176.         bdcde gsscb,scbpb
  177.         ld (oldem),a    ; keep it
  178.  
  179.         bdcde dma,buff  ; set dma
  180.         bdce count,1    ; set multisector count = 1
  181.         bdce errmde,0ffh; set bdos error mode
  182.  
  183.         bdcde read,fcb  ; read disk
  184.         push af         ; keep a
  185.  
  186.                         ; reset dma, multisector count, error mode
  187.         bdcde dma,(olddma)
  188.         ld a,(oldcnt)
  189.         bdce count,e
  190.         ld a,(oldem)
  191.         bdce errmde,a
  192.  
  193.                         ; check read status
  194.         pop af          ; recover a
  195.         cp 1            ; check for end of file
  196.         jr z,finish
  197.         and a           ; set flags
  198.         jr nz,err       ; read fails
  199.  
  200.         ld hl,buff      ; buffer location
  201.         ld b,128        ; counter
  202.  
  203. scan:                   ; scan buffer
  204.         ld a,(hl)       ; get character
  205.         and 127         ; delete sign bit
  206.         cp cntrz        ; check for end of file
  207.         jr z,finish
  208.         ld c,a          ; character to c
  209.         push hl         ; keep hl
  210.         push bc         ; keep bc
  211.  
  212. poll:   call switch
  213.         ld de,42        ; list status offset on jump vector
  214.         call jmpvec     ; call jump vector
  215.         and a           ; set flags
  216.         jr z,poll       ; poll if not ready
  217.  
  218.         pop bc          ; get character in c
  219.         push bc
  220.  
  221.         ld de,12        ; list offset on jump vector
  222.         call jmpvec     ; call jump vector
  223.         
  224.         pop bc
  225.         pop hl
  226.         inc hl          ; increment buffer address
  227.         djnz scan       ; increment b and scan
  228.         jp cycle        ; get next block
  229.  
  230. jmpvec:                 ; jump vector access; expect offset in de
  231.         ld hl,(1)       ; jump vector
  232.         add hl,de       ; points to jump
  233.         jp (hl)         ; jump to it    
  234.  
  235.                         ; error message
  236. mess1:  db cr,lf, '*** disk read error, printing aborted ***'
  237. ccb1:   dw mess1,43     ; data for print block function
  238. err:    bdcde lstblk,ccb1
  239.         jr finish
  240.  
  241.                         ; end of print, send bell and formfeed
  242. mess2:  db bell,ff
  243. ccb2:   dw mess2,2
  244. finish: bdcde lstblk,ccb2
  245.  
  246.         ld a,0ffh       ; to show printing finished & clear rsx
  247.         ld (remove),a
  248. fc:     call switch     ; main program coroutine
  249.         jr fc           ; keep cycling till grabbed by console
  250.  
  251. mess3:  db cr,lf,'file cannot be opened$'
  252. err3:   bdcde prstr,mess3
  253.         ld a,0ffh       ; to show printing finished & clear rsx
  254.         ld (remove),a
  255.         jp 0            ; return to cpm
  256.  
  257. switch:                 ; routine to switch between coroutines
  258.         ld hl,0         ; get stack pointer
  259.         add hl,sp
  260.         ld sp,namex
  261.         ex (sp),hl      ; exchange 'namex' and old sp
  262.         ld sp,hl        ; update stack pointer
  263.         ret     
  264.  
  265. buff:   ds 128          ; disk buffer
  266. fcb:    ds 33           ; fcb
  267.         ds 30           ; auxiliary stack
  268. istack: dw pr           ; entry point for coroutine
  269. namex:  dw istack       ; points auxiliary stack
  270. olddma: ds 2            ; old dma, also used in rsx module search
  271. oldcnt: ds 1            ; old count
  272. oldem:  ds 1            ; old error mode
  273. first:  db 0ffh         ; set to 0 when routine starts
  274. scbpb:  ds 1            ; scb parameter block, first loc = offset
  275.         db 0            ; to get a byte or word
  276.  
  277. bell    equ 7           ; bell
  278. lf      equ 0ah         ; line feed
  279. ff      equ 0ch         ; form feed
  280. cr      equ 0dh         ; carriage return
  281. cntrz   equ 1ah         ; control z
  282.  
  283. bdos    equ next
  284. list    equ 5           ; list character
  285. dcio    equ 6           ; direct console io
  286. prstr   equ 9           ; print string
  287. open    equ 15          ; open file
  288. read    equ 20          ; read sequential
  289. rcd     equ 25          ; return current drive
  290. dma     equ 26          ; set dma
  291. count   equ 44          ; multisector count
  292. errmde  equ 45          ; set bdos error mode
  293. gsscb   equ 49          ; get/set scb
  294. lstblk  equ 112         ; list block
  295.  
  296.     end
  297.  
  298.