Files
SharpMZ/software/asm/mz-1e14.asm
Philip Smart 4a64af4a00 Initial commit
2019-10-25 17:16:34 +01:00

1484 lines
44 KiB
NASM

; V1.01
;
; To compile use:
;
; AS80 [1.31] - Assembler for 8080/8085/Z80 microprocessor.
;
; Available from:
; - http://www.falstaff.demon.co.uk/cross.html
; - ftp://ftp.simtel.net/pub/simtelnet/msdos/crossasm/as80_131.zip
; - and many Simtel mirrors.
;
; as80 -i -l -n -x2 -v mz-1e14.asm
SIOAD EQU 0F4h
SIOBD EQU 0F5h
SIOAC EQU 0F6h
SIOBC EQU 0F7h
; RxD_A <- RDDT (ReaDDaTa)
; RxC_A <- (read data clock)
; TxD_A -> #WRDT (WRiteDaTa)
; TxC_A <- 6.5MHz / 4 / 16 = 101562,5Hz
; CTS_A <- #WRPR (WRitePRotect)
; RTS_A -> #WRGA (WRiteGAte)
; DCD_A <- #HDST (HeaDSeT (disk test)
;
; RTS_B -> (?)
; DCD_B <- #HOME ()
; DTR_B -> #MTON (MoTorON)
GETL EQU 00003h
NL EQU 00009h
PRNT EQU 00012h
GETKY EQU 0001Bh
BRKEY EQU 0001Eh
CMY0 EQU 0005Bh
MSGE1 EQU 00147h
DOT4DE EQU 002A6h
?TMST EQU 00308h
SPHEX EQU 003B1h
SLPT EQU 003D5h
HLHEX EQU 00410h
_2HEX EQU 0041Fh
?WRI EQU 00436h
LLPT EQU 00470h
?WRD EQU 00475h
?RDI EQU 004D8h
?RDD EQU 004F8h
?VRFY EQU 00588h
NLPHL EQU 005FAh
?KEY EQU 008CAh
?PRTS EQU 00920h
MSGOK EQU 00942h
PRNT3 EQU 0096Ch
MSGSV EQU 0098Bh
MSG?2 EQU 009A0h
?BRK EQU 00A32h
?ADCN EQU 00BB9h
?BLNK EQU 00DA6h
?DPCT EQU 00DDCh
BRKCD EQU 00
NTFECD EQU 40
HDERCD EQU 41
WPRTCD EQU 46
QNTRCD EQU 50
NFSECD EQU 53
UNFMCD EQU 54
ATRB EQU 010F0h
NAME EQU 010F1h
SIZE EQU 01102h
DTADR EQU 01104h
EXADR EQU 01106h
COMNT EQU 01108h
NAMSIZ EQU 011h
OBJCD EQU 001h
; QD command table
QDPA EQU 01130h ; QD code 1
QDPB EQU 01131h ; QD code 2
QDPC EQU 01132h ; QD header startaddress
QDPE EQU 01134h ; QD header length
QDCPA EQU 0113Bh ; QD error flag
HDPT EQU 0113Ch ; QD new headpoint possition
HDPT0 EQU 0113Dh ; QD actual headpoint possition
FNUPS EQU 0113Eh
FNUPF EQU 01140h
FNA EQU 01141h ; File Number A (actual file number)
FNB EQU 01142h ; File Number B (next file number)
MTF EQU 01143h ; QD motor flag
RTYF EQU 01144h
SYNCF EQU 01146h ; SyncFlags
RETSP EQU 01147h
DSPXY EQU 01171h
DPRNT EQU 01194h
SWRK EQU 0119Dh
BUFER EQU 011A3h
QDIRBF EQU 0CD90h
; Macro to align boundaries.
ALIGN: MACRO ?boundary
DS ?boundary - 1 - ($ + ?boundary - 1) % ?boundary, 0FFh
ENDM
ORG 0E800h
MZ1E14:
LE800:
NOP
JP LE80A
JP ST1X
QDIOS:
JP QDIOS1
LE80A:
LD A,0C6h ; clear screen
CALL ?DPCT
XOR A
LD (DPRNT),A
DI
XOR A
LD DE,00000h
CALL ?TMST
LD A,001h
OUT (SIOBC),A ; select Write Register 1
XOR A
OUT (SIOBC),A ; Rx INT DISABLE
CALL GETKY
CP 'M'
JR Z,MON
CP 'Q'
JR Z,QBT
CALL LEB22 ; check ROM at 0xF000 (FDD)
CALL Z,0F006h
JR QBT
;
;===============================
;
; Quick disk boot-up
;
;===============================
;
QBT:
CALL IOFRS ; IO Flag ReSet
CALL NL
CALL QDRCK ; QuickDisk Ready ChecK
JR C,LE868
LD A,00Dh ; set filename to ""
LD (BUFER),A
CALL HDPCL ; HeaD Point CLear
;
; Error return set
;
LD A,001h
LD (QDCPA),A
LD HL,LE86B
LD SP,010EEh
EX (SP),HL
;
;
CALL FILSCH ; filesearch
JP C,LEBAC
LD A,(ATRB)
CP OBJCD ; is it an "OBJ" file
JR NZ,LE871
;
; Quick disk boot
;
LD DE,LEB27
RST 018h
JP DSFLNA
LE868:
LD DE,LEB37
LE86B:
CALL NL
RST 018h
JR LE87D
LE871:
LD A,006h ; Motor off
LD (QDPA),A
CALL QDIOS
LD DE,LED4C
RST 018h
LE87D:
CALL NL
MON:
LD DE,DISCLR ; '** MONITOR 9Z-503M **'
RST 018h
ST1X:
CALL NL
LD A,'*'
CALL PRNT
LD DE,BUFER
CALL GETL
ST2X:
LD A,(DE)
INC DE
CP 00Dh
JR Z,ST1X
CP 'J' ; JUMP
JR Z,GOTOX
CP 'L' ; Load CMT
JR Z,LOADX
CP 'F' ; Floppy boot
JR Z,FDCK
CP 'B' ; Bell
JP Z,SGX
CP '#'
JP Z,LEA6A
CP 'P' ; Printer test
JP Z,PTESTX
CP 'M' ; Memory correction
JP Z,MCORX
CP 'S' ; Save CMT
JP Z,SAVEX
CP 'V' ; Verify
JP Z,VRFYX
CP 'D' ; Dump memory
JP Z,DUMPX
CP 'Q' ; Quick disk cmd.
JR NZ,ST2X
;
; Quick disk cmd.
;
QUICK:
LD HL,00000h
LD (0113Ah),HL
LD A,(DE)
CP 'L' ; Load QD
JP Z,QL
CP 'D' ; Directory
JP Z,QD
ST1X1:
JR ST1X
FDCK:
LD A,(DE)
CP 00Dh
JR NZ,ST1X1
CALL LEB22
CALL Z,0F006h
JR ST1X1
?ERX:
CP 002h
JR Z,ST1X1
CALL NL
LD DE,MSGE1 ; 'CHECK SUM ER.'
RST 018h
JR ST1X1
BGETLX:
EX (SP),HL
POP BC
LD DE,BUFER
CALL GETL
LD A,(DE)
CP 01Bh
JR Z,ST1X1
JP (HL)
HEXIYX:
EX (SP),IY
POP AF
CALL HLHEX
JR C,ST1X1
JP (IY)
GOTOX:
CALL HEXIYX
JP (HL)
LOADX:
CALL ?RDI
JR C,?ERX
CALL NL
LD DE,MSG?2 ; 'LOADING '
RST 018h
LD DE,NAME
RST 018h
XOR A
LD (BUFER),A
LD HL,(DTADR)
LD A,H
OR L
JR NZ,LE941
LD HL,(EXADR)
LD A,H
OR L
JR NZ,LE941
LD A,0FFh
LD (BUFER),A
LD HL,01200h
LD (DTADR),HL
LE941:
CALL ?RDD
JR C,?ERX
LD A,(BUFER)
CP 0FFh
JR Z,LE954
LD BC,00100h
LD HL,(EXADR)
JP (HL)
LE954:
OUT (0E0h),A
LD HL,01200h
LD DE,00000h
LD BC,(SIZE)
LDIR
LD BC,00100h
JP 00000h
PTESTX:
LD A,(DE)
CP '&' ; plotter test
JR NZ,PTST1X
PTST0X:
INC DE
LD A,(DE)
CP 'L' ; 40 in 1 line
JR Z,.LPTX
CP 'S' ; 80 in 1 line
JR Z,..LPTX
CP 'C' ; Pen change
JR Z,PENX
CP 'G' ; Graph mode
JR Z,PLOTX
CP 'T' ; Test
JR Z,PTRNX
;
PTST1X:
CALL PMSGX
ST1X2:
JP ST1X1
.LPTX:
LD DE,LLPT ; 01-09-09-0B-0D
JR PTST1X
..LPTX:
LD DE,SLPT ; 01-09-09-09-0D
JR PTST1X
PTRNX:
LD A,004h ; Test pattern
JR LE999
PLOTX:
LD A,002h ; Graph mode
LE999:
CALL LPRNTX
JR PTST0X
PENX:
LD A,01Dh ; 1 change code (text mode)
JR LE999
;
;
; 1 char print to $LPT
;
; in: ACC print data
;
;
LPRNTX:
LD C,000h ; RDAX test
LD B,A ; print data store
CALL RDAX
LD A,B
OUT (0FFh),A ; data out
LD A,080h ; RDP high
OUT (0FEh),A
LD C,001h ; RDA test
CALL RDAX
XOR A ; RDP low
OUT (0FEh),A
RET
;
; $LPT msg.
; in: DE data low address
; 0D msg. end
;
PMSGX:
PUSH DE
PUSH BC
PUSH AF
PMSGX1:
LD A,(DE) ; ACC = data
CALL LPRNTX
LD A,(DE)
INC DE
CP 00Dh ; end ?
JR NZ,PMSGX1
POP AF
POP BC
POP DE
RET
;
; RDA check
;
; BRKEY in to monitor return
; in: C RDA code
;
RDAX:
IN A,(0FEh)
AND 00Dh
CP C
RET Z
CALL BRKEY
JR NZ,RDAX
LD SP,ATRB
JR ST1X2
;
; Memory correction
; command 'M'
;
MCORX:
CALL HEXIYX ; correction address
MCORX1:
CALL NLPHL ; corr. adr. print
CALL SPHEX ; ACC ASCII display
CALL ?PRTS ; space print
CALL BGETLX ; get data & check data
CALL HLHEX ; HLASCII(DE)
JR C,MCRX3
CALL DOT4DE ; INC DE * 4
INC DE
CALL _2HEX ; data check
JR C,MCORX1
CP (HL)
JR NZ,MCORX1
INC DE
LD A,(DE)
CP 00Dh ; not correction
JR Z,MCRX2
CALL _2HEX ; ACCHL(ASCII)
JR C,MCORX1
LD (HL),A ; data correct
MCRX2:
INC HL
JR MCORX1
MCRX3:
LD H,B ; memory address
LD L,C
JR MCORX1
;
; Programm save
;
; cmd. 'S'
;
SAVEX:
CALL HEXIYX ; Start address
LD (DTADR),HL ; data adress buffer
LD B,H
LD C,L
CALL DOT4DE
CALL HEXIYX ; End address
SBC HL,BC ; byte size
INC HL
LD (SIZE),HL ; byte size buffer
CALL DOT4DE
CALL HEXIYX ; execute address
LD (EXADR),HL ; buffer
CALL NL
LD DE,MSGSV ; 'FILENAME? '
RST 018h
CALL BGETLX ; filename input
CALL DOT4DE
CALL DOT4DE
LD HL,NAME ; name buffer
SAVX1:
INC DE
LD A,(DE)
LD (HL),A ; filename trans.
INC HL
CP 00Dh ; end code
JR NZ,SAVX1
LD A,OBJCD ; attribute: OBJ
LD (ATRB),A
CALL ?WRI
?ERX1:
JP C,?ERX
CALL ?WRD ; data
JR C,?ERX1
CALL NL
LD DE,MSGOK ; 'OK!'
RST 018h
LEA5B:
JP ST1X
VRFYX:
CALL ?VRFY
JP C,?ERX
LD DE,MSGOK ; 'OK!'
RST 018h
JR LEA5B
LEA6A:
JP CMY0
SGX:
LD A,(SWRK)
RRA
CCF
RLA
LD (SWRK),A
LEA76:
JR LEA5B
DUMPX:
CALL HEXIYX
CALL DOT4DE
PUSH HL
CALL HLHEX
POP DE
JR C,LEAD6
LEA85:
EX DE,HL
LEA86:
LD B,008h
LD C,017h
CALL NLPHL
LEA8D:
CALL SPHEX
INC HL
PUSH AF
LD A,(DSPXY)
ADD A,C
LD (DSPXY),A
POP AF
CP 020h
JR NC,LEAA0
LD A,02Eh
LEAA0:
CALL ?ADCN
CALL PRNT3
LD A,(DSPXY)
INC C
SUB C
LD (DSPXY),A
DEC C
DEC C
DEC C
PUSH HL
SBC HL,DE
POP HL
JR Z,LEAD3
LD A,0F8h
LD (0E000h),A
NOP
LD A,(0E001h)
CP 0FEh
JR NZ,LEAC7
CALL ?BLNK
LEAC7:
DJNZ LEA8D
LEAC9:
CALL ?KEY
OR A
JR Z,LEAC9
CALL ?BRK
DB 020h
LEAD3:
DB 0B2h
JR LEA76
LEAD6:
LD HL,000A0h
ADD HL,DE
JR LEA85
FNINP:
CALL NL
LD DE,MSGSV ; 'FILENAME? '
RST 018h
LD DE,BUFER
CALL GETL
LD A,(DE)
CP #1B
JR NZ,LEAF3
LD HL,ST1X
EX (SP),HL
RET
LEAF3:
LD B,000h
LD DE,011ADh
LD HL,BUFER
LD A,(DE)
CP 00Dh
JR Z,LEB20
LEB00:
CP 020h
JR NZ,LEB08
INC DE
LD A,(DE)
JR LEB00
LEB08:
CP 022h
JR Z,LEB14
LEB0C:
LD (HL),A
INC HL
INC B
LD A,011h
CP B
JR Z,FNINP
LEB14:
INC DE
LD A,(DE)
CP 022h
JR Z,LEB1E
CP 00Dh
JR NZ,LEB0C
LEB1E:
LD A,00dh
LEB20:
LD (HL),A
RET
LEB22:
LD A,(0F000h)
OR A
RET
LEB27: DB "IPL IS LOADING ",00Dh
LEB37: DB "MAKE READY QD",00Dh
DISCLR: DB "** MONITOR 9Z-503M **",00Dh
;
;====================================
;
; QUICK DISK LOAD COMMAND
;
;====================================
;
QL:
CALL IOFRS
CALL QDRCK ; Ready check
JR C,LEBAC
CALL FNINP ; Input filename
CALL HDPCL ; Head point clear
;
; Disp 'Loading...'
;
LD DE,MSG?2 ; 'LOADING '
RST 018h
;
; File search
;
FILESH:
CALL FILSCH
JR C,LEBAC
;
; Atribute check
;
LD A,(ATRB)
CP OBJCD
JR NZ,FILESH
;
;
;
DSFLNA:
LD DE,NAME
RST 018h
LD HL,(EXADR)
LD A,H
OR L
JR NZ,LEB8B
LD HL,(COMNT)
LD A,H
OR L
LEB8B:
JR NZ,LPARA0
LD A,0FFh
LD (0113Ah),A
;
; Iocs parameter set
;
LD HL,01200h
JR LPARA1
LPARA0:
LD HL,(EXADR)
LPARA1:
LD (QDPC),HL ; Data adrs set
LD HL,(DTADR)
LD (QDPE),HL
LD HL,00103h ; Read data block cmd.
LD (QDPA),HL ; QDPA = 3 (read from headpoint)
; QDPB = 1 (data should be read)
;
; Read data block
;
CALL QDIOS ; QD iocs
LEBAC:
JP C,QER04
LD A,(0113Ah)
CP 0FFh
JR Z,LEBBD
;
; Exec load file
;
LD BC,00300h
LD HL,(COMNT)
JP (HL)
LEBBD:
OUT (0E0h),A
LD HL,01200h
LD DE,00000h
LD BC,(DTADR)
LDIR
LD BC,00300h
JP 00000h
;
; Iocs flag reset
;
IOFRS:
XOR A
LD (MTF),A ; Motor Flag = 0 (OFF)
LD (FNUPS),A ; File number flag = 0
LD (FNUPF),A ; File number up flag = 0
RET
;
;
; File search sub.
;
;
FILSCH:
;
; Iocs parameter set
;
LD HL,00003h ; read from headpoint
LD (QDPA),HL ; QDPA = 3 (read from head point)
; QDPB = 0 (header should be read)
LD HL,ATRB ; Head adrs
LD (QDPC),HL
LD HL,00040h ; Read size
LD (QDPE),HL
;
; Read information block
;
QLINF:
CALL QDIOS
RET C
;
; File name check
;
LD A,(BUFER)
CP 00Dh
RET Z
LD HL,BUFER
LD DE,NAME
LD B,NAMSIZ
LDFNCK:
LD A,(DE)
CP (HL)
JR NZ,QLINF
CP 00Dh
RET Z
INC DE
INC HL
DJNZ LDFNCK
RET
;
; Quick disk ready check
;
QDRCK:
XOR A
LD (QDPB),A ; QDPB = 0 -> only Ready check
INC A
LD (QDPA),A ; QDPA = 1
CALL QDIOS
RET
;
;======================================
;
; Quick disk directory command
;
;======================================
;
QD:
CALL IOFRS
CALL QDRCK
JR C,QER04
CALL HDPCL
LD B,000h
;
; Disp 'Directory of QD:'
;
LD DE,DIRMSG
RST 018h
;
; Iocs parameter set
;
LD HL,QDIRBF
DIRIOP:
LD (QDPC),HL
LD HL,00003h
LD (QDPA),HL ; QDPA = 3 (read from headpoint)
; QDPB = 0 (header should be read)
LD HL,00040h
LD (QDPE),HL ; QDPE = 64 (header length)
;
; Read information block
;
PUSH BC
CALL QDIOS
POP BC
JR C,DIREFC
INC B
;
; Buffer adrs increment
;
LD HL,(QDPC)
LD DE,PRNT
ADD HL,DE
JR DIRIOP
;
; End file check
;
DIREFC:
CP NTFECD
JR Z,DIRMTF
SCF
QER04:
JR C,QERTRT
;
; Motor off
;
DIRMTF:
LD A,006h ; Motor off command
LD (QDPA),A
PUSH BC
CALL QDIOS
POP BC
;
; No file check
;
XOR A
CP B
JR NC,QDOKM
;
; Directory disp
;
CALL NL
LD HL,QDIRBF
;
; Disp atribute
;
DSPATR:
LD A,(HL)
LD DE,MSGQ01
DEC A
JR Z,LECA4
LD DE,MSGQ02
DEC A
JR Z,LECA4
LD DE,MSGQ03
DEC A
JR Z,LECA4
LD DE,MSGQ04
DEC A
JR Z,LECA4
LD DE,MSGQ05
DEC A
JR Z,LECA4
DEC A
JR Z,LECA1
LD DE,MSGQ07
DEC A
JR Z,LECA4
DEC A
JR Z,LECA1
DEC A
JR Z,LECA1
LD DE,MSGQ10
DEC A
JR Z,LECA4
LD DE,MSGQ11
DEC A
JR Z,LECA4
LECA1:
LD DE,MSGQ??
LECA4:
RST 018h
;
; Disp file name
;
LECA5:
LD A,'"'
CALL PRNT
INC HL
PUSH HL
POP DE
RST 018h
LD A,'"'
CALL PRNT
CALL NL
;
; Counter decrement
;
LECB6:
LD DE,00011h
ADD HL,DE
LECBA:
CALL ?KEY
OR A
JR Z,LECBA
CALL ?BRK
JP Z,ST1X
DJNZ DSPATR
QDOKM:
CALL NL
LD DE,MSGQOK
RST 018h
JP ST1X
;
;======================================
;
; Error treatment
;
;=====================================
;
QERTRT:
LD DE,MGNFE ; 'Not Found err'
CP NTFECD ; Not found err
JR Z,QERMF
LD DE,MGNRE ; 'Not ready'
CP QNTRCD ; Not ready
JR Z,QERMF
LD DE,MGUFE ; 'Unformat'
CP UNFMCD ; Unformat err
JR Z,QERMF
LD DE,MSGTRM
CP BRKCD ; Break
JR Z,QERMF
LD DE,MGHDE ; 'Hard error'
;
; Motor off
;
QERMF:
LD A,006h ; Motor off cmd.
LD (QDPA),A
CALL QDIOS
CALL HDPCL
;
LECFC:
LD A,(QDCPA)
RRA
RET C ; Boot err
CALL NL
RST 018h
JP ST1X
;
; Header point clear
;
HDPCL:
LD A,005h ; Head point clear cmd.
LD (QDPA),A
CALL QDIOS
RET
;
;======================================
;
; Message table
;
;======================================
;
MSGQOK: DB "OK!"
MSGTRM: DB 00Dh
MGNFE: DB "QD:FILE NOT FOUND",00Dh
MGHDE: DB "QD:HARD ERR",00Dh
MGNRE: DB "QD:NOT READY",00Dh
MGUFE: DB "QD:UNFORMAT",00Dh
LED4C: DB "QD:FILE MODE ERR",00Dh
DIRMSG: DB "DIRECTORY OF QD:",00Dh
MSGQ01: DB " OBJ ",00Dh
MSGQ02: DB " BTX ",00Dh
MSGQ03: DB " BSD ",00Dh
MSGQ04: DB " BRD ",00Dh
MSGQ05: DB " RB ",00Dh
MSGQ07: DB " LIB ",00Dh
MSGQ10: DB " SYS ",00Dh
MSGQ11: DB " GR ",00Dh
MSGQ??: DB " ??? ",00Dh
QDIOS1:
LD A,005h ; Retry 4
LD (RTYF),A
;
RTY:
DI
CALL QMEIN
EI
RET NC
PUSH AF
CP 028h
JR Z,RTY4
CALL MTOF
POP AF
PUSH AF
CP 029h
JR NZ,RTY4
LD HL,RTYF
DEC (HL)
JR Z,LEDF3
POP AF
JR RTY
LEDF3:
CALL QDHPC
RTY4:
POP AF
RET
QMEIN:
LD (RETSP),SP
LD A,(QDPA)
DEC A ; ready check (1)
JR Z,QDRC
DEC A ; format (2)
; not implemented
DEC A ; read from headpoint (3)
JR Z,QDRD
DEC A ; save from headpoint (4)
; not implemented
DEC A ; headpoint clear (5)
JR Z,QDHPC
JP MTOF ; else motor off
;
;======================================
;
; Head Point Clear
;
;======================================
;
QDHPC:
PUSH AF
XOR A
LD (HDPT),A
POP AF
RET
;
;=================================
;
; Ready Check
;
;=================================
;
QDRC:
LD A,(QDPB) ; QDPB = 0 -> only Ready check
JP QREDY
;
;=================================
;
; Read
;
;=================================
;
QDRD:
LD A,(MTF) ; A = Motor Flag
OR A ; test Motor Flag
CALL Z,MTON ; if Motor Flag = 0 then Motor On and go to home position
CALL HPS ; head point search
RET C
CALL BRKC ; check break key
;
CALL RDATANRCK ; read low-byte blocksize
LD C,A
CALL RDATANRCK ; read high-byte blocksize
LD B,A
LD HL,(QDPE)
SBC HL,BC ;
JP C,IOE41
LD HL,(QDPC)
;
; Block Data Read
;
BDR:
CALL RDATANRCK ; read data
LD (HL),A ; save it
INC HL ; inc address
DEC BC ; dec counter
LD A,B
OR C
JR NZ,BDR ; counter not zero than read again
CALL RDCRC ; read checksum (3 bytes)
LD A,(QDPB)
BIT 0,A
JP NZ,MTOF
RET
;
; Head Point Search
;
HPS:
LD HL,FNB ; HL = next file number
DEC (HL)
JR Z,HPNFE ; Not found
CALL SYNCL2 ; read 2 bytes last is in A
LD C,A ; BLocKFLaG => C reg
LD A,(HDPT) ; A = destination head point position
LD HL,HDPT0 ; HL = address of the actual head point position
CP (HL) ; Search ok ?
JR NZ,HPS1 ; no, than make dummy block read
INC A ; HDPT count up
LD (HDPT),A
LD (HL),A ; HDPT0 count up
LD A,(QDPB) ; A = filetype to load
XOR C ; xor with BLocKFLaG which
RRA
RET NC ; same, than ret else ...
;
; Dummy read
;
DMR:
CALL RDATANRCK ; read size low byte
LD C,A
CALL RDATANRCK ; read size high byte
LD B,A
;
DMR1: ; read size bytes
CALL RDATANRCK
DEC BC
LD A,B
OR C
JR NZ,DMR1
CALL RDCRC ; read checksum (3 bytes)
JR HPS ; next
;
HPS1:
INC (HL) ; increment actual head point position
JR DMR
;
HPNFE:
LD A,NTFECD ; Not Found
SCF
RET
;
; Ready & Write protect
; ACC = 0 : Ready check
; ACC = 1 : & Write Protect
;
QREDY:
LD B,A ; save command
LD A,002h
OUT (SIOBC),A ; select register 2 (IV)
LD A,081h
OUT (SIOBC),A ; write 81h in register 2
LD A,002h
OUT (SIOBC),A ; select register 2 (IV)
IN A,(SIOBC) ; read back register 2
AND 081h
CP 081h
JP NZ,IOE50 ; Not ready
LD A,010h
OUT (SIOAC),A ; NULL CODE, RESET EXT/STATUS INT, REGISTER 0
IN A,(SIOAC)
LD C,A ; save Read Register 0
AND 008h ; test DCD (HeadSet)
JP Z,IOE50 ; Not ready
LD A,B ; restore command
OR A ; if command = 0 then
RET Z ; return
LD A,C ; else restore Read Register 0
AND 020h ; test CTS (WriteProtect)
RET NZ ; if CTS then not protected, return
JP IOE46 ; else Write protect
;
;
; MTON -- QD MOTOR ON
; READ FILE NUMBER
; READ & CHECK CRC,FLAG
;
MTON:
LD HL,SIOLD ; SIO Load Data
LD B,00Bh
CALL LSINT ; load SIO init and motor on and go to home position
CALL SYNCL1 ; search for sync and read first 2 bytes, last is in A
LD (FNA),A ; save actual file no in File Number A
INC A
LD (FNB),A ; save next file no in File Number B
CALL RDCRC ; read checksum (3 bytes)
FNEND:
LD HL,SYNCF
SET 3,(HL) ; set bit3 of SyncFlags
XOR A ; A = 0
LD (HDPT0),A ; actual head point position = 0
RET
;
; sio initial
;
LSINT:
LD C,SIOAC
OTIR
LD A,005h ; 00000101
LD (MTF),A ; MoTor Flag = 5
OUT (SIOBC),A ; ch B select register 5
LD A,080h ; 10000000
OUT (SIOBC),A ; set DTR_B (Motor On), clear RTS_B
LREDY: ; check for ready and if so, than goto home position
LD A,010h ; 00010000
OUT (SIOAC),A ; reset ext/status interrupts, set register 0
IN A,(SIOAC) ; read register 0
AND 008h ; test DCD_A (disk inside ?)
JP Z,IOE50 ; Not ready
CALL BRKC ; BReak Key Check
LD A,010h ; 00010000
OUT (SIOBC),A ; reset ext/status interrupts, set register 0
IN A,(SIOBC) ; read register 0
AND 008h ; test DCD_B (Home)
JR Z,LREDY
LD BC,000E9h ; wait 160ms
JP TIMW
;
; Motor off
;
QDOFF: ; basic call
MTOF:
PUSH AF
LD A,005h
OUT (SIOAC),A ; select Write Register 5
LD A,060h ; 01100000
OUT (SIOAC),A ; DTR OFF (Motor Off), Tx DISABLE, RTS OFF (WRGA)
LD A,005h
OUT (SIOBC),A ; select Write Register 5
XOR A ; 00000000
LD (MTF),A ; Motor Flag = 0
OUT (SIOBC),A ; DTR OFF (Motor Off), clear RTS_B
POP AF
RET
;
; SYNCL1 -- LOAD F.N SYNC ONLY
; (SEND BREAK 110ms)
; SYNCL2 -- LOAD FIRST FILE SYNC
; (SEND BREAK 110ms)
;
SYNCL2:
LD A,058h ; 01011000
; RESET Rx CRC CHECKER, CHANNEL RESET, REGISTER 0
LD B,00Bh ; 11 values to load
LD HL,SIOLD
CALL SYNCA
LD HL,SYNCF
BIT 3,(HL) ; test bit3 of SyncFlags
LD BC,00003h ; WAIT 2ms
JR Z,TMLPL
RES 3,(HL) ; reset bit3 of SyncFlags
SYNCL1:
ld bc,000a0h ; WAIT 110ms
;
TMLPL: ; the motor is switched on
; and a hunt phase is initiated,
; that means the incoming datastream
; is inspected for the programmed
; sync characters
CALL TIMW
LD A,005h
OUT (SIOBC),A ; select Write Register 5
LD A,082h ; 10000010
OUT (SIOBC),A ; DTR ON (Motor On), RTS ON ()
LD A,003h
OUT (SIOAC),A ; select Write Register 3
LD A,0D3h ; 11010011
OUT (SIOAC),A ; RX 8 BIT, ENTER HUNT PHASE, SYNC, Rx ENABLE
LD BC,02CC0h ; 220ms timeout
;
SYNCW0: ; now the datastream is inspected
; also a timeout is checked
LD A,010h
OUT (SIOAC),A ; RESET EXT/STATUS INT, select Register 0
IN A,(SIOAC)
AND 010h ; test SYNC/HUNT
JR Z,SYNCW1 ; first 2 syncbytes found
DEC BC
LD A,B
OR C
JR NZ,SYNCW0
JP IOE54 ; unformatted
;
SYNCW1: ; now we should ignore further sync characters
LD A,003h
OUT (SIOAC),A ; select Write Register 3
LD A,0C3h ; 11000011
OUT (SIOAC),A ; Rx 8 BIT, SYNC CHAR LOAD INHIBIT, Rx ENABLE
LD B,09Fh ; timeout
;
SYNCW2:
; loop for find the end of syncbytes:
; rx available is only set if the first
; byte is found which is not a syncbyte
LD A,010h
OUT (SIOAC),A ; NULL CODE, RESET EXT/STATUS INT, REGISTER 0
IN A,(SIOAC)
AND 001h ; test Rx CHARACTER AVAILABLE
JR NZ,SYNCW3
DEC B
JR NZ,SYNCW2
SYNCW01:
JP IOE54 ; unformated
;
SYNCW3: ; now the datastream is in sync and the
; first real data is ready to read
LD A,003h
OUT (SIOAC),A ; select Write Register 3
LD A,0C9h ; 11001001
OUT (SIOAC),A ; Rx 8 BIT, Rx CRC ENABLE, Rx ENABLE
CALL RDATANRCK
JP RDATANRCK
;
;
;
SYNCA:
LD C,SIOAC
OUT (C),A
LD A,005h
OUT (SIOBC),A ; select Write Register 5
LD A,080h
OUT (SIOBC),A ; set DTR_B (Motor On), clear RTS_B
OTIR
RET
;
; RDCRC -- READ CRC & CHECK
;
RDCRC:
LD B,003h ; 3 retries
RDCR1:
CALL RDATANRCK ; read 3 bytes
DJNZ RDCR1
RDCR2: ; read REGISTER 0
IN A,(SIOAC)
RRCA ; test Rx CHARACTER AVAILABLE
JR NC,RDCR2 ; Rx Available
LD A,001h
OUT (SIOAC),A ; select REGISTER 1
IN A,(SIOAC) ; read REGISTER 1
AND 040h ; test CRC ERROR
JR NZ,IOE41 ; Hard err
OR A
RET
RDATANRCK:
NRCK:
LD A,010h
OUT (SIOAC),A ; reset ext/status interrupts, set register 0
IN A,(SIOAC) ; read register 0
AND 008h ; test DCD (HeadSet)
JP Z,IOE50 ; Not Ready
;
; Read data (1 chr)
;
RDATA:
IN A,(SIOAC) ; read REGISTER 0
RLCA
JR C,IOE41 ; test BREAK/ABORT (Hard Err)
RRCA
RRCA
JR NC,NRCK ; test Rx AVAILABLE
IN A,(SIOAD) ; read data
OR A
RET
;
; i/o err
;
IOE41:
LD A,HDERCD ; Hard err
DB 021h
IOE46:
LD A,WPRTCD ; Write protect
DB 021h
IOE50:
LD A,QNTRCD ; Not ready
DB 021h
IOE53:
LD A,NFSECD ; No file space
DB 021h
IOE54:
LD A,UNFMCD ; Unformat
LD SP,(RETSP)
SCF
RET
;
; wait timer
;
;
; BC = 0001H = 0.7ms ( 0.704ms)
; 0003H = 2.0ms ( 2.107ms)
; 001DH = 20.0ms ( 19.938ms)
; 00A0H = 110.0ms (110.050ms)
; 00E9H = 160.0ms (160.140ms)
; 0140H = 220.0ms (219.940ms)
;
;
TIMW:
PUSH AF
TIMW1:
LD A,086h
TIMW2:
DEC A
JR NZ,TIMW2
DEC BC
LD A,B
OR C
JR NZ,TIMW1
POP AF
RET
;
;
;
; SIO CH A COMMAND CHAIN
;
; SIOLD -- LOAD INIT. DATA
;
;
;
; BiSync mode, uses 16h and 16h as sync characters
; the SIO works also in polling mode, no interrupt is generated
;
SIOLD:
DB 058h ; RESET Rx CRC CHECKER, CHANNEL RESET
DB 004h ; select Write Register 4
DB 010h ; X1 CLOCK mode, 16 bit sync char, sync mode, no parity
DB 005h ; select Write Register 5
DB 004h ; CRC-16
DB 003h ; select Write Register 3
DB 0D0h ; RX 8 BITS, AUTO ENABLES, ENTER HUNT PHASE
DB 006h ; select Write Register 6
DB 016h ; set SYNC CHR(1)
DB 007h ; select Write Register 7
DB 016h ; set SYNC CHR(2)
;
;
; BREAK CHECK
;
BRKC:
LD A,0E8h
LD (0E000h),A
NOP
LD A,(0E001h)
AND 081h
RET NZ
LD SP,(RETSP)
SCF
RET
ld l,#41
; the following is only to get the original length of 4096 bytes
ALIGN 0F7FFh
DB 0FFh