home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
DRI-archive
/
roche
/
GENGRAF.ASM
< prev
next >
Wrap
Assembly Source File
|
2009-12-11
|
16KB
|
695 lines
; GENGRAF.ASM
; -----------
;
; GSX-80 - GENGRAF.COM
;
; Disassembled by:
;
; ROCHE Emmanuel
; 8 rue HERLUISON
; 10000 TROYES
; FRANCE
; ------
;
;--------------------------------
;
PAGE 0 ; Listing without page breaks
;
ORG 0100H ; Standard CP/M-80 COMmand file
;
;--------------------------------
; List of ASCII characters used
;
lf equ 0AH ; Line Feed
cr equ 0DH ; Carriage Return
ctrlZ equ 1AH ; = End Of File
;
;--------------------------------
; List of BDOS functions used
;
BDOS equ 0005H ; Basic Disk Operating System
;
sysres equ 0 ; System reset
conout equ 2 ; Console output
pstring equ 9 ; Print string
openf equ 15 ; Open file
closef equ 16 ; Close file
deletef equ 19 ; Delete file
readf equ 20 ; Read sequential
writef equ 21 ; Write sequential
makef equ 22 ; Make file
renamef equ 23 ; Rename file
setDMA equ 26 ; Set DMA address
filsiz equ 35 ; Compute file size
;
;--------------------------------
; List of page zero locations used
;
reboot EQU 0000H ; Warm start
dskuse EQU 0004H ; Current disk and user number
topTPA EQU 0006H ; Address of top TPA
I$0010 EQU 0010H ; ----I
I$0020 EQU 0020H ; ----I
FCB1 EQU 005CH ; Default File Control Block 1
ZERtyp EQU 0065H ; First char of filetype in page zero
ZERcr EQU 007CH ; Current record position in page zero
ZERrrn EQU 007DH ; Random record number in page zero
DBUF EQU 0080H ; Default 128-byte disk buffer
;
C$CD02 EQU 0CD02H ; -C---
I$CDF9 EQU 0CDF9H ; ----I
I$FFF3 EQU 0FFF3H ; ----I
;
;--------------------------------
; List of offset inside Default FCB 1
;
FCBtyp equ 0009H ; First char of filetype in FCB
FCBex equ 000CH ; Current extent number in FCB
;
;======================================================================
; Start of first program
;
start1: DB 0C3H ; Jump opcode
;
word1: DW start2 ; Point to start of program
;
retone: DB 0C9H ; Return opcode
;
word2: DW 0000H ; ?
;
start3: LXI H,0001H ; HL = 1 (point to BIOS entry?)
SPHL ; Stack = above
CALL chkASG ; Check is ASSIGN.SYS is on disk
CALL readA ; Read ASSIGN.SYS file
MVI A,05H ; Number of drivers to try to load
PUSH PSW ;
LXI H,DMAbuf ; DMA buffer (source)
LXI D,DDnumb ; DD number (destination)
getbyt: MOV A,M ; Get a byte from ASSIGN.SYS
CPI ctrlZ ; = EOF?
JZ close3 ; Then Close ASSIGN.SYS
CPI 31H ; Is it a number?
JNC dozen ;
XRA A ; If < 1 then set to 0
JMP digit ;
;
;--------------------------------
;
dozen: SUI 30H ; Convert to binary number
ADD A ; (Multiplied by 10?)
MOV B,A ;
ADD A ;
ADD A ;
ADD B ;
digit: MOV B,A ;
INX H ;
MOV A,M ; Get a byte from ASSIGN.SYS
SUI 30H ; Convert to binary number
ADD B ;
STAX D ; Store it in DD number
XRA A ; Reset Reg-A to zero
INX D ;
STAX D ; 2nd byte of DD number = zero
INX D ;
INX H ; (Space separator in ASSIGN.SYS)
INX H ; (Point to drive letter)
CALL upper ; Convert to upper case
SUI 40H ; Convert to binary number
STAX D ; Store in DD list
INX D ; Point to next char in destination
INX H ; Point to next char in source
MVI C,08H ; 8 chars of device driver
DDname: CALL upper ; Convert to upper case
CPI ';' ; Start of comments? (end of DD name)
JZ fill1 ;
CPI cr ; End of line?
JNZ fill2 ;
fill1: MVI A,' ' ; Space for filling DD filename
DCX H ; Decrement counter
fill2: STAX D ; Put space in DD table
INX D ;
DCR C ; = 0?
JNZ DDname ; No: loop
MVI A,lf ; Yes: we must have reached the Line Feed
fill3: CMP M ; Isn't it?
INX H ;
JNZ fill3 ;
POP PSW ;
DCR A ; Loop 5 times
PUSH PSW ;
JNZ getbyt ; Get another byte from ASSIGN.SYS
close3: POP PSW ;
CALL closeA ; Close ASSIGN.SYS
LHLD topTPA ; Load address of top of TPA from page zero
SHLD savtop ; Save address of top of TPA
LXI D,DDlist ; Source: List of 5 DD filenames
LXI H,ASSIGN ; Destin: ASSIGN.SYS file spec
MVI C,09H ; 9 bytes (drive code + DD filename)
CALL copyDH ; Copy one file specification
MVI M,50H ; "P" (add PRL filetype)
INX H ;
MVI M,52H ; "R"
INX H ;
MVI M,4CH ; "L"
CALL C0278 ;
LHLD LOMEM ; New top of TPA after DD is loaded
SHLD savtop ; Save address of top of TPA
LXI D,GSXSYS ; Source: GDOS file specification
LXI H,ASSIGN ; Destin: ASSIGN.SYS file spec
MVI C,0CH ; 12 bytes (drive code + FILENAME.TYP)
CALL copyDH ; Copy one file specification
CALL C0278 ;
LHLD LOMEM ; Destin: New top of TPA after DD is loaded
PUSH H ;
LXI B,dskuse ; Current disk and user number
DAD B ;
LXI D,topTPA ; Source: Load address of top TPA
MVI C,02H ; 2 bytes
CALL copyDH ; Copy it in LOMEM
LXI D,DDnumb ; Source:
MVI C,02H ; 2 bytes
CALL copyDH ; Copy it in DDnumb
DCX D ;
DCX D ; Source:
MVI C,37H ; 55 bytes (5 times 11 bytes)
CALL copyDH ; Copy 5 file specifications
XCHG ;
INX D ;
INX D ;
MVI C,pstring ; Print string
CALL BDOS ;
LHLD word2 ; Load what?
POP D ;
DAD D ;
JNC ninofm ; 'not enough memory$'
XCHG ;
SHLD topTPA ; Store address of top TPA
MVI C,setDMA ; Set DMA address
LXI D,DBUF ; Default 128-bytes disk buffer
CALL BDOS ;
LXI D,reloc ; Source: Put RELOC address in Reg-DE
LHLD LOMEM ; Destin: New top of TPA after DD is loaded
LXI B,I$FFF3 ; Length of GSX.SYS (GDOS) ?
DAD B ;
PUSH H ;
SHLD GDOSb ; GDOS base
MVI C,0DH ; 13 bytes
CALL copyDH ; Copy a string in TPA
LXI H,border ; Limit between 1st and 2nd program
POP D ;
PUSH D ;
MOV A,E ;
SUB L ;
MOV C,A ;
MOV A,D ;
SBB H ;
MOV B,A ;
LXI D,start1 ; Start of first program
JMP retone ; Return opcode
;
;--------------------------------
; HL source
; DE destination
; BC count
;
reloc: MOV A,M ; Get a byte
STAX D ; Put it in destination
INX H ;
INX D ;
DCX B ; Decrement 16 bit counter
MOV A,B ;
ORA C ; If finished, then jump to GDOS
DB 0C2H ; JNZ opcode
GDOSb: DW 0000H ; GDOS base
JMP start1 ; Else: Start of first program
;
;--------------------------------
; Test if lower cases.
; If so, convert to upper cases.
;
upper: MOV A,M ; Get a byte
INX H ;
CPI 'a' ; Beginning of lower cases?
RC ;
CPI 'z'+1 ; End of lower cases?
RNC ;
SUI 20H ; Convert to upper cases
RET ;
;
;--------------------------------
; Copy a string in TPA from DE (source) to HL (destination)
;
; DE = source
; HL = destination
; C = number of bytes
;
copyDH: LDAX D ; Get a byte from source
MOV M,A ; Put it in TPA at destination HL
INX D ;
INX H ;
DCR C ; Decrement counter
JNZ copyDH ;
RET ;
;
;--------------------------------
;
ninofm: LXI D,notmem ; 'Not enough memory$'
JMP bak2CPM ;
;
;--------------------------------
;
notmem: DB 'Not enough memory$'
;
GSXSYS: DB 00H ; Default drive
DB 'GSX SYS' ; GDOS file specification
;
;--------------------------------
; Table of DDs
;
; Format:
; DW 0FFFFH is replaced by DD number (HI = DD number, LO = 00H)
; DB 00H is replaced by the drive number
; DS 8 is replaced by the DD filename
;
DDnumb: DW 0FFFFH
DDlist: DB 00H
DB ' ' ; First DD filename
;
DW 0FFFFH
DB 00H
DB ' ' ; Second DD filename
;
DW 0FFFFH
DB 00H
DB ' ' ; Third DD filename
;
DW 0FFFFH
DB 00H
DB ' ' ; Fourth DD filename
;
DW 0FFFFH
DB 00H
DB ' ' ; Fifth DD filename
;
;--------------------------------
;
C0278: CALL chkASG ; Check if ASSIGN.SYS is on disk
CALL readA ; Read ASSIGN.SYS file
LHLD DMA2nd ; DMA buffer 2nd byte (PRL program size)
PUSH H ;
XCHG ;
LHLD savtop ; Load address of top of TPA
MOV A,L ;
SUB E ;
MOV A,H ; Compute HIMEM - PRL program size
SBB D ;
MOV H,A ;
MVI L,00H ; Page boundary
SHLD LOMEM ; Store address of new top of TPA
PUSH H ;
PUSH H ;
PUSH D ;
CALL readA ; Read ASSIGN.SYS file
POP B ;
POP H ;
J$0298: CALL C02C8 ;
MOV M,A ;
INX H ;
DCX B ;
MOV A,C ;
ORA B ;
JNZ J$0298 ;
POP H ;
MOV B,H ;
DCR B ;
POP D ;
J$02A7: MVI C,08H ; 8
CALL C02C8 ;
J$02AC: RLC ;
PUSH PSW ;
JNC J$02B4 ;
MOV A,B ;
ADD M ;
MOV M,A ;
J$02B4: INX H ;
DCX D ;
MOV A,D ;
ORA E ;
JZ close2 ; Close ASSIGN.SYS
POP PSW ;
DCR C ;
JNZ J$02AC ;
JMP J$02A7 ;
;
;--------------------------------
;
close2: POP PSW ;
CALL closeA ; Close ASSIGN.SYS
RET ;
;
;--------------------------------
;
C02C8: PUSH H ;
PUSH D ;
LHLD D03B6 ;
INR L ;
JP J$02D9 ;
PUSH B ;
CALL readA ; Read ASSIGN.SYS file
POP B ;
LXI H,0000H ;
J$02D9: SHLD D03B6 ;
LXI D,DMAbuf ; DMA buffer
DAD D ;
MOV A,M ;
POP D ;
POP H ;
RET ;
;
;--------------------------------
; Check if file is on disk
;
chkASG: LXI D,ASSIGN ; ASSIGN.SYS file spec
chkfil: PUSH D ;
LXI H,FCBex ; Point to current extent number
DAD D ;
MVI M,00H ;
INX H ;
INX H ;
MVI M,00H ;
MVI A,80H ;
STA D03B6 ;
MVI C,openf ; Open file
CALL BDOS ;
POP D ;
LXI H,I$0020 ;
DAD D ;
MVI M,00H ;
badchk: ORA A ; Successful open/close?
RP ; Yes: return
CALL showFN ; No: Display filename on console
LXI D,notfnd ; ' not found$'
JMP bak2CPM ;
;
;--------------------------------
;
closeA: LXI D,ASSIGN ; ASSIGN.SYS file spec
MVI C,closef ; Close file
CALL BDOS ;
JMP badchk ; Cf. above
;
;--------------------------------
; Display filename on console
;
showFN: XCHG ;
MOV A,M ; Get drive code
ORA A ;
JZ nodriv ;
ADI 40H ; Convert drive code in letter
MOV E,A ;
CALL showit ;
MVI E,':' ; Drive separator
CALL showit ;
nodriv: INX H ;
MVI A,8+1 ; Filename
CALL loopri ;
MVI E,'.' ; Filename separator
CALL showit ;
MVI A,3+1 ; Filetype
CALL loopri ;
RET ;
;
;--------------------------------
; Display a char on console
;
showit: PUSH H ;
MVI C,conout ; Console output
CALL BDOS ;
POP H ;
RET ;
;
;--------------------------------
; Display n-1 chars on console
;
loopri: DCR A ; Done?
RZ ;
MOV E,M ; Get char
INX H ; Ready next char
PUSH PSW ;
CALL showit ; Display the char on console
POP PSW ;
JMP loopri ; Loop until done
;
;--------------------------------
; Read ASSIGN.SYS file
;
readA: LXI D,DMAbuf ; DMA buffer
MVI C,setDMA ; Set DMA address
CALL BDOS ;
LXI D,ASSIGN ; ASSIGN.SYS file spec
PUSH D ;
MVI C,readf ; Read sequential
CALL BDOS ;
POP D ;
ORA A ; Successful read?
RZ ; Yes: return
CALL showFN ; No: Display filename on console
LXI D,whyEOF ; ': unexpected EOF$'
bak2CPM:MVI C,pstring ; Print string
CALL BDOS ;
JMP reboot ; Warm start
;
;--------------------------------
;
whyEOF: DB ': unexpected EOF$'
;
notfnd: DB ' not found$'
;
ASSIGN: DB 00H ; Default drive
DB 'ASSIGN SYS' ; File specification
DS 24 ; Rest of FCB definition
;
savtop: DW 0000H ; Save area for top of TPA
;
LOMEM: DW 0000H ; Save area for new top of TPA,
; after a DD is loaded in TPA
;
D03B6: DW 0000H ; ?
;
DMAbuf: DB 00H ; DMA buffer first byte
;
DMA2nd: DB 00H ; DMA buffer second byte (PRL program size)
;
DS 126 ; Rest of 128-bytes buffer
;
;
;======================================================================
; Start of second program
;
start2: LXI D,copyr ; Copyright message
MVI C,pstring ; Print string
CALL BDOS ;
LXI H,ZERtyp ; First char of filetype in page zero
MVI M,43H ; "C" (add COM filetype)
INX H ;
MVI M,4FH ; "O"
INX H ;
MVI M,4DH ; "M"
LXI D,FCB1 ; Default FCB in page zero
MVI C,filsiz ; Compute file size
CALL BDOS ;
LHLD ZERrrn ; Random record number in page zero
DAD H ;
DAD H ;
DAD H ;
DAD H ;
DAD H ;
DAD H ;
DAD H ;
LXI D,I$048D ;
DAD D ;
MOV A,L ;
CMA ;
MOV L,A ;
MOV A,H ;
CMA ;
MOV H,A ;
INX H ;
SHLD word2 ; Save what?
XRA A ;
STA ZERcr ; Current record position set to zero
LXI H,FCB1 ; Source: Default FCB in page zero
LXI D,FCBseq ; Destin: FCB for read/write seq
PUSH D ;
MVI C,24H ; 36 bytes
CALL copyHD ;
POP D ;
PUSH D ;
LXI H,FCBtyp ; Point to first char of filetype
;
border: ; +++ Limit between 1st and 2nd program +++
;
DAD D ;
MVI M,24H ; "$" (temporary file)
INX H ;
MVI M,24H ; "$"
INX H ;
MVI M,24H ; "$"
MVI C,deletef ; Delete file
CALL BDOS ;
I$048D EQU $-1 ; ???
POP D ;
MVI C,makef ; Make file
CALL BDOS ;
INR A ;
JZ nodspc ; Display 'no dir space' on console
LXI H,start3 ; Relocate start of program
SHLD word1 ; Point to start of program
LXI D,start1 ; Start of first program
J$04A1: PUSH D ;
MVI C,setDMA ; Set DMA address
CALL BDOS ;
LXI D,FCBseq ; FCB for read/write seq
MVI C,writef ; Write sequential
CALL BDOS ;
POP D ;
LXI H,DBUF ; Default 128-bytes disk buffer
DAD D ;
XCHG ;
LXI H,start2 ; Start of second program
MOV A,E ;
SUB L ;
MOV A,D ;
SBB H ;
JC J$04A1 ;
LXI D,FCB1 ; Default FCB in page zero
CALL chkfil ; Check if file is on disk
J$04C5: MVI C,80H ;
LXI D,copyr ;
J$04CA: PUSH D ;
PUSH B ;
MVI C,setDMA ; Set DMA address
CALL BDOS ;
LXI D,FCB1 ; Default FCB in page zero
MVI C,readf ; Read sequential
CALL BDOS ;
STA errcod ; Error code (Read sequential)
ORA A ;
POP B ;
POP D ;
JNZ J04EE ;
DCR C ;
JZ J04EE ;
LXI H,DBUF ; Default 128-bytes disk buffer
DAD D ;
XCHG ;
JMP J$04CA ;
;
;--------------------------------
;
J04EE: MVI A,80H ;
SUB C ;
MOV C,A ;
LXI D,copyr ;
J$04F5: PUSH B ;
PUSH D ;
MVI C,setDMA ; Set DMA address
CALL BDOS ;
LXI D,FCBseq ; FCB for read/write seq
MVI C,writef ; Write sequential
CALL BDOS ;
ORA A ;
POP D ;
POP B ;
JNZ werror ; Display 'write error$' on console
DCR C ;
JZ J$0516 ;
LXI H,DBUF ; Default 128-bytes disk buffer
DAD D ;
XCHG ;
JMP J$04F5 ;
;
;--------------------------------
;
J$0516: LDA errcod ; Error code (Read sequential)
ORA A ;
JZ J$04C5 ;
LXI D,FCBseq ; FCB for read/write seq
MVI C,closef ; Close file
CALL BDOS ;
LXI D,FCB1 ;
MVI C,deletef ; Delete file
CALL BDOS ;
LXI D,FCBseq ; FCB for read/write seq
LXI H,I$0010 ;
DAD D ;
MVI C,10H ; 16 bytes
XCHG ;
CALL copyHD ;
LXI H,rentyp ;
MVI M,43H ; "C" (add COM filetype)
INX H ;
MVI M,4FH ; "O"
INX H ;
MVI M,4DH ; "M"
MVI C,renamef ; Rename file
LXI D,FCBseq ; FCB for read/write seq
CALL BDOS ;
MVI C,sysres ; System reset
JMP BDOS ;
;
;--------------------------------
; HL = source
; DE = destination
; C = count
;
copyHD: MOV A,M ; Get a byte
STAX D ; Put it in destination DE
INX H ;
INX D ;
DCR C ; Decrement count
JNZ copyHD ;
RET ;
;
;--------------------------------
;
werror: LXI D,wrierr ; 'Write Error.$'
JMP bak2CPM ;
;
;--------------------------------
;
nodspc: LXI D,nodirs ; 'No Directory Space.$'
JMP bak2CPM ;
;
;--------------------------------
;
errcod: DB 00H ; Error code (Read sequential)
;
DB 00H ; (Byte added by linker?)
;
FCBseq: DB 00H ; FCB for read/write seq
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H
;
rentyp: DB 00H,00H,00H ; Filetype for renaming filename.COM
DB 00H,00H,00H,00H,00H,00H,00H,00H
;
;--------------------------------
;
wrierr: DB 'Write Error.$'
;
nodirs: DB 'No Directory Space.$'
;
copyr: DB '---------------------------------------------------', cr, lf
DB 'GENGRAF 1.0 15 Nov 82 Serial No 5000-1232-654321', cr, lf
DB 'Copyright (C) 1982 ', cr, lf
DB 'Digital Research, Inc. All Rights Reserved', cr, lf
DB '---------------------------------------------------', cr, lf, '$'
;
;--------------------------------
;
END 100H ; Standard CP/M-80 COMmand file