Files
erkyrath.infocom-zcode-terps/c-128/xzip/boot.asm
Andrew Plotkin b642da811e Initial commit.
2023-11-16 18:19:54 -05:00

460 lines
9.5 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
PL 58 ; PAGE LENGTH OF PRINTER
DEBUG EQU $0 ; 0 = NO, 1 = YES
ZEROPG EQU $03
ZPGTOP EQU $8F
COLD1 EQU $1200 ; WHERE TO ENTER THE REST OF THE CODE
INCLUDE EQ.ASM
INCLUDE HARDEQ.ASM
PAGE
STTL "--- MACHINE AUTOBOOT: CBM64 ---"
; ------------------
; THE VERY BEGINNING
; ------------------
ORG EZIP
; 'CBM' IS AUTOBOOT RECOGNITION CODE
; $00,$0C = TELLS AUTOBOOT TO READ REST IN STARTING AT $C00
; $00,$02 = READ IN 2 PAGES, $00 = NO DISK CODE, $00 = NO FILE NAME
DB 'C','B','M'
DB $00,$0C,$00,$02,$00,$00
LDA COLMODE ; 1ST MAKE SURE IN 40 COLUMN MODE
CMP #$80 ; TO DISPLAY 80 COL MONITOR NEEDED MSG
BNE OK40
JSR SWAPPER ; INTO 40 COL MODE
OK40: LDA #$0B ; DARK GRAY
STA EXTCOL ; BORDER
STA BGCOLO ; BACKGRND
STA FRCOLO ; FORGRND COLOR REG
LDY #>COLRAM
STY I+HI
LDY #<COLRAM
STY I+LO
IF DEBUG
; IN DEBUG NEED TO READ 40 COL DISPLAY
; SO LEAVE SCREEN AS IS (FILL IN CODE W/ NOPS)
DB $EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA
ELSE
LDY #0 ; SET COLOR RAM TO
LDX #4
CLR40: STA (I),Y ; DARK GRAY
INY
BNE CLR40
INC I+HI
DEX
BNE CLR40 ; ALL 4 PAGES
ENDIF
LDX #0
LDY #7
NEEDLP: LDA #$0F ; LIGHT GRAY CHARS FOR MSG
STA $DB48,Y ; SET THOSE BYTES IN COLOR RAM
LDA NEED,X ; SHOW MSG - PLACE DIRECTLY ON SCREEN
STA $748,Y ; LINE 20, COLUMN 8
INY
INX
CPX #NEEDL
BCC NEEDLP
JSR SWAPPER ; SET TO 80 COL DISPLAY
BOOT0:
;
; init expansion ram stuff if necessary
;
LDA #0
JSR RSETMSG ; no system messages please
LDA #%00000101 ; 4K SHARED RAM, LOW ($00-$10)
STA RCR
LDA #%01001110 ; SYS ROM, IO, TO BANK 1
STA CR ; THIS IS TO LOAD EZIP INTO BANK 1
; DO IT HERE SO IN JUMP TIME IT WILL
; TAKE EFFECT (NOT IMMEDIATE)
LDA #%00001001 ; 80 Column display
; Fast disk i/o
; 8502 processor
STA MCR ; and save it
LDA #$01 ; set fast mode!
STA FASTER ;
JMP COLD ; THIS PAGE WILL BECOME IOBUFF
; SO THIS JUMP WILL GET THINGS STARTED
; AND GET US OUT OF HERE AS THIS BOOT
; STUFF WILL DISSAPEAR
NEED: DB 56,48,32,03,15,12,21,13,14,32,13,15,14,09,20,15,18,32
DB 18,05,17,21,09,18,05,04 ; "80 COLUMN MONITOR REQUIRED"
NEEDL EQU $-NEED
; ---------
; COLDSTART
; ---------
; THERE IS NOT ENOUGH ROOM IN BANK0 FOR THE PRELOAD AS WE CAN'T START
; BEFORE $1C00 OR USE PAST $BFFF DUE TO THE KERNAL USE OF MEMORY
; SO: THIS RTN WILL LOAD THE ACTUAL INTERPRETER INTO BANK1 AND BANK1
; WILL BE USED AS THE MAIN BANK WITH BANK0 BEING USED AS THE SECOND,
; AUXILIARY BANK. IN ORDER TO USE BANK0 AND THE KERNAL THE FIRST 4K
; OF MEMORY IS BEING SET ASIDE AS COMMON MEMORY, TREATED AS BANK0
; SPACE BUT ABLE TO READ/WRITE TO BOTH BANKS. AT $400 IN THIS COMMON
; RAM WILL RESIDE THE RTNS TO READ/WRITE TO EITHER BANK AND TO SWITCH
; TO BANK0 FOR KERNAL USE AND BACK AGAIN. AS SOON AS THE INTERPRETER
; HAS BEEN LOADED BANK1 WILL BE SET TO ALL RAM, THE START OF THE
; INTERPRETER WILL BE JUMPED TO AND THE AREA THIS CODE IS IN WILL
; BE USED AS BUFFER SPACE.
ORG $C00
COLD: LDA #8 ; TURN DRIVE ON
JSR BDOPEN
LDA #1 ; SET TO READ IN COMMON CODE 1ST
STA TRACK
LDA #3 ; IT STARTS ON SECTOR 3
STA SECTOR ; AFTER ALL THIS LOADING SHIT
LDA #4
STA DBUFF+HI ; LOAD IT AT $400
LDA #0
STA DBUFF+LO
JSR GETONE ; GET 2 SECTORS OF CODE
JSR GETONE ; COMMON TO BOTH BANKS
LDA #$12 ; THEN MOVE IN THE REST
STA DBUFF+HI ; OF EZIP INTO BANK1
BIGLOOP: JSR GETONE
LDA DBUFF+HI
CMP #MAINSTRT ; THIS IS END OF EZIP, START OF GAME
BNE BIGLOOP
; INITIALIZE THE SOUND SYSTEM (WHILE STILL ACCESSIBLE)
LDX #$1C ; CLEAR
LDA #0 ; ALL
CLD0: STA FRELO1,X ; SID REGISTERS
DEX
BPL CLD0
LDA #2 ; SET VOICE #1
STA PWLO1 ; PULSE WIDTH
LDA #8 ; FOR A
STA PWHI1 ; 50% DUTY CYCLE
LDA #%10000000 ; DISABLE OUTPUT
STA SIGVOL ; FROM VOICE #3
LDA #$EE
STA FRELO3 ; SET VOICE #3 TO
STA FREHI3 ; AN AMUSING FREQUENCY
LDA #%10000000 ; SPECIFY NOISY WAVEFORM
STA VCREG3 ; FOR RANDOMNESS
LDA #%01111111
STA CR ; SET FOR NORMAL USE NOW
JMP COLD1 ; AND GO START THE THING FOR REAL
GETONE: CLC
JSR BDISK
BCS DKERR ; OOPS
LDY #0
LOOP: LDA IOBUFF,Y
STA (DBUFF),Y
INY
BNE LOOP
INC SECTOR ; NEXT SECTOR SO READY
LDY TRACK ; AS VARIABLE # OF SECTORS
LDA SECTOR ; PER TRACK, CHECK AGAINST
CMP TRKTAB,Y ; TBL WITH SIZE PER TRACK
BCC SECOK
INC TRACK
LDA #0
STA SECTOR
SECOK: INC DBUFF+HI
RTS
; DON'T BOTHER SKIPPING SECTOR 0 ON TRK 18 & 20
; AS DON'T ACCESS THOSE TRACKS IN THIS CODE
TRKTAB: DB 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21
DB 19,19,19,19,19,19,19
DB 18,18,18,18,18,18
DB 17,17,17,17,17
; *** ERROR #14: DRIVE ACCESS ***
DKERR: LDY #DRVML ; AS IT'S THE START, TELL THEM WHAT'S WRONG
DKERR1: LDA DRVMSG,X
JSR RCHROUT
INX
DEY
BNE DKERR1
JMP $ ; HANG AS WOULD REBOOT WITH SAME PROBLEM
DRVMSG: DB "DRIVE ACCESS ERROR"
DB EOL
DRVML EQU $-DRVMSG
PAGE
STTL "--- DISK ACCESS FOR BOOT: C-128 ---"
; NOTE: THIS IS SAME AS OTHER DISK ACCESS CODE
; BUT IS LOCATED SO BOOT CODE CAN USE IT TO READ
; INTERPRETER OFF THE DISK AND LOCATE IT CORRECTLY
; --------------
; OPEN DRIVE [A]
; --------------
; ENTRY: DISK ID (8 OR 9 BINARY) IN [A]
BI0: DB "I0"
BI0L EQU $-BI0
BDOPEN: STA DRIVE ; SAVE DRIVE ID HERE
JSR BDCLOSE ; CLOSE COMMAND & DATA CHANNELS
LDA #15 ; LOGICAL FILE #
TAY ; SECONDARY ADDRESS
LDX DRIVE ; DEVICE # (8 OR 9)
JSR RSETLFS ; SET UP LOGICAL FILE
LDX #<BI0 ; POINT TO FILENAME
LDY #>BI0 ; "I0:"
LDA #BI0L ; LENGTH OF FILENAME
JSR RSETNAM
JMP ROPEN ; OPEN THE DISK (CARRY CLEAR IF OK)
; --------------------------
; OPEN DIRECT ACCESS CHANNEL
; --------------------------
BPOUND: DB "#"
BPNDL EQU $-BPOUND
BAOPEN: LDA #0
; STA SPENA ; SHUT OFF CURSOR DMA
JSR BACLOSE ; CLOSE FIRST
LDA #2 ; D/A CHANNEL ID
TAY ; SECONDARY ID
LDX DRIVE
JSR RSETLFS
LDX #<BPOUND ; POINT TO FILENAME
LDY #>BPOUND ; "#"
LDA #BPNDL
JSR RSETNAM
JMP ROPEN ; OPEN CHANNEL (CARRY CLEAR IF OK)
; -------------------
; CLOSE CURRENT DRIVE
; -------------------
BDCLOSE: LDA #15 ; CLOSE COMMAND CHANNEL
JSR RCLOSE
; FALL THROUGH ...
; ---------------------
; CLOSE THE D/A CHANNEL
; ---------------------
BACLOSE: LDA #2 ; AND THE
JMP RCLOSE ; DATA CHANNEL
; ----------------
; DIVIDE [A] BY 10
; ----------------
; EXIT: QUOTIENT IN [X], REMAINDER IN [A]
BDIV10: LDX #0 ; START WITH ZERO QUOTIENT
BD10L: CMP #10 ; IF DIVISOR < 10,
BCC BD10EX ; WE'RE DONE
SBC #10 ; ELSE SUBTRACT ANOTHER 10
INX ; UPDATE QUOTIENT
BNE BD10L ; BRANCH ALWAYS
BD10EX: RTS
; ---------------
; SEND Ux COMMAND
; ---------------
; ENTRY: ASCII "1" OR "2" IN [A]
BCOMLIN: DB "U"
BDCOMM: DB "*"
DB ":2,0,"
BDTRAK: DB "***,"
BDSECT: DB "***"
DB EOL
BCMLL EQU $-BCOMLIN
BSENDU: STA BDCOMM ; INSERT COMMAND ("1" OR "2") IN STRING
; CONVERT [TRACK] AND [SECTOR] TO ASCII IN [COMLIN]
LDA TRACK
LDY #2
BTCON: JSR BDIV10 ; DIVIDE BY 10
ORA #'0' ; CONVERT TO ASCII
STA BDTRAK,Y ; STORE INTO STRING
TXA ; GET QUOTIENT INTO [A]
DEY ; ZERO-FILL USUSED BYTES
BPL BTCON
LDA SECTOR ; SAME FOR SECTOR ID
LDY #2
BSCON: JSR BDIV10
ORA #'0'
STA BDSECT,Y
TXA
DEY
BPL BSCON
; SEND COMMAND
JSR RCLRCHN
LDX #15 ; OUTPUT TO THE
JSR RCHKOUT ; COMMAND CHANNEL
BCS BUEX ; EXIT W/CARRY SET IF ERROR
LDY #0
BSCM0: LDA BCOMLIN,Y ; SEND THE COMMAND LINE
JSR RCHROUT ; TO THE DRIVE CHANNEL
INY ; A BYTE AT A TIME
CPY #BCMLL
BCC BSCM0
CLC ; SUCCESS!
BUEX: RTS
; ----------------------
; SET THE BUFFER POINTER
; ----------------------
BBPLINE: DB "B-P:2,0"
DB EOL
BBPLL EQU $-BBPLINE
BSETBP: JSR RCLRCHN
LDX #15 ; OUTPUT TO
JSR RCHKOUT ; COMMAND CHANNEL
BCS BBEX ; CARRY SET IF ERROR
LDY #0
BSBPL: LDA BBPLINE,Y
JSR RCHROUT
INY
CPY #BBPLL
BCC BSBPL
CLC
BBEX: RTS
; ------------------------------
; READ/WRITE A BLOCK TO [IOBUFF]
; ------------------------------
; ENTRY: [TRACK] = TRACK # (1-35)
; [SECTOR] = SECTOR # (0-15)
; [DRIVE] = DRIVE ID (8 OR 9)
; CARRY CLEAR TO READ, CARRY SET TO WRITE
BDISK: BCS BDWRITE ; WRITE IF CARRY SET
; READ A DISK BLOCK
JSR BAOPEN ; OPEN THE ACCESS CHANNEL
BCS BBADISK
LDA #'1' ; SEND A "U1" COMMAND
JSR BSENDU
BCS BBADISK ; CARRY SET IF ERROR
JSR BSETBP ; SET THE BUFFER POINTER
BCS BBADISK ; CARRY SET IF ERROR
JSR RCLRCHN
LDX #2 ; INPUT FROM
JSR RCHKIN ; DATA CHANNEL
BCS BBADISK
LDY #0
BREAD1: JSR RCHRIN ; GET A BYTE
STA IOBUFF,Y ; MOVE TO I/O BUFFER
INY
BNE BREAD1 ; DO 256 BYTES
BEQ BSHUTD ; THEN EXIT
; WRITE A BLOCK
BDWRITE: JSR BAOPEN ; OPEN THE ACCESS CHANNEL
BCS BBADISK
JSR BSETBP ; SET THE BUFFER POINTER
BCS BBADISK ; CARRY SET IF ERROR
JSR RCLRCHN
LDX #2 ; OUTPUT TO
JSR RCHKOUT ; DATA CHANNEL
BCS BBADISK ; CARRY SET IF ERROR
LDY #0
BWRITE1: LDA IOBUFF,Y ; SEND CONTENTS OF [IOBUFF]
JSR RCHROUT ; TO THE DRIVE
INY
BNE BWRITE1 ; WRITE 256 BYTES
LDA #'2' ; ISSUE A "U2" COMMAND
JSR BSENDU
BCS BBADISK ; CARRY SET IF ERROR
BSHUTD: JSR RREADST
AND #%10000011
BNE BBADISK
JSR RCLRCHN
CLC ; CARRY CLEAR FOR SUCCESS
RTS
BBADISK: JSR RCLRCHN
SEC
RTS ; OR SET IF ERROR
ORG $DFF ; just to fill out the sector with
; 'ff's, curtesy of the assembler!
DB $AA
; MARKER
END