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

444 lines
9.0 KiB
NASM

PL 58 ; PAGE LENGTH OF PRINTER
DEBUG EQU $00 ; 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
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
LDX #0
LDY #8
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: 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)
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
DB 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
DB 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
DB 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
DB 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
DB 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
DB 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
DB 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
DB 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
DB 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
; ---------
; 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.
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
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
DB 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
DB 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
DB 00,00,00,00,00,00,00,00,00
; MARKER
END