home *** CD-ROM | disk | FTP | other *** search
- title print program
-
- .comment *
-
- This program should be loaded as an 'rsx'. Its function is to print a file on
- the standard listing device while, at the same time, the computer can continue
- most normal operations.
-
- The call is
-
- print filename.typ
-
- Console read operations are intercepted and listing continues while the main
- program waits for input.
-
- The program is organized as two coroutines. The first being the code
- intercepting the calls to the bios and the second being the listing program.
- Switching between the coroutines is carried out by the subroutine 'switch'.
-
- *
-
- ; rsx print program
- .z80
-
- ; standard rsx heading
- serial: db 0,0,0,0,0,0
- jp ftest ; entry point
- next: jp 0 ; jump to next module
- prev: dw 2 ; previous module
- remove: db 0 ; set to 0ffh to delete this rsx
- nonbnk: db 0 ; no bank flag
- name: db 'print ' ; name - 8 bits
- loader: db 0 ; loader flag
- db 0,0 ; reserved
-
- ; macros
- bdce macro ?c,?e ; set c and e, then call bdos
- ld c,?c ; bdos code
- ld e,?e ; argument
- call bdos
- endm
-
- bdcde macro ?c,?de ; set c and de, then call bdos
- ld c,?c ; bdos code
- ld de,?de ; argument
- call bdos
- endm
-
- ftest: ; check if finished
- ld a,(remove) ; non-zero if finished
- and a ; set flags
- jr nz,next
-
- ld a,(first) ; check for first time through (first is set to 0 when
- and a ; set flags \\ other print instructions are complete.
- jr nz,firstx ; routine for first time through
-
- ld a,c ; bdos code
- cp 10 ; buffer read
- jr z,rd
- cp 1 ; check if read
- jr z,rd
- cp 6 ; direct io
- jr nz,next
- ld a,e
- cp 0fdh ; code for wait for entry
- jr z,rd
- jr next
-
- rd: ; keep calling pr until console receives input
- push bc ; must keep bc,de
- push de
- rd1: bdce dcio,0feh ; to get input status
- and a ; set flags
- jr nz,exit ; exit if character waiting
- call switch
- jr rd1 ; keep running printer if waiting for console entry
-
- firstx: push bc ; unconditionally call print coroutine and exit
- push de
- call switch
-
- exit: pop de ; recover registers
- pop bc
- jr next
-
- ;-------------------------------------------------------------------------------
-
- pr: ; print coroutine
-
- ; copy file spec
- ld hl,5ch ; parsed command string file name
- ld de,fcb ; where it will be stored
- ld bc,33 ; number of bytes to be copied
- ldir ; block copy
- xor a ; clear a
- ld hl,fcb
- ld bc,12
- add hl,bc
- ld (hl),a ; extent
- ld bc,20
- add hl,bc
- ld (hl),a ; record
- ; state drive explicitly
- ld a,(fcb) ; get disk
- and a ; set flags
- jr nz,drvsp ; drive specified
- ld c,rcd ; get current drive
- call bdos
- inc a ; for fcb, increment by 1
- ld (fcb),a ; store in fcb
- drvsp:
-
- ; open file
- bdcde open,fcb
- and a ; set flags
- jp nz,err3 ; exit if file not opened
-
- ; is another file being printed with print?
- ld hl,(next+1) ; entry of next routine
- ld (olddma),hl ; keep in olddma
- search: ld hl,(olddma) ; entry of routine
- ld de,18
- add hl,de ; points to loader flag
- ld a,(hl) ; get loader flag
- and a ; set flags
- jr nz,s4 ; this is the loader - so print not found
- ld de,-8
- add hl,de ; hl now points to module's name
- ld de,name ; de points to 'print '
- ld bc,8 ; number of bytes to be compared
- s1: ld a,(de) ; get byte from (de)
- cpi ; compare with byte from (hl), update hl,bc
- inc de ; advance de
- jr nz,s3 ; not 'print '
- jp pe,s1 ; cycle if iterations are to continue
- ld hl,(olddma) ; has found another 'print ' module
- ld de,8
- add hl,de ; points to remove flag
- s2: ld a,(hl) ; remove flag = 0 if module active
- and a ; set flags
- jr nz,s4 ; continue with program
- push hl ; keep address
- call switch ; wait
- pop hl
- jr s2 ; check remove flag
-
- s3: ld hl,(olddma) ; to get to next module
- ld de,4 ; offset to next module address
- add hl,de ; points to next module address
- ld e,(hl) ; get next module address to de
- inc hl
- ld d,(hl)
- ld (olddma),de ; store it
- jr search
-
- s4: xor a ; clear a
- ld (first),a ; clear first time indicator
-
- cycle: ; read/print cycle
- ; get current dma
- ld a,03ch ; offset in scb
- ld (scbpb),a ; send it to scb parameter block
- bdcde gsscb,scbpb
- ld (olddma),hl ; keep it
-
- ; get current multisector count
- ld a,04ah ; offset in scb
- ld (scbpb),a ; send it to scb parameter block
- bdcde gsscb,scbpb
- ld (oldcnt),a ; keep it
-
- ; get current multisector error mode
- ld a,04bh ; offset in scb
- ld (scbpb),a ; send it to scb parameter block
- bdcde gsscb,scbpb
- ld (oldem),a ; keep it
-
- bdcde dma,buff ; set dma
- bdce count,1 ; set multisector count = 1
- bdce errmde,0ffh; set bdos error mode
-
- bdcde read,fcb ; read disk
- push af ; keep a
-
- ; reset dma, multisector count, error mode
- bdcde dma,(olddma)
- ld a,(oldcnt)
- bdce count,e
- ld a,(oldem)
- bdce errmde,a
-
- ; check read status
- pop af ; recover a
- cp 1 ; check for end of file
- jr z,finish
- and a ; set flags
- jr nz,err ; read fails
-
- ld hl,buff ; buffer location
- ld b,128 ; counter
-
- scan: ; scan buffer
- ld a,(hl) ; get character
- and 127 ; delete sign bit
- cp cntrz ; check for end of file
- jr z,finish
- ld c,a ; character to c
- push hl ; keep hl
- push bc ; keep bc
-
- poll: call switch
- ld de,42 ; list status offset on jump vector
- call jmpvec ; call jump vector
- and a ; set flags
- jr z,poll ; poll if not ready
-
- pop bc ; get character in c
- push bc
-
- ld de,12 ; list offset on jump vector
- call jmpvec ; call jump vector
-
- pop bc
- pop hl
- inc hl ; increment buffer address
- djnz scan ; increment b and scan
- jp cycle ; get next block
-
- jmpvec: ; jump vector access; expect offset in de
- ld hl,(1) ; jump vector
- add hl,de ; points to jump
- jp (hl) ; jump to it
-
- ; error message
- mess1: db cr,lf, '*** disk read error, printing aborted ***'
- ccb1: dw mess1,43 ; data for print block function
- err: bdcde lstblk,ccb1
- jr finish
-
- ; end of print, send bell and formfeed
- mess2: db bell,ff
- ccb2: dw mess2,2
- finish: bdcde lstblk,ccb2
-
- ld a,0ffh ; to show printing finished & clear rsx
- ld (remove),a
- fc: call switch ; main program coroutine
- jr fc ; keep cycling till grabbed by console
-
- mess3: db cr,lf,'file cannot be opened$'
- err3: bdcde prstr,mess3
- ld a,0ffh ; to show printing finished & clear rsx
- ld (remove),a
- jp 0 ; return to cpm
-
- switch: ; routine to switch between coroutines
- ld hl,0 ; get stack pointer
- add hl,sp
- ld sp,namex
- ex (sp),hl ; exchange 'namex' and old sp
- ld sp,hl ; update stack pointer
- ret
-
- buff: ds 128 ; disk buffer
- fcb: ds 33 ; fcb
- ds 30 ; auxiliary stack
- istack: dw pr ; entry point for coroutine
- namex: dw istack ; points auxiliary stack
- olddma: ds 2 ; old dma, also used in rsx module search
- oldcnt: ds 1 ; old count
- oldem: ds 1 ; old error mode
- first: db 0ffh ; set to 0 when routine starts
- scbpb: ds 1 ; scb parameter block, first loc = offset
- db 0 ; to get a byte or word
-
- bell equ 7 ; bell
- lf equ 0ah ; line feed
- ff equ 0ch ; form feed
- cr equ 0dh ; carriage return
- cntrz equ 1ah ; control z
-
- bdos equ next
- list equ 5 ; list character
- dcio equ 6 ; direct console io
- prstr equ 9 ; print string
- open equ 15 ; open file
- read equ 20 ; read sequential
- rcd equ 25 ; return current drive
- dma equ 26 ; set dma
- count equ 44 ; multisector count
- errmde equ 45 ; set bdos error mode
- gsscb equ 49 ; get/set scb
- lstblk equ 112 ; list block
-
- end
-
-