home *** CD-ROM | disk | FTP | other *** search
- ; SAVEVRAM.MAC
- ; program to try to grab contents of video RAM and store them
- ; in a file
- ; jbh, Feb 11, 1988, after the original Epson subroutine,
- ; but using BIOS RDVRAM routine instead
-
- ; John B. Haviland, 3312 SE Woodstock, Portland, OR 97202
-
- ; USAGE NOTES:
- ; The form is simply: >savevram filename
- ; where "filename" is the file where you want the screen contents to be filed
- ; THere are no further switches, and the program does not bother to check
- ; whether you are in screen mode 0,1,2 or not (it probably won't work in
- ; any mode but 0, I should think.)
- ;
- ; The program DOES check to see how many lines your virtual screen has in it,
- ; and it tries to capture them all. It strips trailing blanks, and puts in
- ; standard CR-LF line terminators. Because of the way the BIOS routine works,
- ; it can only capture data from the selected screen.
- ; (I use CONFIG to set up screen 1 on my PX8 to have 40 lines, limiting
- ; the other screen to only 8 lines, but allowing all 40 lines of screen 1 to
- ; be recovered to a file by SAVEVRAM.)
-
- ; I thought of this as either a DO-able routine to make such things as
- ; FIND and various directory programs more useful (by allowing you to save
- ; at least some of their output to file), or as a possible add-on to RTX--
- ; but I haven't had the time to do the whole job. I have combined it with
- ; the little NECRX program that captures files to the PX8 from a NEC PC8201a
-
- .z80
- ; CPM equates, and PX=8 stuff
- bios equ 1 ;wmboot addr
- bdos equ 5 ;BDOS function dispatch jump vector
- scrmode equ 0f2c9h ;current screen mode
- slvflg equ 0f358h ; slave comm. enable flag
- selscrn equ 0f2CAh ;0 or 1 depending on what screen is selected
- sc1lin equ 0f720h ;# of lines in screen 1 (mode 0)
- sc2lin equ 0f726h ;# of lines in screen 2
- ;
- ;
- aseg
- org 100h
- start:
- call calcrdv
- call create ;set up file to save screen
- cp 0ffh ;is disk directory full?
- jr z,exit ; if so, exit routine
- ; otherwise, the file is now open
- ; now check the screen selected and fill in the # of lines to read
- ld a,(selscrn)
- ld hl,sc1lin
- or a
- jr z,scr1
- ld hl,sc2lin
- scr1:
- ld a,(hl)
- dec a
- ld (lines),a ;don't bother to save the last screen line
- ; since at best it just has this program on it
- ; now read the lines
- xor a ;cheap zero for counters
- loop:
- inc a
- ld (count),a
- call readvram ;get data block from VRAM
- ld a,(count) ; increment block counter
- cp 40 ; have we written the whole screen?
- lines equ $-1
- jr nz,loop ; if not, go back and do it again
- ;
- ; now all screen is written to RAM,
- ; put in final ^Z
- ld hl,(nextadr)
- ld (hl),'Z'-40h
- ;now we need to write the file
- call wrfile
- jp 0
- ; routine to wrte file from buffer to (nextadr)
- wrfile:
- call setdma
- call write
- inc a
- jr z,exit ;if write fault, close the file and quit
- ; otherwise go on to next record
- ld de,128
- ld hl,(dmabuf)
- add hl,de
- ld (dmabuf),hl
- ex de,hl ;de has top dma addr
- ld hl,(nextadr)
- or a
- sbc hl,de ;see if dmabuf is above nextadr
- jr nc,wrfile
- ;otherwise the file is written
- exit:
- ;close the file
- call close
- jp 0 ;return to cpm
- ;
- ;subroutine to read VRAM in a block of 80 bytes
-
- readvram:
- ld a,(count) ;line number of data to be read
- ld c,a ; C holds line at start of read
- ld b,1 ;always start at left edge of screen
- ld de,80 ;read 80 chars
- ld hl,(nextadr) ;HL holds address for read
- rdv:
- call rdv ; call readvram routine
- ;now back up to last non-blank, and put in crlf
- ld hl,(nextadr)
- ld de,80
- add hl,de
- srchlp: dec hl
- ld a,(hl)
- cp ' '
- jr z,srchlp
- ; if we get here hl points to last non-blank on latest line
- inc hl
-
- ; subroutine to fix add crlf at end of line
- docrlf: ld (hl),CR
- inc hl
- ld (hl),LF
- inc hl
- ld (nextadr),hl
- ret
- ;
- CR equ 'M'-40h
- LF equ 'J'-40h
- ;
- ; calculate and set proper rdv address
- calcrdv:
- ld hl,(bios)
- ld a,75h
- add a,l
- ld l,a
- ld (rdv+1),hl
- ret
- ;
- ; subroutine to create data file
- create:
- xor a
- ld (fcbadr+12),a ;zero first FCB byte for safety
- ld hl,fcbadr+12
- ld de,fcbadr+13
- ld bc,25
- ldir ;and zero rest of FCB, too
- ld c,13 ;reset disks BDOS function
- call bdos
- ; call setdma
- call delete ;wipe out any preexisting file
- ld c,22
- file: ld de,fcbadr ;set up new FCB address
- file2: call bdos ;try to create
- ret ; calling routine must deal with errors
- ; set DMA
- setdma:
- ld c,26
- ld hl,(dmabuf)
- ex de,hl
- jr file2
- ;
- dmabuf: defw buffer
- ;
- ; write subroutine for each block
- write:
- ld c,21
- jr file
- ; close subroutine
- close:
- ld c,16
- jr file
- ;
- erase: call close
- delete: ld c,19
- jr file
- ;
- ; data storage area for all variables
-
- fcbadr equ 5ch ; default FCB from CPM
- count: db 0 ;block counter
- nextadr:
- defw buffer
- crlf: db CR,LF
- buffer equ $ ;this will be the buffer for the file
-
- end start