|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 17664 (0x4500)
Types: TextFile
Names: »INIT.MAC«
└─⟦72577d508⟧ Bits:30003297 Diverse BIOS typer til RC703
└─⟦this⟧ »INIT.MAC«
SUBTTL HARDWARE INITIALIZATION CODE
PAGE
;========================================================
;= MOVE CODE TO RUNTIME POSITION =
;========================================================
; ENTRY FROM ROM BOOTSTRAP
; THIS CODE IS PLACED IN 380H AND FORWARD AFTER BOOT
DI ; (* disable interrupts during initialization *)
LD HL,0 ; HL := load_address
LD DE,START ; DE := run_time_address
LD BC,DSPSTR-START+1; BC := code_size
LDIR ; (* move code *)
LD HL,CONVTA ; HL := conv_tab_address;
LD DE,OUTCON ; DE := run_time_address;
LD BC,128+256 ; BC := conv_tab_length;
LDIR ; (* move conversion tables *)
LD SP,BUFF ; (* if a interrupt should occure *)
LD A,(CITAB+1) ; (* high byte of int. table address *)
LD I,A ; (* load interrupt register *)
IM 2 ; (* set interrupt mode 2 *)
;===========================================================
;= INITIALIZE Z80 PIO =
;= PORT A USED FOR KEYBOARD INPUT =
;= PORT B USED FOR PARALLEL OUTPUT =
;===========================================================
INIT: LD A,20H ; SET PORT A INTERRUPT VECTOR
OUT (PIOAC),A ;
LD A,22H ; SET PORT B INTERRUPT VECTOR
OUT (PIOBC),A ;
LD A,4FH ; SET PORT A MODE (INPUT)
OUT (PIOAC),A ;
LD A,0FH ; SET PORT B MODE (OUTPUT)
OUT (PIOBC),A ;
LD A,83H ;
OUT (PIOAC),A ; ENABLE PORT A INTERRUPT
OUT (PIOBC),A ; ENABLE PORT B INTERRUPT
PAGE
;==============================================================
;= INITIALIZE Z80 CTC =
;= CHANNEL 0 USED AS BAUD RATE GENERATOR FOR SIO CHANNEL A =
;= CHANNEL 1 USED AS BAUD RATE GENERATOR FOR SIO CHANNEL B =
;= CHANNEL 2 USED AS INTERRUPT HANDLER FOR DISPLAY CONTROLLER =
;= CHANNEL 3 USED AS INTERRUPT HANDLER FOR DMA CONTROLLER =
;==============================================================
LD A,00H ; SET CTC INTERRUPT VECTOR
OUT (CTCCH0),A ;
LD A,(MODE0) ; SET OPERATING MODE FOR CHANNEL 0
OUT (CTCCH0),A ; MODE:= CLOCK GENERATOR (NO INTERRUPT)
LD A,(COUNT0) ; SET COUNT FOR CHANNEL 0
OUT (CTCCH0),A ;
LD A,(MODE1) ; SET OPERATING MODE FOR CHANNEL 1
OUT (CTCCH1),A ; MODE:= CLOCK GENERATOR (NO INTERRUPT)
LD A,(COUNT1) ; SET COUNT FOR CHANNEL 1
OUT (CTCCH1),A ;
LD A,(MODE2) ; SET OPERATING MODE FOR CHANNEL 2
OUT (CTCCH2),A ; MODE:= INTERRUPT AFTER 1 COUNT
LD A,(COUNT2) ; SET COUNT FOR CHANNEL 2
OUT (CTCCH2),A ;
LD A,(MODE3) ; SET OPERATING MODE FOR CHANNEL 3
OUT (CTCCH3),A ; MODE:= INTERRUPT AFTER 1 COUNT
LD A,(COUNT3) ; SET COUNT FOR CHANNEL 3
OUT (CTCCH3),A ;
PAGE
;==============================================================
;= INITIALIZE Z80 CTC 2 =
;= CHANNEL 0 USED AS INTERRUPT GENERATOR FOR WD1000 =
;= CHANNEL 1 NOT USED =
;= CHANNEL 2 NOT USED =
;= CHANNEL 3 NOT USED =
;==============================================================
LD A,08H ; SET CTC INTERRUPT VECTOR
OUT (CTC2C0),A ;
LD A,(MODE4) ; SET OPERATING MODE FOR CHANNEL 0
OUT (CTC2C0),A ; MODE:= INTERRUPT AFTER 1 COUNT
LD A,(COUNT4) ; SET COUNT FOR CHANNEL 0
OUT (CTC2C0),A ;
LD A,(MODE5) ; SET OPERATING MODE FOR CHANNEL 1
OUT (CTC2C1),A ; MODE:= CHANNEL RESET
LD A,(MODE5) ; SET OPERATING MODE FOR CHANNEL 2
OUT (CTC2C2),A ; MODE:= CHANNEL RESET
LD A,(MODE5) ; SET OPERATING MODE FOR CHANNEL 3
OUT (CTC2C3),A ; MODE:= CHANNEL RESET
PAGE
;========================================================
;= INITIALIZE Z80 SIO =
;= CHANNEL A USED FOR READER AND PUNCH =
;= CHANNEL B USED FOR PRINTER =
;========================================================
LD HL,PSIOA ; SIO A PROGRAM
LD B,9 ; PROGRAM LENGTH
LD C,SIOAC ; PORT A CONTROL
OTIR ; PROGRAM SIO CHANNEL A
LD HL,PSIOB ; SIO B PROGRAM
LD B,11 ; PROGRAM LENGTH
LD C,SIOBC ; PORT B CONTROL
OTIR ; PROGRAM SIO CHANNEL B
IN A,(SIOAC) ; READ CHANNEL A, STATUS REGISTER 0
LD (RR0_A),A ;
LD A,1 ;
OUT (SIOAC),A ;
IN A,(SIOAC) ; READ CHANNEL A, STATUS REGISTER 1
LD (RR1_A),A ;
IN A,(SIOBC) ; READ CHANNEL B, STATUS REGISTER 0
LD (RR0_B),A ;
LD A,1 ;
OUT (SIOBC),A ;
IN A,(SIOBC) ; READ CHANNEL B, STATUS REGISTER 1
LD (RR1_B),A ;
PAGE
;========================================================
;= INITIALIZE AM9517 DMA =
;= CHANNEL 0 - WINCHESTER DISK CONTROLLER =
;= CHANNEL 1 - FLOPPY DISK CONTROLLER =
;= CHANNEL 2 - DISPLAY CONTROLLER =
;= CHANNEL 3 - DISPLAY CONTROLLER =
;========================================================
LD A,20H ;
OUT (DMAC),A ; ENTER COMMAND MODE
LD A,(DMODE0) ;
OUT (DMAMOD),A ; SET CHANNEL 0 MODE
LD A,(DMODE2) ;
OUT (DMAMOD),A ; SET CHANNEL 2 MODE
LD A,(DMODE3) ;
OUT (DMAMOD),A ; SET CHANNEL 3 MODE
PAGE
;========================================================
;= INITIALIZE UPD765 FLOPPY DISK CONTROLLER =
;========================================================
IN A,(SW1) ;
AND 80H ;
JR Z,IFD0 ; IF MINI_DRIVE THEN
LD HL,INFD0 ; BEGIN
LD A,(HL) ; CHANGE MAXI DRIVE FORMAT TO MINI
CP 8 ;
JR NZ,IFDX ;
LD (HL),16 ;
IFDX: INC HL ;
LD A,(HL) ;
CP 8 ;
JR NZ,IFDY ;
LD (HL),16 ;
IFDY: LD HL,FDPROG+3 ; CHANGE HEAD LOAD TIME TO 52 MS
LD A,12*2+0 ; <7654321><0>
LD (HL),A ; H.LOAD DMA
IFD0: IN A,(FDC) ; ELSE:
AND 1FH ; READ STATUS
JR NZ,IFD0 ; WAIT TILL FD READY FOR COMMANDS
LD HL,FDPROG ;
LD B,(HL) ;
IFD1: INC HL ;
IFD2: IN A,(FDC) ;
AND 0C0H ;
CP 80H ; TEST DIO AND RQM
JR NZ,IFD2 ;
LD A,(HL) ;
OUT (FDD),A ;
DJNZ IFD1 ;
PAGE
;========================================================
;= INITIALIZE DISPLAY DRIVER VARIABLES =
;========================================================
; (* CLEAR DISPLAY BUFFER *)
LD HL,DSPSTR ;
LD DE,DSPSTR+1 ;
LD BC,07CFH ;
LD (HL),' ' ;
LDIR ;
; (* CLEAR BACKGROUND FLAGS *)
LD HL,BGSTAR ;
LD DE,BGSTAR+1 ;
LD BC,250 ;
LD (HL),0 ;
LDIR ;
; (* CLEAR VARIABLES *)
LD HL,CCTAD ;
LD DE,CCTAD+1 ;
LD (HL),0 ;
LD BC,0FFFFH-CCTAD ;
LDIR ;
; (* INSERT DEFAULT COLLOURS *)
ld hl,dspstr ;
ld a,(icolour) ;
ld (colour),a ;
call set$col ; set default colours
PAGE
;========================================================
;= INITIALIZE INTEL8275 DISPLAY CONTROLLER =
;========================================================
LD A,0 ;
OUT (DSPLC),A ; RESET
LD A,(PAR1) ;
OUT (DSPLD),A ; SET CHARACTERS PR. ROW
LD A,(PAR2) ;
OUT (DSPLD),A ; SET ROWS PR. FRAME
LD A,(PAR3) ; SET LINES PR. CHARACTER AND
OUT (DSPLD),A ; UNDERLINE POSITION
LD A,(PAR4) ; SET CURSOR FORMAT
OUT (DSPLD),A ;
LD A,80H ; LOAD CURSOR POSITION COMMAND
OUT (DSPLC),A ;
LD A,0 ;
OUT (DSPLD),A ; SET CURSOR X POSITION = 0
OUT (DSPLD),A ; SET CURSOR Y POSITION = 0
LD A,0E0H ; PRESET COUNTERS
OUT (DSPLC),A ;
LD A,23H ;
OUT (DSPLC),A ; START DISPLAY
PAGE
;================================================
;= INITIALIZE RUN TIME VARIABLES =
;================================================
LD DE,ENDPRG ; GET END PROGRAM ADR.
LD HL,BGSTAR ; GET LAST PROGRAM ADR. + 1
AND A ;
SBC HL,DE ;
LD C,L ;
LD B,H ;
LD HL,ENDPRG+1 ;
EX DE,HL ;
LD (HL),00 ;
LDIR ; CLEAR ALL VARIABLES
LD A,(PSIOA+6) ;
AND 60H ;
LD (WR5A),A ; M(SIOA_WR5):=SIOA.WR5.BITS_PR_CHAR;
LD A,(PSIOB+8) ;
AND 60H ;
LD (WR5B),A ; M(SIOB_WR5):=SIOB.WR5.BITS_PR_CHAR;
LD A,(XYFLG) ;
LD (ADRMOD),A ;
LD HL,(STPTIM) ;
LD (FDTIMO),HL ;
LD A,0FFH ;
LD (FL_FLG),A ; FLOPPY_BUSY:=FALSE
CALL IDT ; initilize disk tables
ld a,(ibootd) ;
ld (bootd),a ; init bootd with HDINST var.
PAGE
;==============================================================================
;= CHECK HARD DISK ONLINE =
;==============================================================================
INI050: EI ;
LD A,1 ;
LD (HD_OFL),A ; INIT HDDSK OFFLINE
INI060: LD B,0101B ; STEPPING RATE (2,5 MILL.SECS)
LD A,20H ; SIZE,DRIVE,HEAD(00=256 BYTES/SECT 20=512)
CALL HRDRST ; RESTORE
LD BC,0F000H ; SET COUNTER
HD_TMR: LD A,(HD_FLG) ; WHILE NOT COMPLETE OR NOT TIMEOUT DO
OR A ; CHECK FLAG
JR NZ,HD_RDY ; IF READY THEN COMPLETE=TRUE;
DEC BC ;
LD A,B ;
OR C ; IF COUNT = 0 THEN TIMEOUT=TRUE;
JR NZ,HD_TMR ; ENDWHILE;
JP HD_OFF ;
HD_RDY: LD A,(ERFLAG) ; IF HD READY
OR A ; IF ERRORFLAG <> 0 THEN
LD A,0 ; RESET ERROR FLAG
LD (ERFLAG),A ; RESET HD INTERRUPT FLAG
LD (HD_FLG),A ; PRINT WAITING MESSAGE
PUSH AF ; GOTO ISSUE RESTORE COMMAND
LD HL,WMESS ;
CALL PRMSG ;
XOR A ;
LD (WMESS),A ;
POP AF ;
JP NZ,INI060 ;
XOR A ; ELSE
LD (HD_FLG),A ; RESET HD-ITRFLAG
LD (HD_OFL),A ; HARDDISK OFFLINE = FALSE
PAGE
;====================================================================
;= HARD DISK ONLINE --> READ CONFIGURATION SECTOR =
;====================================================================
LD BC,2 ;
CALL SELD ; SELECT DRIVE C:
CALL XHOME ; issue seek_command to set step-rate
LD BC,0 ;
CALL SETT ; SET TRACK = 0
LD BC,124 ; SET SECTOR = 124 (LAST SECTOR -3
CALL SETS ; ON 2ND PAGE)
LD BC,080H ;
CALL SETD ; SET DMA ADDRESS
CALL XREAD ; READ CONFIGURATION SECTOR
OR A ;IF ERROR THEN
JR Z,INI065 ; PRINT MESSAGE
LD HL,HDERR ; MAX DRIVE = 1
CALL PRMSG ; REMOVE CLEAR SCREEN FROM BOOTM
LD A,13 ;
LD (SIGNON),A ;
JP HD_OFF ; ELSE
INI065: LD DE,INFD2 ; MOVE CONFIGURATION READ TO DISK CONF ARR
LD HL,080H ; (* READ BUFFER *)
LD BC,15 ; (* NO OF BYTES *)
LDIR ;
PAGE
;====================================================================
;= CONFIGURATION SECTOR READ --> CHECK IF RC763 OR RC763B =
;====================================================================
XOR A ; rodime_202_flag:=false
LD (R202_FLG),A ;
LD B,5 ;
LD DE,HD_TEXT ; hd_text:='RC763'
LD HL,80H+32 ; hard_disk_id from configuration sector
CH_ID1: LD A,(DE) ; i:=0
CP (HL) ; while hd_text(i)=hard_disk_id(i) and i<5 do
JR NZ,CHK_CONF ; i:=i+1
INC DE ;
INC HL ;
DJNZ CH_ID1 ;
LD A,(HL) ; if i=5 and hard_disk_id(i)='B'
CP 'B' ; then rodime_202_flag:=true
JR NZ,CHK_CONF ; re_initialize (dpb,fsp,fdf)
LD A,1 ;
LD (R202_FLG),A ;
PAGE
;====================================================================
;= IF RC763B --> CHANGE DPB'S, FSP'S AND FDF'S FOR RODIME 202 =
;====================================================================
LD B,5 ; insert new value of cpmspt=256 in dpb's
LD DE,DPB40-DPB32 ; and fsp's
LD IX,DPB32 ;
LD HL,256 ;
I_DPB: LD (IX+0),L ;
LD (IX+1),H ;
ADD IX,DE ;
DJNZ I_DPB ;
LD B,5 ;
LD DE,FSPA40-FSPA32;
LD IX,FSPA32 ;
I_FSP: LD (IX+3),L ;
LD (IX+4),H ;
ADD IX,DE ;
DJNZ I_FSP ;
LD B,5 ; insert new trk_size values in fdf's
LD DE,FDF6-FDF5 ;
LD HL,TRKSIZ ;
LD IX,FDF5 ;
I_FDF: LD A,(HL) ;
LD (IX+2),A ;
INC HL ;
LD A,(HL) ;
LD (IX+3),A ;
INC HL ;
ADD IX,DE ;
DJNZ I_FDF ;
JR CHK_CONF ; check configuration sector
PAGE
HD_TEXT:DB 'RC763' ; hard disk id-text
TRKSIZ: DW 36 ; 1.1 MB unit (Rodime 202 table)
DW 36 ; 0.8 MB unit
DW 70 ; 1.9 MB unit
DW 140 ; 3.8 MB unit
DW 280 ; 7.9 MB unit
;====================================================================
;= CONFIGURATION SECTOR READ --> CHECK CONFIGURATION =
;====================================================================
CHK_CON:LD HL,INFD2 ; IF NOT CONF DISK THEN (FORMAT <> 20H AND 28H)
LD A,(HL) ;
CP 20H ; FORMAT C: := FLOPPY FORMAT+24
JR Z,CHK_C1 ; FORMAT D: := FFH (* NOT USED *)
CP 28H ; NUMBER FLS:= 02
JR Z,CHK_C1 ;
LD A,(FD0) ;
ADD A,24 ;
LD (HL),A ;
INC HL ;
LD (HL),0FFH ;
CHK_C1: CALL IDT ; RE-INITIALIZE DISK TABLE CONFIG
PAGE
;====================================================================
;= FIND AND INSERT THE DISK OFFSET (SKIPPED TRACKS) FOR DISK C -> P =
;====================================================================
LD HL,FD2 ; addr of format byte for disk unit C
LD DE,3 ; no of tracks to skip on unit C
LD IY,TRKOFF+4 ; track offset table ( unit C )
; i:=2 , off_set:=3
I_TOFF: LD A,(HL) ; while format_byte(i) <> 255 do
CP 255 ; do
JR Z,I_TOF1 ;
PUSH HL ;
LD (IY+0),E ; track_offset_table(i):=off_set
INC IY ;
LD (IY+0),D ;
INC IY ;
AND 11111000B ; format:=format_byte(i) and 11111000b
LD B,0 ; /* clear position bits */
LD C,A ;
LD IX,FDF1 ; offset:=offset+disk_format.trk_size(format)
ADD IX,BC ;
LD L,(IX+2) ;
LD H,(IX+3) ;
ADD HL,DE ;
EX DE,HL ;
POP HL ;
INC HL ; i:=i+1
JR I_TOFF ; end
I_TOF1: JP BIOS ;
PAGE
;==============================================================================
;= INITIALIZE DISK TABLES =
;= move floppy/hard disk format array to runtime position =
;= count the number of atcive drives =
;==============================================================================
;
IDT: LD C,0 ; INIT. DRIVE COUNT
LD HL,INFD0 ; GET DEST. ADR.
LD DE,FD0 ; GET SRC. ADR.
IDT10: LD A,(HL) ; GET DRIVE # FORMAT CODE
CP 0FFH ; IF: FORMAT CODE = OK.
JP Z,IDT20 ; THEN: INIT FD# WITH CODE
LD (DE),A ;
INC C ; DRV. COUNT:=DRV. COUNT + 1
INC DE ;
INC HL ; GOTO INI10
JP IDT10 ; ELSE:
IDT20: LD A,C ;
DEC A ;
LD (DRNO),A ; INIT. MAX DRIVE NO.
RET ;
;====================================================================
;= HARD DISK OFFLINE OR READ ERROR FROM HARD DISK =
;====================================================================
HD_OFF: LD A,255 ; mark unit C as offline
LD (INFD2),A ;
XOR A ; drive A = boot unit
LD (BOOTD),A ;
CALL IDT ; re-initialize disk tables (drno=1)
JP BIOS ;
DS (BIOS-$) ; ALIGN TO DA00H
«eof»