+ X8 )18) lDISK FORMAT: CP/M DISK HAS NO BOOT LOGIC INSERT NEW BOOT DISK WHICH SLOT HAS BOOT DISK?Ӡ뮠ӠӠӠӠ묠堧姮APLDRVR ERM APLDRVR A65,SMLCHRIOA65SMLCHRIOERLYAPLDRVR ERLCPMBOOT A65 CP6502 A65!"#$%&'()*+,-./0CP6502 A65123456789:;<=>?@; ;EQUATES RWTSENTER: .EQU 0BD00H ;RWTS ENTRY POINT UNDER APPLEDOS INIT .EQU 0 ;INIT COMMAND READ .EQU 1 ;READ COMMAND WRITE .EQU 2 ;WRITE COMMAND FORMAT .EQU 4 ;FORMAT COMMAND FDISK .EQU 0 ;CPM DRIVE NUMBER OF APPLES FIRST DISK ;**************G THERE ; REMOVED CODE FOR FORMATTING ; REMOVED CODE FOR SUPPORTING MORE THAN 2 DRIVES ; INSTEAD ADDED CODE TO USE THE BOOTSLOT NUMBER ; ; 6/15/83 (WLS) ; REMOVED CODE WHICH CHANGED THE READ DELAY FOR MORE ROOM ; AND THERE ARE REPORTS OF READ /16/81 (WLS) ; CREATED ;******************************* FALSE .EQU 0 ;CONDITIONAL ASSEMLBY EQUATES TRUE .EQU NOT FALSE ;EXTERNALS .DEF IAP16,RAP16,WAP16,OAP16 ;EQUATES .NOLIST .INCLUDE DRVREQUS.A65 .LIST ; Following four EQUs defCP6502 A65MABCDEFGHIJCPMBOOT ERLQCPMBOOT PRN5KLMNOPSMLCHRIOPRNWRSTUVWXZ[\CP6502 ERL]^_APLDRVR PRNv `SEND HOST AND DISK PARAMETERS ; ; 6/16/82 (WLS) ; CHANGED FORMAT TO GET THE DRIVE NUMBER ; ; 5/26/82 (WLS) ; MOVED SECTOR TRANSLATION FROM Z80 BIOS TO HERE ; ADDED SNDPRM SUPPORT ; ; 4/28/82 (WLS) ; ADDED CODE TO SUPPORT BLOCK DEVICE TABLES ERRORS. MAY BE THIS WILL HELP ; ; 4/7/83 (WLS) ; REMOVED CODE TO RETURN DRIVER NAME TO MAKE MORE ROOM ; ; 9/3/82 (WLS) ; ADDED CODE TO SET PREVIOUS DRIVE AND SLOT ; ADDED CODE TO RETURN DRIVER NAME ; ; 8/1/82 (WLS) ; ADDED CALL RD1Z80BYTE IN ined in "DRVREQUS.A65" ;ABOOTSLOT: .EQU CP65+94 ;ADDRESS OF THE BOOT SLOT ;ABOOTPRMS: .EQU CP65+95 ;ADDRESS OF THE BOOT PARAMETERS ;ARWTSPSLOT: .EQU CP65+152 ;ADDRESS OF THE PREVIOUS SLOT ;ARWTSPDISK: .EQU CP65+153 ;ADDRESS OF THE PREVIOUS DISK .WIDTH 96 ;****************************** ;FILE: APLDRVR.A65 ;PURP: CALL THE APPLE DISK CONTROLER ;CHANGES: ; 12/6/83 (WLS) ; ADDED CODE TO SUPPORT ARWTSPSLOT AND ARWTSPDISK ; ; 6/29/83 (WLS) ; REMOVED CODE WHICH CHECK FOR THE CONTROLLER BEIN; ; 4/2/82 (WLS) ; ADDED CODE TO CHANGE MONTC2 DEPENDING ON TYPE OF COMMAND ; ADDED CODE TO CHECK IF THE CARD IS IN THE SLOT ; ; 2/24/82 (WLS) ; CHANGED TO ALLOW MULTIPLE CONTROLLERS ; ; 1/7/82 (WLS) ; MADE DRIVE 0 BE THE APPLE DRIVES ; ; 11***************** ;ROUTINES: IAP16,RAP16,WAP16,OAP16 ;PURP: HANDLE THE 4 ENTRY POINTS ;ENTRY: A,Y = ADDRESS OF PARAMETERS ;EXIT: IF NO ERRORS THEN ; A = 0 ; ELSE ; A <> 0 ;USED: A,F ;****************************** IAP16: LDA ABOOTSLOT S (ˮ!!>2S{:1:*6##ww#w$w#w:  ##N#F*B>2w#w#[s#r> "~ͯ*-w#ww##> ͯÂ""~>2:[R0 *4#4>2:[R> *4 #4(> AND SLOT LDA IBSLOT STA ARWTSPSLOT ;SET PREVIOUS SLOT LDA IBDRVN STA ARWTSPDISK ;SET PREVIOUS DRIVE ;RETURN WITH NO ERRORS NOERROR1: LDA #0 RTS FUNCTION: .BYTE 0 ;FUNCTION NUMBER IDX: .BYTE 0 ;TEMPORARY CNT: .BYTE 0 ;TEMPORARY BOOTPRMS,Y JSR WR1Z80BYTE ;SEND THE NEXT BYTE INC IDX ;INCREMENT TO NEXT BYTE LDY IDX CPY #23 ;ARE WE DONE ? BNE $0 ;BIF NOT DONE LDA #0 ;INDICATE NO ERRORS RTS ;CHECK FOR FORMAT COMMAND $1: CMP #FRMTCMD ;FORMAT BNE ERRXIT ;ERRORE COUNTER BYTE 2 SECTRAN: .BYTE 0,6,12,3,9,15,14,5,11,2,8,7,13,4,10,1 .END ;GET LOW BYTE OF DMA ADDRESS STA IBBUFP INY LDA (PG0W0),Y ;GET HIGH BYTE OF DMA ADDRESS STA IBBUFP+1 LDA FUNCTION ;GET FUCNTION BEQ NOERROR1 ;EXIT WITH NO ERRORS (A=0) IF COMMAND IS INIT STA IBCMD ;SET COMMAND LDA ARWTSPSLOT STA IBPSN TA IBSLOT ;SET SLOT IN IOB STA ARWTSPSLOT ;SET PREVIOUS SLOT LDA #1 STA ARWTSPDISK ;SET PREVIOUS DISK LDX #INIT ; JMP APLF16 BEQ APLF16 ;INIT = 0, SAVES ONE BYTE RAP16: LDX #READ ; JMP APLF16 BNE APLF16 ;READ <> 0, SAVE ONE BYTE WAS OF DEVICE CHARACTERICS TABLE IBBUFP: .WORD 0 ;BUFFER POINTER IBFREE: .WORD 0 ;UNUSED IBCMD: .BYTE 0 ;COMMAND 0=NUL, 1=READ, 2=WRITE, 3=FORMAT IBSTAT: .BYTE 0 ;ERROR STATUS 0=OK, 10H=WRITE PROTECTED ; 20H=BAD VOLUME, 40H=DRIVE ERROR, 80H=READ ERROADRIOB: .WORD IOB ;ADDRESS OF IOB IOB: IBTYPE: .BYTE 1 ;TYPE OF IOB IBSLOT: .BYTE 0 ;SLOT NUMBER * 16 IBDRVN: .BYTE 0 ;DRIVE NUMBER IBVOL: .BYTE 0 ;VOLUME NUMBER IBTRK: .BYTE 0 ;TRACK NUMBER IBSEC: .BYTE 0 ;SECTOR NUMBER IBDCTP: .WORD DCTB ;ADDRES EXIT JSR RD1Z80BYTE ;GET DRIVE NUMBER ERRXIT: LDA #0FFH ;UNKNOWN OTHER COMMAND RTS ;******************************** ;ROUTINE: APLF16 ;PURP: PERFORM AN APPLE 16 SECTOR CALL ;ENTRY: A = HIGH BYTE OF PARAMETERS ; Y = LOW BYTE OF PARAMETERS ;:4^q*##~6ͻ>2}*|(̈́|( ̈́6-#[RM8( G> A~#*(C! !TRUEFALSE!9N#Z~#( G~#> >    "~(lѻ(( !0 ;SET PREVIOUS SLOT NUMBER LDA ARWTSPDISK STA IBPDN ; AND PREVIOUS DISK NUMBER LDA ADRIOB+1 ;A,Y = ADDRESS OF IOB LDY ADRIOB JSR RWTSENTER BCC NOERROR ;BIF NO ERRORS ERROR: LDA #0FFH ;ELSE ERROR RTS NOERROR: ;CHANGE THE PREVIOUS DISKP16: LDX #WRITE ; JMP APLF16 BNE APLF16 ;WRITE <> 0, SAVE ONE BYTE OAP16: CMP #SNDPRMCMD ;IS THIS THE SEND PARAMETERS COMMAND BNE $1 ;SEND THE HOST AND DISK PARAMETERS JSR RD1Z80BYTE ;GET THE DRIVER NUMBER LDY #0 STY IDX $0: LDA AR IBSMOD: .BYTE 0 ;ACTUAL VOLUME NUMBER IBPSN: .BYTE 0 ;PREVIOUS SLOT NUMBER * 16 IBPDN: .BYTE 1 ;PREVIOUS DISK NUMBER DCTB: .BYTE 0 ;DEVICE TYPE CODE PPTC: .BYTE 1 ; MONTC: .BYTE 0EFH ;MOTOR ON TIME COUNTER BYTE 1 MONTC2: .BYTE 0D8H ;MOTOR ON TIM STA IBDRVN INC IBDRVN ;INCREMENT TO 1 OR 2 LDY #OCURTRK LDA (PG0W0),Y STA IBTRK ;SET TRACK LDY #OCURSEC LDA (PG0W0),Y ;GET REQUESTED SECOTOR TAY LDA SECTRAN,Y ;TRANSLATE THE SECTOR STA IBSEC ;STORE IT LDY #OCURDMA LDA (PG0W0),Y EXIT: IF NO ERRORS THEN ; A = 0 ; ELSE ; A = 1 ;USED: A,F ;****************************** APLF16: STX FUNCTION STA PG0W0+1 ;SAVE POINTER TO PARAMETERS STY PG0W0 ;THE SLOT IS SET BY INIT TO SAVE SPACE LDY #OCURDSK LDA (PG0W0),Y Page 1 0000: .WIDTH 96 0000: ;****************************** 0000: ;FILE: APLDRVR.A65 0000: ;PURP: CALL THE APPLE DISK CONTROLER 0000: ;CHANGES: 0000: ; 12/6/83 (WL 0000: ;******************************* 0000: ;ROUTINES: IAP16,RAP16,WAP16,OAP16 0000: ;PURP: HANDLE THE 4 ENTRY POINTS 0000: ;ENTRY: A,Y = ADDRESS OF PARAMETERS 0000: ;EXIT: IF NO EROLLERS 0000: ; 0000: ; 1/7/82 (WLS) 0000: ; MADE DRIVE 0 BE THE APPLE DRIVES 0000: ; 0000: ; 11/16/81 (WLS) 0000: ; CREATED 0000: ; 6/15/83 (WLS) 0000: ; REMOVED CODE WHICH CHANGED THE READ DELAY FOR MORE ROOM 0000: ; AND THERE ARE REPORTS OF READ ERRORS. MAY BE THIS WILL HELP 0000: ; 0000: ; 4/7/83 (WP65+153 ;ADDRESS OF THE PREVIOUS DISK 0000: 0000: ; 0000: ;EQUATES 0000: BD00 = RWTSENTER: .EQU 0BD00H ;RWTS ENTRY POINT UNDER APPLEDOS 0000: 0000 = INIT .EQU 0 ;INIT COMMAND 0000: 0001 = REANDPRM SUPPORT 0000: ; 0000: ; 4/28/82 (WLS) 0000: ; ADDED CODE TO SUPPORT BLOCK DEVICE TABLES 0000: ; 0000: ; 4/2/82 (WLS) 0000: ; ADDED COS) 0000: ; ADDED CODE TO SUPPORT ARWTSPSLOT AND ARWTSPDISK 0000: ; 0000: ; 6/29/83 (WLS) 0000: ; REMOVED CODE WHICH CHECK FOR THE CONTROLLER BEING THERE 0000: ; IAP16,RAP16,WAP16,OAP16 0000: 0000: Page 2 0000: ;EQUATES 0000: .NOLIST 0000: .LIST 0000: 0000: ; Following four EQUs defined in "DRVREQUS.A65" 000******************************* 0000: 0000: 0000 = FALSE .EQU 0 ;CONDITIONAL ASSEMLBY EQUATES 0000: FFFF = TRUE .EQU NOT FALSE 0000: 0000: ;EXTERNALS 0000: .DEF LS) 0000: ; REMOVED CODE TO RETURN DRIVER NAME TO MAKE MORE ROOM 0000: ; 0000: ; 9/3/82 (WLS) 0000: ; ADDED CODE TO SET PREVIOUS DRIVE AND SLOT 0000: ; D .EQU 1 ;READ COMMAND 0000: 0002 = WRITE .EQU 2 ;WRITE COMMAND 0000: 0004 = FORMAT .EQU 4 ;FORMAT COMMAND 0000: 0000: 0000 = FDISK .EQU 0 ;CPM DRIVE NUMBER OF APPLES FIRST DISK 0000:DE TO CHANGE MONTC2 DEPENDING ON TYPE OF COMMAND 0000: ; ADDED CODE TO CHECK IF THE CARD IS IN THE SLOT 0000: ; 0000: ; 2/24/82 (WLS) 0000: ; CHANGED TO ALLOW MULTIPLE CONT REMOVED CODE FOR FORMATTING 0000: ; REMOVED CODE FOR SUPPORTING MORE THAN 2 DRIVES 0000: ; INSTEAD ADDED CODE TO USE THE BOOTSLOT NUMBER 0000: ; 0000: ; 0: ;ABOOTSLOT: .EQU CP65+94 ;ADDRESS OF THE BOOT SLOT 0000: ;ABOOTPRMS: .EQU CP65+95 ;ADDRESS OF THE BOOT PARAMETERS 0000: ;ARWTSPSLOT: .EQU CP65+152 ;ADDRESS OF THE PREVIOUS SLOT 0000: ;ARWTSPDISK: .EQU C00: ; CHANGED FORMAT TO GET THE DRIVE NUMBER 0000: ; 0000: ; 5/26/82 (WLS) 0000: ; MOVED SECTOR TRANSLATION FROM Z80 BIOS TO HERE 0000: ; ADDED S ADDED CODE TO RETURN DRIVER NAME 0000: ; 0000: ; 8/1/82 (WLS) 0000: ; ADDED CALL RD1Z80BYTE IN SEND HOST AND DISK PARAMETERS 0000: ; 0000: ; 6/16/82 (WLS) 00RRORS THEN 0000: ; A = 0 0000: ; ELSE 0000: ; A <> 0 0000: ;USED: A,F 0000: ;****************************** 0000: 0000: IAP16: 0000: AD5EB0 ;****************************** 0043: 0043: APLF16: 0043: 8EA400 STX FUNCTION 0046: 8506 STA PG0W0+1 ;SAVE POINTER TO PARAMETERS 0048: 8405 STY PG0W0 004A: ;SEND THE HOST AND DISK PARAMETERS 001E: 2009B0 JSR RD1Z80BYTE ;GET THE DRIVER NUMBER 0021: A000 LDY #0 0023: 8CA500 STY IDX Page 3 0026: $0: 0026: B95FB0 ; JMP APLF16 0014: D02D BNE APLF16 ;READ <> 0, SAVE ONE BYTE 0016: 0016: WAP16: 0016: A202 LDX #WRITE 0018: ; JMP APLF16 0018: D029 ND 0042: 60 RTS 0043: 0043: 0043: ;******************************** 0043: ;ROUTINE: APLF16 0043: ;PURP: PERFORM AN APPLE 16 SECTOR CALL 0043: ;ENTRY: A = HIGH BYTE R THE FUNCKEY BUFFER DL1FCMD: .EQU 12 ;DOWN LOAD 1 FUNCKEY STRING ULAFCMD: .EQU 13 ;UP LOAD FUNCTION KEY BUFFER DLAFCMD: .EQU 14 ;DOWN LOAD FUNCTION KEY BUFFER SELFB1: .EQU 16 ;SELECT FUNCKEY BUFFER 1 SELFB2: .EQU 17 ;SELECT FUNCKEY BUFFER 2 R LDA ABOOTSLOT 0003: 8DAA00 STA IBSLOT ;SET SLOT IN IOB 0006: 8D98B0 STA ARWTSPSLOT ;SET PREVIOUS SLOT 0009: A901 LDA #1 000B: 8D99B0 STA ARWTSPDISK ;SET PREVIE WE DONE ? 0034: D0F0 BNE $0 ;BIF NOT DONE 0036: A900 LDA #0 ;INDICATE NO ERRORS 0038: 60 RTS 0039: 0039: ;CHECK FOR FORMAT COMMAND 0 LDA ABOOTPRMS,Y 0029: 200CB0 JSR WR1Z80BYTE ;SEND THE NEXT BYTE 002C: EEA500 INC IDX ;INCREMENT TO NEXT BYTE 002F: ACA500 LDY IDX 0032: C017 CPY #23 ;AR\Th=@RAP16UT M@\iy`@RFV b @R4bJ@FZP}` ,֔Yi@vR02@-TH! `V@Z@;FbFB @ Hm0Fۀje` P T TL,X*@j@ @OF PARAMETERS 0043: ; Y = LOW BYTE OF PARAMETERS 0043: ;EXIT: IF NO ERRORS THEN 0043: ; A = 0 0043: ; ELSE 0043: ; A = 1 0043: ;USED: A,F 0043: BNE APLF16 ;WRITE <> 0, SAVE ONE BYTE 001A: 001A: OAP16: 001A: C900 CMP #SNDPRMCMD ;IS THIS THE SEND PARAMETERS COMMAND 001C: D01B BNE $1 001E: 001E: OUS DISK 000E: A200 LDX #INIT 0010: ; JMP APLF16 0010: F031 BEQ APLF16 ;INIT = 0, SAVES ONE BYTE 0012: 0012: RAP16: 0012: A201 LDX #READ 0014:039: C901 $1: CMP #FRMTCMD ;FORMAT 003B: D003 BNE ERRXIT ;ERROR EXIT 003D: 2009B0 JSR RD1Z80BYTE ;GET DRIVE NUMBER 0040: A9FF ERRXIT: LDA #0FFH ;UNKNOWN OTHER COMMAN THE OTHER DEVICE APPLEON: .EQU 3 ;TURN ON THE APPLE DISPLAY WDTHDSP: .EQU 4 ;WIDTH OF THE DISPLAY CLAFCMD: .EQU 11 ;CLEA0H<phThOAP16U$hWAP16b @R4bJ@FZP}` ,֔Yi@vR02@-TH! `V@Z@;FbFB @ Hm0Fۀje` P T TL,X*@j@ @ ;THE SLOT IS SET BY INIT TO SAVE SPACE 004A: A000 LDY #OCURDSK 004C: B105 LDA (PG0W0),Y 004E: 8DAB00 STA IBDRVN 0051: EEAB00 INC IBDRVN ;INCR.EQU FALSE ;TRUE FOR DEBUG CODE ;ENTRY POINTS .DEF APLINIT,APLIN,APLOUT,APLOTHER .NOLIST .INCLUDE DRVREQUS.A65 .LIST LINEBASE: .EQU 28H ;BASE OF CURRENT SCREEN LINE CURSORH: .EQU 24H ;CURRENT CURSOR HORZITIONAL POSITION CURSORV: .EQU 25H ;PURP: THIS IS THE FIRST STAGE FOR CPM BOOT OFF 0000: ; THE MINI FLOPPIES. GETS READ IN BY THE 0000: ; FIRMWARE AND THEN READS IN TRACKS 0..2 0000: ; AND EXECTUES AT THE LOAD ADDRESS 0000: 105 LDA (PG0W0),Y ;GET LOW BYTE OF DMA ADDRESS 006A: 8DB100 STA IBBUFP 006D: C8 INY 006E: B105 LDA (PG0W0),Y ;GET HIGH BYTE OF DMA ADDRESS 0070: 8DB200 STA VED INITIALIZTION OF SFTVIDEO STUFF TO SAVE ROOM ; ; 7/2/82 (WLS) ; ADDED TEST IN OTHER FOR COMMANDS GREATER THAN 1 ; TO RETURN A 0. REMOVED WIDTH DISPLAY INITIALIZATION ; ; 5/26/82 (WLS) ; ADDED CALL TO HOME AND CLEAR SCREEN ROUTINE IN ROM ; ;ELSE ERROR 0094: 60 RTS 0095: 0095: NOERROR: 0095: ;CHANGE THE PREVIOUS DISK AND SLOT 0095: ADAA00 LDA IBSLOT 0098: 8D98B0 STA ARWTSPSLOT ;SET PREMENT TO 1 OR 2 0054: 0054: A001 LDY #OCURTRK 0056: B105 LDA (PG0W0),Y 0058: 8DAD00 STA IBTRK ;SET TRACK 005B: A003 LDY #OCURSEC 005D: B105 LDA ;****************************************** 0000: 0000: 9100 = LOADADR .EQU 9100H ;LOAD ADDRESS SYSTEM CODE 0000: B000 = GOADR .EQU B000H ;GO ADDRESS AFTER LOADING 0000: B05E = ;CHANGES: 0000: ; 6/30/83 (WLS) 0000: ; ADDED CODE TO SET THE DEFAULT SLOT OF THE BOOT DRIVE 0000: ; 0000: ; 12/23/81 (WLS) 0000: ; CREATED 0000: IBBUFP+1 0073: ADA400 LDA FUNCTION ;GET FUCNTION 0076: F029 BEQ NOERROR1 ;EXIT WITH NO ERRORS (A=0) IF COMMAND IS INIT 0078: 8DB500 STA IBCMD ;SET COMMAND 007B: 007B; 5/10/82 (WLS) ; ADDED INITIALIZATION OF TYPECARD ; ; 5/6/82 (WLS) ; MODIFIED FOR DEVICE HANDLER CONVECTIONS ; ; 2/20/82 (WLS) ; CREATED ;****************************** TRUE: .EQU 1 ;VALUE FOR TRUE FALSE: .EQU 0 ;VALUE FOR FALSE DEBUG: Page 1 CPMBOOT 0000: .TITLE "CPMBOOT" 0000: .WIDTH 96 0000: ;****************************************** 0000: ;FILE: CPMBOOT.A65 0000: (PG0W0),Y ;GET REQUESTED SECOTOR 005F: A8 TAY 0060: B9BE00 LDA SECTRAN,Y ;TRANSLATE THE SECTOR 0063: 8DAE00 STA IBSEC ;STORE IT 0066: A005 LDY #OCURDMA 0068: B .TITLE "SMALL CHARIO KS Z80 COMPUTER" .WIDTH 96 ;****************************** ;FILE: SMLCHRIO.A65 ;PURP: SMALL CHARIO ROUTINES FOR THE BOOT CODE ;CHANGES: ; 6/29/83 (WLS) ; REMOVED DIRECT CALLS TO THIS CODE, ICHARIO, CONST,CONIN,CONOUT ; REMOADA800 LDA ADRIOB+1 ;A,Y = ADDRESS OF IOB 008A: ACA700 LDY ADRIOB 008D: 2000BD JSR RWTSENTER 0090: 9003 BCC NOERROR ;BIF NO ERRORS 0092: A9FF ERROR: LDA #0FFH : AD98B0 LDA ARWTSPSLOT Page 4 007E: 8DB800 STA IBPSN ;SET PREVIOUS SLOT NUMBER 0081: AD99B0 LDA ARWTSPDISK 0084: 8DB900 STA IBPDN ; AND PREVIOUS DISK NUMBER 0087: ;CURRENT CURSOR VERTICAL POSITION CURCHR: .BLOCK 1 ;CURRENT CHARACTER AT CURSOR POSITION ;************************************ ;ROUTINE: INITIALIZE ROUTINES ;PURP: INITIALIZE THE CARDS ;ENTRY: Y = n0 ; X = Cn ;EXIT: THE CARD IS INITIALIZED ;USED TO RETURN A 0. REMOVED WIDTH DISPLAY INITIALIZATION 0000: ; 0000: ; 5/26/82 (WLS) 0000: ; ADDED CALL TO HOME AND CLEAR SCREEN ROUTINE IN ROM 0000: ; 0000: ; 5/10/82 (W KNOW THEN RETURN A 0 TAY ;SET FLAGS BEQ CHREADY ;IF 0 THEN OUTPUT STATUS SO ALWAYS READY APLINSTAT: ; ELSE DO INPUT STATUS BIT 0C000H BPL CHNOTREADY CHREADY: LDA #0FFH SEC RTS CHNOTREADY: LDA #0 CLC RTS .END OR A CHARACTER TO BECOME AVAILABLE STA 0C010H ;CLEAR STROBE AND #07FH ;CLEAR BIT 7 RTS ;*********************************** ;ROUTINE: APLOUT ;PURP: OUTPUT A CHARCTER TO THE DEVICE ;ENTRY: A = CHARACTER ; Y = n0 ; X = Cn ;EXIT: NONE ;USEHRIO.A65 0000: ;PURP: SMALL CHARIO ROUTINES FOR THE BOOT CODE 0000: ;CHANGES: 0000: ; 6/29/83 (WLS) 0000: ; REMOVED DIRECT CALLS TO THIS CODE, ICHARIO, CONST,CONIN,CONOUT 0000: HARACTER AND #7FH ;TURN OFF BIT 7 ORA #40H ;TURN ON BIT 6 STA (LINEBASE),Y ;MAKES A FLASHING CURSOR RTS ;******************************* ;ROUTINE: APLOTHER ;PURP: RETURN THE STATUS ;ENTRY: A = STATUS TYPE = 0 = OUTPUT STATUS, 1 = INPUT STAT: ALL ;************************************ APLINIT: LDA #0A0H ;MAKE CURRENT CHARACTER A SPACE STA CURCHR LDA #60H ;MAKE CURSOR A FLASHING SPACE LDY CURSORH STA (LINEBASE),Y ;CLEAR THE SCREEN JMP 0FC58H ;CALL THE HOME AND CLEAR SCREEicable. If you have no command to clear the screen, enter - (hyphen). ----------------------------------------------------------------- Does CLEAR SCREEN also HOME cursor? _ This is normally the case; if it is not so on your terminal, enter cursor address for your terminal. ----------------------------------------------------------------- CLEAR SCREEN command: _ Enter the command that will clear the entire contents of your screen, both foreground and background, if applD: A,F,Y,X ;********************************** APLOUT: PHA ;SAVE CHARACTER ;RESTORE CHARACTER AT CURSOR LDA CURCHR LDY CURSORH STA (LINEBASE),Y PLA ;RESTORE CHARACTER CMP #0DH ;CHECK FOR CARRIAGE RETURN BNE $1 ;BIF NOT LDA ; REMOVED INITIALIZTION OF SFTVIDEO STUFF TO SAVE ROOM 0000: ; 0000: ; 7/2/82 (WLS) 0000: ; ADDED TEST IN OTHER FOR COMMANDS GREATER THAN 1 0000: ; US ; Y = n0 ; X = Cn ; WHERE n = THE SLOT NUMBER 0..7 ;EXIT: IF READY (WITH INPUT OR OK TO OUTPUT) THEN ; A=0FFH ; C=1 ; ELSE ; A=0 ; C=0 ;USED: A,F,Y ;******************************* APLOTHER: CMP #2 BCS CHNOTREADY ;IF DO NOTN ROUTINE IN ROM ;*********************************** ;ROUTINE: APLIN ;PURP: GET A CHARCTER FROM A CARD ;ENTRY: Y = n0 ; X = Cn ;EXIT: A = CHARACTER ;USED: A,F,Y,X ;*********************************** APLIN: LDA 0C000H BPL APLIN ;WAIT F Page 1 SMALL CHARIO KS Z80 COMPUTER 0000: .TITLE "SMALL CHARIO KS Z80 COMPUTER" 0000: .WIDTH 96 0000: ;****************************** 0000: ;FILE: SMLCP #"z"+1 BCS $2 ;BIF GREATER THAN LOWER CASE Z SEC SBC #20H ;ELSE MAKE LOWER CASE $2: ORA #80H ;SET BIT 7 JSR 0FDF0H ;OUTPUT CHARACTER ;MAKE A FLASHING CURSOR (BIT 7 = 0, BIT 6 = 1) $3: LDY CURSORH LDA (LINEBASE),Y STA CURCHR ;SAVE C #0 STA CURSORH ;IF IT IS A CR THEN JUST SET CURSOR ; POSITION TO 0 SO AUTOMATIC LIND FEEDS AFTER ; CARRIAGE RETURNS DO NOT OCCUR BEQ $3 ;ALWAYS TAKEN ;CONVERT LOWER TO UPPER CASE $1: CMP #"a" BCC $2 ;BIF LESS THAN LOWER CASE A CMEVIOUS SLOT 009B: ADAB00 LDA IBDRVN 009E: 8D99B0 STA ARWTSPDISK ;SET PREVIOUS DRIVE 00A1: 00A1: ;RETURN WITH NO ERRORS 00A1: NOERROR1: 00A1: A900 LDA #0 CMD EQ B05B: ALSTSLT EQ B049: AMONITOR EQ B02A: AOSLCLAD EQ B02F AOSLEN EQ B033: AOSSLVAD EQ B031: AOSSTART EQ B035: AOTHRRES EQ B026: APLF16 PL 0043 APLON EQ 8FB6: APPLEON EQ 0003: AREBOOTV EQ B028: ARESCODE EQ B024: ARESETIF EQ B078 ARWTSPDI 0H<phThOAP16U$hWAP16b @R4bJ@FZP}` ,֔Yi@vR02@-TH! `V@Z@;FbFB @ Hm0Fۀje` P T TL,X*@j@ @MBER 00AC: 00 IBVOL: .BYTE 0 ;VOLUME NUMBER 00AD: 00 IBTRK: .BYTE 0 ;TRACK NUMBER 00AE: 00 IBSEC: .BYTE 0 ;SECTOR NUMBER 00AF: BA00 IBDCTP: .WORD DCTB ;ADDRESS OF DEVICE CHARACTERICS TABLE 6: @2CMDDEF EQ 0003: @2CURPOL EQ 0075 @2HARDDE EQ 0003: @2HARDGX EQ 0003: @2OTHRON EQ 00B8: @2POLLTB EQ 0076: @2TRANSL EQ 0002 @2TRANVE EQ 0000: @2TYPECA EQ 006D: AACMDARY EQ B05C: ABEGSLT EQ B047: ABEGSLTA EQ B048 ABOOTPRM EQ B05F: ABOOTSLO EQ B05E: A MONTC2: .BYTE 0D8H ;MOTOR ON TIME COUNTER BYTE 2 00BE: 00BE: SECTRAN: 00BE: 00060C0309 .BYTE 0,6,12,3,9,15,14,5,11,2,8,7,13,4,10,1 00C3: 0F0E050B02 00C8: 08070D040A 00CD: 01 00CE: 00CE: 00A3: 60 RTS 00A4: 00A4: 00A4: 00 FUNCTION: .BYTE 0 ;FUNCTION NUMBER 00A5: 00 IDX: .BYTE 0 ;TEMPORARY 00A6: 00 CNT: .BYTE 0 ;TEMPORARYDX ;INCREMENT TO NEXT BYTE LDY IDX CPY #23 ;ARE WE DONE ? BNE $0 ;BIF NOT DONE LDA #0 ;INDICATE NO ERRORS RTS ;CHECK FOR FORMAT COMMAND $1: CMP #FRMTCMD ;FORMAT BNE ERRXIT ;ERROR EXIT JSR RD1Z80BYTE ;GET DRIVE NUMBER ERRXIT: LDA #S JSR RD1Z80BYTE ;GET THE DRIVER NUMBER LDY #0 STY IDX $0: LDA ABOOTPRMS,Y JSR WR1Z80BYTE ;SEND THE NEXT BYTE INC I00B1: 0000 IBBUFP: .WORD 0 ;BUFFER POINTER 00B3: 0000 IBFREE: .WORD 0 ;UNUSED 00B5: 00 IBCMD: .BYTE 0 ;COMMAND 0=NUL, 1=READ, 2=WRITE, 3=FORMAT 00B6: 00 IBSTAT: .BYTE 0 ;ERROR STATUS 0=OK, 10HDRIOB PL 00A7: ADSKBUF EQ B076: ADZ80 EQ B09D AEZ80 EQ B09A: AFRSTCMD EQ B05A: AHSTIDB EQ B046: AIDSKSZ EQ B03D: AIHIMEM EQ B040 AIHIPG0 EQ B042: AILOMEM EQ B03F: AILOPG0 EQ B041: AINITBLK EQ B04A: AINITCHR EQ B052 AISYSPG EQ B043: ALAST\Th=@RAP16UT M@\iy`@RFV b @R4bJ@FZP}` ,֔Yi@vR02@-TH! `V@Z@;FbFB @ Hm0Fۀje` P T TL,X*@j@ @ 00A7: A900 ADRIOB: .WORD IOB ;ADDRESS OF IOB 00A9: IOB: 00A9: 01 IBTYPE: .BYTE 1 ;TYPE OF IOB 00AA: 00 IBSLOT: .BYTE 0 ;SLOT NUMBER * 16 00AB: 00 IBDRVN: .BYTE 0 ;DRIVE NU .END 00B00 TP 0026: 00B01 TP 0039: @1BLKDEV EQ 0000: @1CHRDEV EQ 0080: @1IBDEV EQ 0000 @1ICDEV EQ 0080: @1OBDEV EQ 0006: @1OCDEV EQ 0086: @1RBDEV EQ 0002: @1RCDEV EQ 0082 @1WBDEV EQ 0004: @1WCDEV EQ 0084: @2APLON EQ 00B IBPDN: .BYTE 1 ;PREVIOUS DISK NUMBER 00BA: 00BA: 00 DCTB: .BYTE 0 ;DEVICE TYPE CODE 00BB: 01 PPTC: .BYTE 1 ; 00BC: EF MONTC: .BYTE 0EFH ;MOTOR ON TIME COUNTER BYTE 1 00BD: D8 =WRITE PROTECTED 00B7: ; 20H=BAD VOLUME, 40H=DRIVE ERROR, 80H=READ ERROR 00B7: 00 IBSMOD: .BYTE 0 ;ACTUAL VOLUME NUMBER 00B8: 00 IBPSN: .BYTE 0 ;PREVIOUS SLOT NUMBER * 16 00B9: 01 EQ B099: ARWTSPSL EQ B098: AVERHI EQ B02D: AVERLOW EQ B02C: AWALCNT EQ B045 AWBLCLAD EQ B037: AWBLEN EQ B039: AWBSTART EQ B03B: AWCMDCNT EQ B044: AZ80SLOT EQ B02E BEGINCP6 EQ B000: BFP0BASE EQ 0086: BLKDEVS EQ 8E00: CHRDEVS EQ 8E80: CLAFCMD EQ 0STA TRACK PATCH: ;PATCH READ SECTOR ADDRESS JSR RDSEC ;READ THE SECTOR INC SEC LDA SEC CMP #LASTSEC+1 BNE RDLP ;CONTINUE UNTIL DONE WITH TRACK ;INCREMENT TO NEXT TRACK LDA TRK AND #3 ASL A ;MULTIPLY BY 4 ASL A ORA SLOT16 ADDRESS ;CHANGES: ; 6/30/83 (WLS) ; ADDED CODE TO SET THE DEFAULT SLOT OF THE BOOT DRIVE ; ; 12/23/81 (WLS) ; CREATED ;****************************************** LOADADR .EQU 9100H ;LOAD ADDRESS SYSTEM CODE GOADR .EQU B000H ;GO ADDRESS AFTDDEF EQ 8F03: HARDGXY EQ 8F03 HARDGXYB EQ 8F54: HARDGXYO EQ 8F53: HIMEM EQ 0012: HIPG0 EQ 0015: IAP16 DF 0000 IBBUFP PL 00B1: IBCMD PL 00B5: IBDCTP PL 00AF: IBDEV EQ 8E00: IBDRVN PL 00AB IBFREE PL 00B3: IBPDN PL 00B9: IBPSN EAD SECTOR CALL ;CHANGE THE NOP ABOVE TO AN RTS SO THAT THE FRIMWARE RDSEC ROUTINE ; BECOMES A SUBROUTINE LDA #060H ;OPCODE FOR RTS STA CPMBOOT+1 ; CHANGE THE NOP TO RTS ;READ IN 3 TRACKS STARTING AT TRACK 0 SECTOR 1 TO LOADADR LDA #LOADADOLLROUT EQ B003: POLLTBL EQ 8F76: PPTC PL 00BB: PWREDUP EQ 03F4: RAP16 DF 0012 RBDEV EQ 8E02: RCDEV EQ 8E82: RD1Z80BY EQ B009: RDNZ80BY EQ B015: READ EQ 0001 RETCFB EQ 0012: RWTSENTE EQ BD00: SCRNBASE EQ 000C: SECTRAN PL 00BE: SELFB00B CMDARYPT EQ 0080: CMDDEFS EQ 8F03: CMDLPENT EQ B006: CNT PL 00A6: CP65 EQ B000 CURPOLLN EQ 8F75: DCTB PL 00BA: DEVTBL EQ 8E00: DL1FCMD EQ 000C: DLAFCMD EQ 000E EFP0BASE EQ 00FF: ENDEXTRA EQ B0A0: ENDFIXED EQ 8FB9: ERROR PL 0092: ;SLOT NUMBER * 16 OF CARD LASTSEC .EQU 15 ;LAST SECTOR OF TRACK LASTTRK .EQU 2 ;LAST TRACK TO READ WAIT .EQU 0FCA8H ;WAIT ROUTINE IN APPLE MONITOR ROM CPMBOOT: .BYTE 1 ;THE FIRST BYTE OF THE FIRST SECTOR IS THE ; NUMBER OF SECTORS TO RER LOADING ABOOTSLOT .EQU GOADR+94 ;ADDRESS OF THE BOOT SLOT RDSEC .EQU 0C65CH ;ADDRESS OF THE READ SECTOR ROUTINE TRACK .EQU 041H ;RDSECTOR TRACK SECTOR .EQU 03DH ;RDSECTOR SECTOR BUFADR .EQU 026H ;RDSECTOR BUFFER ADDRESS SLOT16 .EQU 02BH PL 00B8: IBSEC PL 00AE: IBSLOT PL 00AA IBSMOD PL 00B7: IBSTAT PL 00B6: IBTRK PL 00AD: IBTYPE PL 00A9: IBVOL PL 00AC ICDEV EQ 8E80: IDX PL 00A5: INIT EQ 0000: INITOFFS EQ 0000: INOFFSET EQ 0002 IOB PL 00A9: ISTATCDE EQR AND 0FFH ;LOW BYTE STA BUFADR LDA #LOADADR U/ 256 ;HIGH BYTE STA BUFADR+1 LDA #1 ;SECTOR 1 STA SEC LDA #0 ;TRACK 0 STA TRK RDLP: LDY SEC ;GET SECTOR LDA SECTRAN,Y ; TRANSLATE TO PHYSICAL STA SECTOR LDA TRK ;GET TRACK .TITLE "CPMBOOT" .WIDTH 96 ;****************************************** ;FILE: CPMBOOT.A65 ;PURP: THIS IS THE FIRST STAGE FOR CPM BOOT OFF ; THE MINI FLOPPIES. GETS READ IN BY THE ; FIRMWARE AND THEN READS IN TRACKS 0..2 ; AND EXECTUES AT THE LOAD ERRXIT PL 0040 FALSE EQ 0000: FDISK EQ 0000: FLUSHCMD EQ 0002: FORMAT EQ 0004: FRMTCMD EQ 0001 FRSTVHI EQ 0076: FRSTVLO EQ 00B5: FUNCTION PL 00A4: GOTOBHDL EQ B00F: GOTOCHDL EQ B012 GOTOINIT EQ B01B: GOTOWB EQ B01E: GXYOFFSE EQ 0000: HAREAD NOP ;THIS IS WHERE CONTROL IS TRANSFER TO BY ; RDSEC. THIS WILL BE PATCHED TO A RTS ;SET SLOT AND PATCH THE READ SECTOR CALL LDX SLOT16 TXA LSR A LSR A LSR A LSR A ORA #0C0H ;FORM CN FOR READ SECTOR STA PATCH+2 ;PATCH THE R0: OCURSEC EQ 0003: OCURTRK EQ 0001: OPG0BASE EQ 0080: OSTATCDE EQ 0000 OTHERON EQ 0002: OTHOFFSE EQ 0006: OTHRON EQ 8FB8: OUTOFFSE EQ 0004: PG0B0 EQ 0009 PG0B1 EQ 000A: PG0B2 EQ 000B: PG0BASE EQ 0005: PG0W0 EQ 0005: PG0W1 EQ 0007 P 0001: LOMEM EQ 0010: LOPG0 EQ 0014: MONTC PL 00BC MONTC2 PL 00BD: NOERROR PL 0095: NOERROR1 PL 00A1: NOTUSED EQ B021: NUMBLKDE EQ 0010 NUMCHRDE EQ 0010: OAP16 DF 001A: OBDEV EQ 8E06: OCDEV EQ 8E86: OCURDMA EQ 0005 OCURDSK EQ 000 ;FORM OFFSET TO THIS TRACKS PHASE OFF TAX LDY #2 ;ADVANCE 2 PHASES TO THE NEXT TRACK SKLP: LDA 0C080H,X ;TURN OFF THIS PHASE INX ;ADVANCE TO THE NEXT PHASE INX TXA AND #F7H ;MAKE THE LOWER 3 BITS MODULO 8 TAX LDA 0C081H,X ;TURMEMORY IMAGE ; SO THAT IT WILL SUPPORT DIFFERENT SIZED CP/M'S ; ; 5/26/82 (WLS) ; MADE INITIALIZE SMALLER ; ; 5/22/82 (WLS) ; FIXED BUG IN CONDRVR WHICH WAS SETTING THE FRSTDRVS ARRAY ; WHEN WE WERE CONNECTING A CHARACTER DEVICE ; ; 5/21/82 RESET TO BEFORE CALLING THE "OTHER" RESET ROUTINE ; SO ROUTINES WHICH INTERCEPT THE RESET ROUTINE CAN ; OUTPUT A MESSAGE TO THE CONSOLE ; ;VERSION 2.0 ; 4/24/83 (WLS) ; ADDED BEGSLT, LSTSLT ; ; 4/18/83 (WLS) ; ADDED R,WNZ80BYTES ; MOVED ZK: .BYTE 0 ;TEMPORARY TRACK .END  ;SECTOR TRANSLATION TABLE SECTRAN: .BYTE 0,2,4,6,8,10,12,14 .BYTE 1,3,5,7,9,11,13,15 SEC: .BYTE 0 ;TEMPORARY SECTOR TRLS) ; ADDED CODE TO RESET SO THAT IIE 80 COLUMN CARD WILL BE ; REINITIALIZED AFTER A RESET ; FIXED INITIALIZATION OF HIMEM ; ; 8/1/82 (WLS) ; FIXED BUG IN PAGE ZERO RELOCATION ; REMOVED FRSTDRVS FROM DRVREQUS ; ; 7/16/82 (WLS) ; CHANGED TH SECOND WHICH SHOULD BE PLENTY FAST ENOUGH FOR ; 1200 BAUD MODEM PROGRAMS? I DO NOT BLEIVE ; THAT FAST PEEK AND POKE WILL MAKE THE DIFFERENCE ; SO I'VE DECIDED NOT TO PUT THEM! ; ; ADDED BOOTSLOT,BOOTPRMS SO THEY MAY BE CHANGED ; ; CHANGEN ON NEXT PHASE LDA #056H JSR WAIT ;WAIT FOR ABOUT 20 MILLI-SECONDS DEY BNE SKLP ;CONTINUE UNTIL WE ARE AT THE NEXT TRK LDX SLOT16 ;SET X BACK TO SLOT TIME 16 LDA #0 STA SEC ;BACK TO SECTOR 0 INC TRK LDA TRK CMP #LASTTRK+1 BNEINAL STUFF ; 3/24/83 (WLS) ; MOVED THE DRVREQUS DOWN TO 800H AND ADDED CODE AND VECTORS ; FOR INITIALIZATION OF HI AND LOW MEMORY POINTERS PLUS ; ALLOCATING OF THE DISK BUFFER AT RUN TIME ; REMOVED CODE WHICH LOOKED FOR THE 256 "Z"'S IN THE ROM 80SLOT ; SIMPLIFIED THE INITIALIZATION OF THE DEFAULT CHARACTER ; AND BLOCK DEVICES TO MAKE CP6502 SMALLER ; ; 4/6/83 (WLS) ; ADDED SYSPG INITIALIZATION, CHANGED VERSION NUMBER TO 2 ; MOVED SOME VECTORS AROUND, ADDED SOME MORE RESET CODE ; ;ORG .TITLE "COMMAND PROCESSOR FOR 6502" .WIDTH 96 ;*********************************** ;FILE: CP6502.A65 ;PURP: COMMAND PROCESSOR FOR COMMUNICATION ; BETWEEN 6502 AND Z80 ;CHANGES: ; VERSION 2.2 ; 12/6/83 (WLS) ; ADDED RWTSPSLOT, RWTSPDISK ; ; VEE HEADER VARIABLES SO THAT THEY ARE ALL ; 2 BYTES LONG SO THAT PASCAL CAN USE THEM EASIER ; ; 7/2/82 (WLS) ; ADDED SEND1DATA AND REC1DATA ; ; 6/1/82 (WLS) ; CHANGED INITIALIZATION TO PICK UP Z80 ADDRESSES OF ; THE CCP AND BIOS FROM THE CP/M D INITIALIZE TO ONLY ALLOW FOR 2 BOOT DEVICES AS THE ; DEFAULT. THAT IS ALL APLDRVR WILL NOW HANDLE ; ; 6/20/83 (WLS) ; REMOVED BIT C010H FROM BEGINNING RESETROUTINE ; ; 6/15/83 (WLS) ; MOVED THE CODED WHICH CALLS THE INITCONSOLE ROUTINE IN ; RDLP ;BIF NOT DONE YET LDA SLOT16 ;PASS THE SLOT WE BOOTED OFF OF STA ABOOTSLOT JMP GOADR ;GOTO THE SYSTEM CODE ;SECTOR TRANSLATION TABLE SECTRAN: .BYTE 0,2,4,6,8,10,12,14 .BYTE 1,3,5,7,9,11,13,15 SEC: .BYTE 0 ;TEMPORARY SECTOR TRAREA ; SO THAT THE CARD WILL RUN IN SLOT 3 WITH A VIDEO CARD ; ADDED CODE IN RESETROUTINE TO CHECK FOR "M" OR "R" WHEN ; RESETING SO THAT THE MONITOR OR REBOOT CAN BE DONE ; ; 2/26/83 (WLS) ; ADDED CONDITIONAL ASSEMBLY FOR CPM3 ; ; 12/8/82 (WPEEK/POKE COMMANDS AS CONDITIONAL ASSEMBLY. ; ; FAST PEEKING IT IS ABOUT 50% FASTER THEN ; FUNCTIONS 6 AND 7. TO DO 10000H (65536) PEEKS ; TOOK ABOUT 10.3 SECONDS FOR WITH FAST AND 14.3 WITH ; SLOW. THAT WORKS OUT TO BE ABOUT 4000 PEEKS A ; RSION 2.1 ; 7/27/83 (WLS) ; CHANGED TO VERSION 2.1 ; ADDED CODE TO RESET R,M TO INITIALIZE APPLE MONITOR SO ; THE DISPLAY WILL BE CORRECT ; ; 7/7/83 (WLS) ; ADDED CODE TO INITIALIZE ALL THE DEVICES UPON RESET ; ; 6/29/83 (WLS) ; ADDED FAST (WLS) ; REMOVED SVA CONDITIONAL ASSMEBLY ; ADDED TO CONDRVR THE USE OF A LOAD ADDRESS FOR ; LOADING ABSOLUTE CODE ; ; 5/19/82 (WLS) ; ADDED POLLTBL ; ; 5/11/82 (WLS) ; CHANGED FINDZ80 TO ONLY SEARCH UNTIL A Z80 IS FOUND ; AND NOT TO SEAR RSETZ80 .EQU UDP1+1 ;RESET Z80 PORT INTZ80 .EQU RSETZ80+1 ;INTERRUPT Z80 PORT NMIZ80 .EQU INTZ80+1 ;NMI Z80 PORT Z80RESETWAIT .EQU 080H ;VALUE TO CALL WAIT WITH BEFORE ; CHECKING FOR Z80 CARD Z80ID: .BLOCK IDLEN ;ID NUMBER OF CARD ;OSEXADR .EQU 8000H ;OS EXECUTATION ADDRESS OSSIZE .EQU 1F00H ;OS SIZE OS6502ADR .EQU 09100H ;OS 6502 ADDRESS WBEXADR .EQU 0FFD7H ;WARM BOOT ENTRY WBSIZE .EQU 0 ;WARM BOOT SIZE WB6502ADR .EQU 0 ;WARM BOOT 6502 ADDRESS NOT USED .ENDC .IFING ROUTINE ; ; 3/7/82 (WLS) ; ADDED HOSTOS CONDITIONAL ASSEMBLY ; ; 2/20/82 (WLS) ; CHANGED CMD ARRAY TO BELOW BEGIN SO THAT IT WON'T MOVE ; AND WE CAN PATCH IN OTHER DRIVERS ; ADDED CODE IN CMDLOOP TO TEST FOR CONSOLE STATUS SO THAT ; IT ND Z80CALLSUB .EQU 4 ;4 = Z80 CALL SUBROUTINE LOAD Z80 REGISTERS Z80FCALLSUB .EQU 5 ;5 = Z80 FAST CALL ONLY LOAD 8080 REGISTERS .DSECT ;Z80 PORTS FOR THE Z80 BOARD ;THE PORT VALUE IS USED WITH INDEXED ADDRESS TO ACCESS THE PORT ; SUCH AS: ; OS .QUERY "ENTER HOST OPERATING SYSTEM (CPM,CPM3): " DFTLOMEM .QUERY "ENTER LOW MEMORY ADDRESS (0900H): " DFTHIMEM .QUERY "ENTER HIGH MEMORY ADDRESS (08E00H): " DFTDSKSZ .EQU 512 ;DEFAULT DISK BUFFER SIZE ;EXTERNALS .REF IAP16,RAP16,WAP16,OAP16 CH ALL THE SLOTS ; ; 5/9/82 (WLS) ; ADDED RESET ROUTINE TO WARM BOOT CPM ON RESETS ; ; 5/6/82 (WLS) ; REMOVED CPM HANDLERS NOW THERE ARE ONLY THE DEVICE HANDLERS ; ; 5/4/82 (WLS) ; ADDED DEVICE COMMANDS ; ; 5/1/82 (WLS) ; ADDED CONNECT DRIVR .EQU CCP ;OS LOAD ADDRESS OSEXADR .EQU BIOS ;OS EXECUTATION ADDRESS OSSIZE .EQU 1F00H ;OS SIZE OS6502ADR .EQU 09100H ;OS 6502 ADDRESS WBEXADR .EQU BIOS+3 ;WARM BOOT ENTRY WBSIZE .EQU 1600H ;WARM BOOT SIZE WB6502ADR .EQU 09100H ;WARM BOO HOSTOS=CPM ;CPM EQUATES MSIZE .EQU 224 ;SET TO NUMBER OF PAGES IF NOT USING ; INSTALL BIAS .EQU (MSIZE-80)*256 ;BIAS TO CALCULATE CCP CCP .EQU 3400H+BIAS ;DESTINATION ADDRESS OF CPM BIOS .EQU CCP+1600H ;STARTING EXECUTATION ADDRESS OSLDADHAPPENS AS QUICKLY AS POSSIBLE ; ; 2/19/82 (WLS) ; CHANGED WBOOT TO SEND CCP AND BDOS INSTEAD OF JUST CCP ; ; 2/18/82 (WLS) ; ADDED ERROR CHECKING IN SELDSK ; ; 1/14/82 (WLS) ; ADDED CONDITIONAL ASSEMBLY FOR SVA DRIVERS ; ; 1/7/82 (WLS) ; MLDX Z80SLOT ; LDA STATZ80,X INZ80 .EQU 0C080H ;INPUT PORT OUTZ80 .EQU INZ80+1 ;OUTPUT PORT OFFSET OSTATZ80 .EQU OUTZ80+1 ;STATUS OF OUTPUT PORT IN BIT 7 ISTATZ80 .EQU OSTATZ80+1 ;STATUS OF INPUT PORT IN BIT 7 UDP1 .EQU ISTATZ80+1 ;UNDEFINED PORT.REF APLINIT,APLIN,APLOUT,APLOTHER ;ENTRY POINTS .DEF LASTDATA .DEF RDZ80BYTE,WRZ80BYTE, R1Z80BYTE, W1Z80BYTE, Z80SLOT ;EQUATES ; .NOLIST .INCLUDE DRVREQUS.A65 ; .LIST .IF HOSTOS=CPM3 ;CPM EQUATES OSLDADR .EQU 8000H ;OS LOAD ADDRESS ER ; ; 4/28/82 (WLS) ; ADDED DEVICE TABLES ; ; 4/27/82 (WLS) ; ADDED CODE TO SET THE SOFTEV AND PWREDUP BYTES ; SO RESET WILL REBOOT THE SYSTEM ; ; 3/30/82 (WLS) ; CHANGED POLLING ROUTINE TO BE A SUBROUTINE ; ; 3/15/82 (WLS) ; ADDED POLLT 6502 ADDRESS .ENDC ;Z80 COMMANDS Z80IDCMD .EQU 0 ;0 = ID COMMAND (RETURNS "Z80" PLUS ID) IDLEN .EQU 8 ; 8 BYTES OF ID Z80SEND .EQU 1 ;1 = SEND DATA TO Z80 Z80REC .EQU 2 ;2 = RECIEVE DATA FROM Z80 Z80EXEC .EQU 3 ;3 = Z80 EXECUTE COMMA TRUE .EQU 1 FALSE .EQU 0 FASTPP .EQU FALSE ;TRUE FOR FAST PEEK AND POKE DEBUG .EQU FALSE ;TRUE FOR DEBUG STUFF CPSTK .EQU 0FFH ;COMMAND PROCESSOR STACK CPM .EQU 1 ;CPM AS HOST OPERATING SYSTEM CPM3 .EQU 2 ;CPM 3.0 HOST OPERATING SYSTEM HOSTADE THE APPLE DISKS DRIVES 0 AND 1 ; ; 12/28/81 (WLS) ; REMOVED ALL EXCESS CODE TO MAKE AS SMALL AS POSSIBLE ; ; 12/9/81 (WLS) ; MOVED THE CHARACTER IO ROUTINES TO CHARIO.A65 ; ; 11/10/81 (WLS) ; CREATED ;************************************ THESE MUST BE IN THIS ORDER DRVRPARMS: CURDSK: .BLOCK 1 ;CURRENT SELECTED DRIVE CURTRK: .BLOCK 2 ;CURRENT TRACK NUMBER CURSEC: .BLOCK 2 ;CURRENT SECTOR NUMBER CURDMA: .BLOCK 2 ;CURRENT ADDRESS FOR A READ OR WRITE CURSSZ: .BLOCK 2 ;CURRENT SECTORANDS ;BOOT DRIVES STUFF BOOTSLOT: .BYTE 060H ;SLOT * 16 OF THE BOOT SLOT ; SET BY THE BOOTCODE ON TRACK 0 BOOTPRMS: ;HOST AND DISK PARAMETERS ;HOST PARAMETERS FOR APPLE MINI FLOPPIES .WORD 256 ;BYTES PER SECTOR .WORD 32 ;CPM RECORDS PER T502 VERHI: .BYTE 2 ;HIGH VERSION NUMBER OF CP6502 Z80SLOT: .BYTE 0 ;SLOT NUMBER * 16 FOR THE Z80 BOARD OSLCLADR: .WORD OS6502ADR ;LOCAL ADDRESS OF OPERATING SYSTEM OSSLVADR: .WORD OSLDADR ;SLAVEADDRESS OF OPERATING SYSTEM OSLEN: .WORD OSSIZE IVER NUMBER OF DEVICES RELOCOFFSET: .BLOCK 1 ;RELOCATION OFFSET BYTE RELOCFLG: .BLOCK 1 ;RELOCATION FLAG 0 = NORELOCATION LASTDATA: ;END OF DATA .IF FASTPP ;PEEK POKE STUFF ; THIS MUST BE INITIALIZED WITH SETPP BEFORE USING PPNUM: .BLOCK 1 PEE* 16 BEGSLTA: .BYTE 0C7H ; SLOT 7 ADDRESS LSTSLT: .BYTE 10H-10H ;LAST SLOT * 16 - 10H ;BLOCK DEVICE TABLE SET UP BY INITIALIZE INITBLKDEVTBL: .WORD IAP16 ;APPLE 5 INCH FLOPPY DISK .WORD RAP16 .WORD WAP16 .WORD OAP16 ; ;CHARACTER DEVICEIZE SUBROUTINE JMP WARMBOOT ;WARM BOOT CODE INITCON: JMP (ICDEV+(8*3)) ;GOTO INIT CONSOLE ROUTINE FOR RESET ARESETROUTINE: .WORD RESETROUTINE ;ADDRESS OF THE RESET ROUTINE OTHRRESET: .WORD RESETCONTINUE ;ADDRESS OF OTHER RESET ROUTINE JUMPED TO SIZE CMDADR: .BLOCK 2 ;USED TO JUMP TO ROUTINE IN CMDLOOP CMDBYTE: .BLOCK 1 ;COMMAND BYTE FROM Z80 ;TEMPORARIES USED BY RESETROUTINE RRTMP1: .BLOCK 1 RRTMP2: .BLOCK 1 RRTMP3: .BLOCK 1 ;CONNECT DRIVER DATA DRVRADR: .BLOCK 2 ;DRIVER ADDRESS ;DEFAULT DISK BUFFER SIZE ILOMEM: .BYTE DFTLOMEM U/ 256 ;DEFAULT LOW MEMORY VALUE IHIMEM: .BYTE DFTHIMEM U/ 256 ;DEFAULT HIGH MEMORY VALUE ILOPG0: .BYTE BFP0BASE ;DEFAULT LOW PAGE 0 VALUE IHIPG0: .BYTE EFP0BASE ;DEFAULT HIGH PAGE 0 VALUE ISYSPG: .BYTE ;SIZE OF OPERATING SYSTEM OSSTART: .WORD OSEXADR ;ENTRY POINT OF OPERATING WBLCLADR: .WORD WB6502ADR ;WARM BOOT ADDRESS WBLEN: .WORD WBSIZE ;SIZE OF WARM BOOT CODE WBSTART: .WORD WBEXADR ;ENTRY POINT FOR WARM BOOT IDSKSZ: .WORD DFTDSKSZ KDEST: PEEKADR: .EQU PEEKDEST+1 PEEK0: .BLOCK 8 ;RESERVE AREA FOR FAST PEEK CODE PEEK1: .BLOCK 8 PEEK2: .BLOCK 8 POKEDEST: POKEADR: .EQU POKEDEST+4 POKE0: .BLOCK 8 ;RESERVE AREA FOR FAST POKE CODE POKE1: .BLOCK 8 POKE2: .BLOCK 8 SZPEEKPOKE: .EQ TABLE SET UP BY INITIALIZE INITCHRDEVTBL: .WORD APLINIT .WORD APLIN .WORD APLOUT .WORD APLOTHER ;COMMAND DISPATCH ARRAY FRSTCMD: .BYTE 1 ;FIRST COMMAND LASTCMD: .BYTE 12+1 ;LAST COMMAND PLUS 1 ACMDARY: .WORD CMDARY ;ADDRESS OF SYSTEM COMM ; AFTER AN LOOKING FOR A CHARACTER ; IF BIT 7 OF A = 1 THE A=CHAR REBOOTVECTOR: .WORD 0FA62H ;REBOOT VECTOR WHEN "R" AFTER RESET MONITORVECTOR: .WORD 0FF65H ;MONITOR VECTOR WHEN "M" AFTER RESET VERLOW: .BYTE 2 ;LOW VERSION NUMBER OF CP6 DRVRLEN: .BLOCK 2 ;DRIVER LENGTH DRVRP0LEN: .BLOCK 1 ;DRIVER LENGTH OF PAGE 0 DATA DRVRCURRBYTE: .BLOCK 1 ;DRIVER CURRENT RELOCATION BYTE DRVRDEVNUM: .BLOCK 1 ;DRIVER DEVICE NUMBER DRVRCURDEV: .BLOCK 1 ;DRIVER CURRENT DEVICE DRVRNUMDEVS: .BLOCK 1 ;DR DEVTBL U/ 256 ;DEFAULT SYSTEM PAGE (2 PAGES LONG) WCMDCNT: .BYTE 2 ;NUMBER OF CHECKS OF Z80 TO DO BEFORE POLLING WALCNT: .BYTE 4 ;WAIT A LITTLE COUNT 4 ABOUT 1/2 SECOND HSTIDB: .BYTE "Z" ;HOST PROCESSOR ID BYTE BEGSLT: .BYTE 70H ;BEGINNING SLOT Z80 JMP W1Z80BYTE ;WRITE A BYTE TO THE Z80 JMP JMPBHDLR ;GOTO THE BLOCK HANDLER (CMDBYTE SET) JMP JMPCHDLR ;GOTO THE CHARACTER HANDLER (CMDBYTE SET) JMP RNZ80BYTES ;READ N Z80 BYTES JMP WNZ80BYTES ;WRITE N Z80 BYTES INIT: JMP INITIALIZE ;INITIALU $-POKEDEST ;SIZE OF PEEK AND POKE AREAS .ENDC .PSECT BEGIN: JMP START ;JUMP OVER TABLES POLLRTN: ;ADDRESS OF POLLING ROUTINES JMP DOPOLLING ;POLLING ROUTINE CMDLOOP: JMP CMDLP ;GOTO COMMAND LOOP JMP R1Z80BYTE ;READ A BYTE FROM THE RACK .BYTE 2 ;CPM RECORDS PER HOST BLOCK .BYTE 8 ;CPM RECORDS PER ALLOCATION BLOCK .BYTE 1 ;SECTOR MASK .BYTE 1 ;SECTOR SHIFT COUNT ;DISK PARAMETER BLOCK FOR APPLE MINI FLOPPIES .WORD 32 ;SECTORS PER TRACK .BYTE 3 ;BLOCK SHIFT FACTOR URPOLLNUM + 2 IS THE INDEX OF THE NEXT ROUTINE TO DO ;EXIT: NONE ;USED: ALL ;************************************ DOPOLLING: LDA CURPOLLNUM ;GET CURRENT POLL NUMBER CLC ADC #2 ;INCREMENT TO NEXT DEVICE AND #SZPOLLTBL-1 ;TRUNCATE STA CURPOANYBODY WAITCMD: JSR POLLRTN ;DO POLLING LDY WCMDCNT ;DO SEVERAL CHECKS BEFORE POLLING LDX Z80SLOT ;INITIALIZE THE SLOT NUMBER $1: LDA ISTATZ80,X BMI GETCMD ;WAIT UNTIL BIT 7 = 1 DEY BNE $1 ;CONTINUE LOOKING A LITTLE MORE BEQ WAITCMD 0,0,0,0,0,0 ;CHARCTER DEVICE FLAGS ;NEW FOR 2.2, PREVIOUS SLOT AND DRIVE NUMBERS RWTSPSLOT: .BYTE 0 ;PREVIOUS SLOT RWTSPDISK: .BYTE 0 ;PREVIOUS DISK CMDARY .WORD CMDLOOP ;0 = ILLEGAL COMMAND .WORD SENDDATA ;1 = SEND DATA TO Z80 .WORD RE STA PG0W0 LDA BHDLRS+1,Y STA PG0W0+1 JMP DOIT ;CHARACTER DEVICE COMMAND ; BITS 0,1 (NOW IN 2,3) = COMMAND ; BITS 2..5 (NOW IN 3..6) = DEVICE NUMBER CDEVCMD: AND #7H TAY LDA CHDLRS,Y STA PG0W0 LDA CHDLRS+1,Y STA PG0W0+1 JMP DOACTER DEVICE BHDLRS: .WORD BINIT ;BLOCK DEVICE INITIALIZE .WORD BREAD ;BLOCK DEVICE READ .WORD BWRITE ;BLOCK DEVICE WRITE .WORD BOTHER ;BLOCK OTHER COMMAND CHDLRS: .WORD CINIT ;CHAR DEVICE INITIALIZE .WORD CREAD ;CHAR DEVICE READ .WOR .BYTE 7 ;BLOCK MASK .BYTE 0 ;EXTENT MASK .WORD 127 ;NUMBER OF BLOCKS ON DISK - 1 .WORD 47 ;NUMBER OF DIRECTORY ENTRIES - 1 .BYTE 192 ;ALLOC0 (MASKS) .BYTE 0 ;ALLOC1 .WORD 12 ;CHECK MASKS .WORD 3 ;OFFSET TO DIRECTORY TRACK ;ADDRESCMD BCS $1 ;BIF COMMAND IS TOO LARGE ASL A ;MULTIPLY BY 2 TAY LDA (CMDARYPTR),Y STA PG0W0 INY LDA (CMDARYPTR),Y STA PG0W0+1 JMP DOIT $1: JMP CMDLOOP ;HANDLE DEVICE COMMANDS ;A = CMDBYTE BIT 6 = 1 FOR CHARACTER DEVICE, 0 FOR BLOCK ;GET THE COMMAND GETCMD LDA INZ80,X ;READ THE BYTE STA CMDBYTE ;PROCESS THE COMMAND PROCCMD: BMI DEVCMD ;BIF BIT 7 = 1 (THIS IS A DEVICE HANDLER CMD) CMP FRSTCMD ;ELSE PERFORM REGULAR COMMAND BCC $1 ;BIF COMMAND IS TOO SMALL CMP LASTCDATA ;2 = RECIEVE DATA FROM Z80 .WORD EXECUTE ;3 = EXECUTE ROUTINE .WORD WBOOT ;4 = CPM WARM BOOT .WORD CONDRVR ;5 = CONNECT DRIVER .WORD SEND1DATA ;6 = SEND 1 DATA BYTE TO Z80 .WORD REC1DATA ;7 = RECIEVE 1 DATA BYTE FROM Z80 .IF FASTPP IT DOIT: JSR $1 ;DO THE ROUTINE JMP CMDLOOP ;CONTINUE WITH LOOP $1: JMP (PG0W0) ;GOTO THE ROUTINE @PG0W0 RETURN TO ; JMP CMDLOOP ABOVE ;********************************** ;ROUTINE: DOPOLLING ;PURP: CALL THE NEXT POLL ROUTINE ;ENTRY: CD CWRITE ;CHAR DEVICE WRITE .WORD COTHER ;CHAR OTHER COMMAND START: JSR INIT ;INITIALIZE, A = BOOTSLOT CMDLP: LDX #CPSTK ;CALLSUB ASSUMES THAT THE STACK TXS ; IS RESET WHEN CMDLOOP IS CALLED ;READ THE NEXT COMMAND BYTE AND POLL S OF DISK BUFFER ADRDSKBUF: .WORD 0 ;ADDRESS OF DISK BUFFER, FILLED IN BY INIT ;RESET ROUTINE INITIALIZE FLAGS, <> 0 MEANS RESET THIS DEVICE RESETIFLGS: .BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;BLOCK DEVICE FLAGS .BYTE 0,0,0,0FFH,0,0,0,0,0,0, DEVICE DEVCMD: ASL A ;* 2 BIT 6 TO BIT 7 BMI CDEVCMD ;BIF IT'S A CHAR DEVICE ;BLOCK DEVICE COMMAND ; BITS 0,1 (NOW IN 2,3) = COMMAND ; BITS 2..5 (NOW IN 3..6) = DEVICE NUMBER BDEVCMD: AND #7H ;GET TYPE OF COMMAND TAY LDA BHDLRS,Y ER VECTORS ;BIT 7 = 1 = DEVICE HANDLER REQUEST ;BITS 0,1 = COMMAND TYPE ; 0 = INIT ; 1 = READ ; 2 = WRITE ; 3 = OTHER ;BITS 2..6 = DEVICE NUMBER (BIT 6 = 0 = BLOCK 1 = CHARACTER) ; 0 .. 15 = BLOCK DEVICE ; 16.. 31 = CHAR .WORD PEEK0 ;8 = PEEK 0 .WORD PEEK1 ;9 = PEEK 1 .WORD PEEK2 ;10= PEEK 2 .WORD SETPEEK ;11= SETUP PEEKS .WORD POKE0 ;12= POKE 0 .WORD POKE1 ;13= POKE 1 .WORD POKE2 ;14= POKE 2 .WORD SETPOKE ;15= SETUP POKES .ENDC ;DEVICE HANDLLLNUM TAY LDA POLLTBL,Y ;GET LOW BYTE OF NEXT POLL ROUTINE STA PG0W0 LDA POLLTBL+1,Y ;GET HIGH BYTE STA PG0W0+1 JMP (PG0W0) ;EXECUTE THE ROUTINE VIA THE INDIRECT JMP BELOW ; RETURNS TO THE CALLER OF DOPOLLING ADRRETURN: .WORD ARETURLEN+1 STA PG0W1+1 ;PG0W1 = LENGTH JSR WRZ80WORD ;SEND THE LENGTH LDA OSLCLADR STA PG0W0 ;PG0W0 = STARTING ADDRESS OF MEMORY IMAGE LDA OSLCLADR+1 STA PG0W0+1 JSR SENDTOZ80 ;SEND DATA TO HOST ;EXECUTE THE AT THE COLD BOOT ENTRY LDA #Z8YTE OF STA POKEDEST,X ; POKE INY ;INCREMENT LENGTH OF PEEK/POKE CODE TYA AND #7 ; 8 BYTES IN PEEK AND POKE CODE TAY INX CPX #SZPEEKPOKE BNE $LP .ENDC ;FIND THE Z80 BOARD ;WAIT FOR SELF TEST TO COMPLETE JSR WAITALITTLE ;WAIT F STA LOPG0 ;SET LOW PAGE 0 ADDRESS LDA IHIPG0 STA HIPG0 ;SET HIGH PAGE 0 ADDRESS STY SYSP1 STY SYSP2 LDX ISYSPG STX SYSP1+1 ;POINT AT THE FIRST PAGE INX STX SYSP2+1 ;POINT AT THE SECOND PAGE LDA ACMDARY ;INITIALIZE THE COMMAUE UNTIL ALL SLOTS ARE LOOKED AT JMP NOZ80 ;ELSE BOMB OFF FNDZ80: ;WE HAVE THE PROCESSOR, GET IT'S ID NUMBER STX Z80SLOT ;SAVE THE SLOT NUMBER LDA #Z80IDCMD JSR WRZ80BYTE ;SEND THE ID COMMAND LDY #0 GETIDLP: JSR RDZ80BYTE STA Z80ID,-1,Y STA CHRDEVS-1,X LDA INITBLKDEVTBL-1,Y STA BLKDEVS-1,X DEX DEY BNE IDVLP1 CPX #0 BNE IDVLP ;ONLY ALLOW 2 BLOCK DEVICES ON BOOT SO ZERO ALL OTHERS LDX #SZBLKDEVS-(2*8) ;ALL BUT 2 DEVICES LDY #2*8 LDA #0 ;A = 0 ZBDVLP: STA BLKN ;ADDRESS OF A RETURN ;************************************* ;ROUTINE: INITIALIZE ;PURP: INITIALIZE THE SYSTEM ;ENTRY: NONE ;EXIT: WHAT EVER NEEDS DOING ;USED: ALL ;************************************ INITIALIZE: ;INITIALIZE MEMORY POICA8H ;WAIT FOR THE Z80 TO RESET ;LOOK IF THERE IS A BYTE FROM THE Z80? LDA ISTATZ80,X BPL NOTZ80 ;BIF BIT 7 <> 1 (CAN'T BE THE Z80) ;GET THE FIRST BYTE (IT SHOULD ALSO BE HSTIDB) JSR RDZ80BYTE CMP HSTIDB ;SHOULD BE HOST ID BYTE BEQ FNDOR A LITTLE WHILE ;START SEARCHING FROM SLOT 7 DOWN THROUGH SLOT 1 LDX BEGSLT ;START AT BEGINNING SLOT STX Z80SLOT LDA BEGSLTA STA PG0W0+1 ;Z80ADR = LDA #0 STA PG0W0 FZ80LP: LDA RSETZ80,X ;RESET THE Z80 LDA #Z80RESETWAIT JSR 0FND ARRAY POINTER STA CMDARYPTR LDA ACMDARY+1 STA CMDARYPTR+1 LDA #0FFH STA TRANSLOT ;INDICATE NO TRANSLATION BEING DONE ;INITIALIZE POLLSTUFF, APLON (OTHRON, TRANVEC OPTIONAL) ; Y = 0 LDX #SZPOLLTBL/2 STY CURPOLLNUM ;CURPOLLNUM := 0 Y INY CPY #IDLEN BNE GETIDLP ;LOAD THE OPERATING SYSTEM LDX Z80SLOT LDA #Z80REC JSR WRZ80BYTE ;TELL THE HOST TO RECIEVE OPERATING SYSTEM LDA OSSLVADR+1 LDY OSSLVADR JSR WRZ80WORD ;SEND THE LOAD ADDRESS LDY OSLEN STY PG0W1 LDA OSDEVS,Y INY DEX BNE ZBDVLP ;INITAIZIZE CHARACTER AND BLOCK STUFF JSR ICHRDEV JSR IBLKDEV .IF FASTPP ;INTIIALIZE FAST PEEK POKE CODE LDX #0 LDY #0 $LP: LDA PEEK,Y ;MOVE NEXT BYTE OF STA PEEKDEST,X ; PEEK LDA POKE,Y ;MOVE NEXT BNTERS ; Y = 0 LDY #0 STY LOMEM LDA ILOMEM STA LOMEM+1 TYA ;SET HIGH MEMORY AND DISK BUFFER ADDR SEC ; TO IHIMEM - IDSKSZ SBC IDSKSZ STA HIMEM STA ADRDSKBUF LDA IHIMEM SBC IDSKSZ+1 STA HIMEM+1 STA ADRDSKBUF+1 LDA ILOPG0 Z80 ; BIF FOUND ;ARRIVE HERE IF THIS SLOT IS NOT A Z80 NOTZ80: DEC PG0W0+1 ;INCREMENT HIGH BYTE OF POINTER TO Z80 CARD ; ROM AREA TXA SEC SBC #10H ;DECREMENT TO NEXT SLOT TAX CPX LSTSLT ;IS THIS THE LAST SLOT BNE FZ80LP ;CONTIN ;NOT NECESSARY STA TRANVEC+1 ; " STA POLLTBL,Y INY DEX BNE $1 ;INITIALIZE BLOCK DEVICE AND CHARACTER DEVICE TABLES ; START AT THE LAST DEVICE AND WORK UP LDX #SZBLKDEVS IDVLP: LDY #8 ;8 BYTES PER DEVICE IDVLP1: LDA INITCHRDEVTBL$1: LDA ADRRETURN ;SET ALL POLL TABLE ENTRIES STA APLON ;NECESSARY FOR RESET M STA OTHRON ;NOT NECESSARY STA TRANVEC ; " STA POLLTBL,Y ; TO THE ENDPOLLING ROUTINE INY LDA ADRRETURN+1 STA APLON+1 ;NECESSARY FOR RESET M STA OTHRON+10EXEC LDX Z80SLOT JSR WRZ80BYTE ;SEND THE EXECUTE COMMAND LDA OSSTART+1 LDY OSSTART JSR WRZ80WORD ;SEND THE ADDRESS ;SET RESET VECTOR TO OUR RESET ROUTINE LDA ARESETROUTINE STA SOFTEV LDA ARESETROUTINE+1 STA SOFTEV+1 EOR #0A5H STA: JSR RDZ80WORD ;GET THE STARTING ADDRESS STA PG0W0+1 STY PG0W0 JSR RDZ80WORD ;GET THE NUMBER OF BYTES STA PG0W1+1 STY PG0W1 JMP SENDTOZ80 ;*********************************** ;ROUTINE: RECDATA ;PURP: RECIEVE DATA FROM Z80 ;ENTRY: X = ER FROM THE STACK BPL WARMBOOT ;BIF NO CHARACTER (DO A WARM BOOT) AND #01011111B ;MAKE IT UPPER CASE CMP #"R" BEQ REBOOT ;BIF DO REBOOT CMP #"M" BNE WARMBOOT ;BIF NOT MONITOR JSR INITAPL JMP (MONITORVECTOR) ;GOTO THE MONITOR REBOOT: JSR80RESET AND EXECUTION AT WARMBOOT ;USED: ALL ;************************************ RESETROUTINE: ;WAIT A LITTLE WHILE AND CHECK FOR THE OPERATOR TO TYPE A KEY ; IF THE KEY IS "R" THEN JUMP TO C600H IF THE KEY IS "M" GOTO THE ; MONITOR ;INIT * ;ROUTINE: WAITALITTLE ;PURP: WAIT FOR ABOUT 1/2 SECOND ;ENTRY: NONE ;EXIT: NONE ;USED: ALL ;********************************* WAITALITTLE: LDY WALCNT ;GET COUNT FOR WAIT A LITTLE WHILE $1: LDA #0FFH JSR 0FCA8H ;CALL WAIT IN THE ROM DEY RTMP3 JSR THRUPG0W0 ;CALL THE INIT SUBROUTINE $1: LDA RRTMP2 ;NEXT N0 VALUE CLC ADC #10H ; ADD 10 STA RRTMP2 INC RRTMP3 ;NEXT CN VALUE, ADD 1 INC RRTMP1 ;NEXT DEVICE NUMBER, ADD 1 LDA RRTMP1 CMP #32 ;32 DEVICES MAX BNE $LP ;CONTIA PWREDUP ;SET POWER UP BYTE SO WE VECTOR THROUGH SOFTEV ARETURN: RTS ;RETURN ;!!!! THERE IS NO HOST CARD !!!! NOZ80: ;WAIT A LITTLE WHILE JSR WAITALITTLE LDA #0 STA SOFTEV+1 STA PWREDUP ;BESURE THE WE INDICATE NOT POWERED UP BY SHOULD BE HOST ID BYTE BNE REBOOT ;BIF NOT (DO REBOOT AS SOMEBODY IS LOST) ;EXECUTE AT WARM BOOT ENTRY POINT IN CP/M BIOS LDA #Z80EXEC LDX Z80SLOT JSR WRZ80BYTE ;SEND THE EXECUTE COMMAND LDA WBSTART+1 ;EXECUTE AT WARM BOOT ENTRY LDY WBST INITAPL INC PWREDUP ;CHNAGE POWER UP BYTE SO WE COLD BOOT JMP (REBOOTVECTOR) ;REBOOT WARMBOOT: LDX Z80SLOT LDA RSETZ80,X ;RESET THE Z80 LDA #Z80RESETWAIT JSR 0FCA8H ;WAIT A SHORT WHILE JSR RDZ80BYTE ;READ THE CHARACTER CMP HSTIDB ;ALL CHARACTER WITH THE INIT FLAG SET LDA #00H STA RRTMP1 ;RRTMP1 GETS INCREMENTED BY 1 STA RRTMP2 ;SLOT NUMBER * 16 LDA #0C0H-16 ;SLOT ADDRESS STA RRTMP3 ; INCREMENTED BY 1 $LP: LDY RRTMP1 LDA RESETIFLGS,Y BEQ $1 ;BRANCH IF NOT SUPPOSE BNE $1 RTS ;************************************* ;ROUTINE: SENDDATA ;PURP: SEND DATA TO Z80 FROM 6502 MEMORY ;ENTRY: X = Z80SLOT ; ADDRESS, NUMBER OF BYTES ;EXIT: DATA SENT TO Z80 ;USED: ALL ;************************************ SENDDATNUE IF NOT DONE JSR WAITALITTLE ;WAIT FOR A LITTLE WHILE LDA 0C000H ;CHECK KEYBOARD PHA ;SAVE CHARCTER IF ANY JMP (OTHRRESET) ;DO ANY OTHER RESETS RESETCONTINUE: BIT 0C010H ;STROBE THE KEYBOARD INCASE ANY KEY PLA ;RECOVER THE CHARACT ; MAKEING PWREDUP <> EOR(SOFETV+1,0A5H) JMP (0FFFCH) ;GO THROUGH 6502 RESET VECTOR ICHRDEV: JMP (ICDEV) IBLKDEV: JMP (IBDEV) ;************************************ ;ROUTINE: RESETROUTINE ;PURP: HANDLE PRESSING OF RESET ;ENTRY: NONE ;EXIT: ZART JSR WRZ80WORD ;SEND THE ADDRESS OF WARM BOOT JMP CMDLOOP ;GO WAIT FOR COMMANDS FROM Z80 INITAPL: JSR DOAPLON JMP 0FB2FH ;INITIALIZE THE APPLE MONITOR DOAPLON: JMP (APLON) THRUPG0W0: JMP (PG0W0) ;********************************0+1 LDY #0 ;GET LOW BYTE OF INIT ADDRESS LDA (PG0W0),Y TAX ;SAVE LOW BYTE IN X INY ORA (PG0W0),Y BEQ $1 ;BIF NO SUCH DEVICE LDA (PG0W0),Y ;GET HIGH BYTE OF ADDRESS STA PG0W0+1 ; AND STORE STX PG0W0 ;SET LOW BYTE LDY RRTMP2 LDX R TO INITIALIZE ;GET ADDRESS OF INIT ROUTINE FROM DEVICE TABLE TYA ;COMPUTE ADDRESS OF NEXT INIT ENTRY ASL A ; MULTIPLY CURRENT DEVICE BY 8 ASL A ASL A CLC ADC SYSP1 ;AND ADD TO SYSTEM PAGE 1 STA PG0W0 LDA SYSP1+1 ADC #0 STA PG0WZ80SLOT ; ADDRESS, NUMBER OF BYTES ;EXIT: DATA GOTTEN FROM Z80 ;USED: ALL ;************************************ RECDATA: JSR RDZ80WORD ;GET THE STARTING ADDRESS STA PG0W0+1 STY PG0W0 JSR RDZ80WORD ;GET THE NUMBER OF BYTES STA PG0W1+1 STY: $1: LDA ISTATZ80,X BPL $1 ;WAIT UNTIL BIT 7 = 1 LDA INZ80,X ;READ THE BYTE RTS ;************************************* ;ROUTINE: WRZ80WORD ;PURP: WRITE A WORD TO THE Z80 ;ENTRY: X = Z80 SLOT ; A = HIGH BYTE (THE SECOND BYTE SENT) ; Y = PG0W1 ;DECREMENT COUNTER BNE $1 XITSEND: RTS ;******************************* ;ROUTINE: RECFRMZ80 ;PURP: RECIEVE A BLOCK OF MEMORY FROM THE Z80 ;ENTRY: X = Z80SLOT ; PG0W0 = STARTING ADDRESS ; PG0W1 = NUMBER OF BYTES ;EXIT: NONE ;USED: ALIEVE 1 DATA FROM Z80 ; STORE USING ABSOLUTING ADDRESSING. ;ENTRY: X = Z80SLOT ; ADDRESS, NUMBER OF BYTES ;EXIT: DATA GOTTEN FROM Z80 ;USED: ALL ;************************************ REC1DATA: JSR RDZ80WORD ;GET THE STARTING ADDRESS STA R1D+2 PURP: READ A WORD FROM THE Z80 ;ENTRY: X = Z80SLOT ; Z80 SENDING 2 BYTES ;EXIT: A = HIGH BYTE (THE SECOND BYTE SENT) ; Y = LOW BYTE (THE FIRST BYTE SENT) ;USED: A,F,Y ;************************************* RDZ80WORD: JSR RDZ80BYTE TAY JMP RDQ SDPART ;BIF NO FULL PAGES TO DO ; INSTEAD OF A CALL DO IT INLINE FOR SPEED $1: LDA OSTATZ80,X BMI $1 ;WAIT UNTIL BIT 7 = 0 LDA (PG0W0),Y STA OUTZ80,X ;WRITE THE BYTE INY BNE $1 INC PG0W0+1 DEC PG0W1+1 BNE $1 ;SEND THE LAST PA PG0W1 JMP RECFRMZ80 ;************************************* ;ROUTINE: SEND1DATA ;PURP: SEND 1 DATA BYTE TO Z80 FROM 6502 MEMORY ; USING ABSOLUTE ADDRESSING. ;ENTRY: X = Z80SLOT ; ADDRESS, NUMBER OF BYTES ;EXIT: DATA SENT TO Z80 ;USED: ALL ;*T UNTIL BIT 7 = 1 LDA INZ80,X ;READ THE BYTE STA (PG0W0),Y INY BNE $1 INC PG0W0+1 DEC PG0W1+1 ;DECREMENT COUNTER BNE $1 ;GET THE LAST PARTIAL PAGE ;Y MUST BE 0 RCDPART: LDA PG0W1 ;GET NUMBER OF BYTES IN LAST PAGE BEQ XITREC L ;******************************* RNZ80BYTES: LDX Z80SLOT RECFRMZ80: ;GET ALL OF THE FULL PAGES FIRST LDY #0 LDA PG0W1+1 BEQ RCDPART ;BIF NO FULL PAGES TO DO ; INSTEAD OF A CALL DO IT INLINE FOR SPEED $1: LDA ISTATZ80,X BPL $1 ;WAI STY R1D+1 JSR RDZ80BYTE ;GET THE BYTE R1D: STA 1000H ;STORE THE DATA WITH DIRECT ADDRESSING RTS ;************************************** ;ROUTINE: EXECUTE ;PURP: EXECUTE A ROUTINE IF THE ROUTINE TERMINATES ; WITH A RTS THEN CONTROL IS RETURNED Z80BYTE ;************************************* ;ROUTINE: RDZ80BYTE ;PURP: READ A BYTE FROM THE Z80 ;ENTRY: X = Z80SLOT ; Z80 SENDING 1 BYTE ;EXIT: A = BYTE ;USED: A,F,Y ;************************************* R1Z80BYTE: LDX Z80SLOT RDZ80BYTERTIAL PAGE ;Y MUST BE 0 SDPART: LDA PG0W1 ;GET NUMBER OF BYTES IN LAST PAGE BEQ XITSEND ; INSTEAD OF A CALL DO IT INLINE FOR SPEED $1: LDA OSTATZ80,X BMI $1 ;WAIT UNTIL BIT 7 = 0 LDA (PG0W0),Y STA OUTZ80,X ;WRITE THE BYTE INY DEC *********************************** SEND1DATA: JSR RDZ80WORD ;GET THE STARTING ADDRESS STA S1D+2 STY S1D+1 S1D: LDA 1000H ;GET THE DATA WITH DIRECT ADDRESSING JMP WRZ80BYTE ;*********************************** ;ROUTINE: RECDATA ;PURP: REC ; INSTEAD OF A CALL DO IT INLINE FOR SPEED $1: LDA ISTATZ80,X BPL $1 ;WAIT UNTIL BIT 7 = 1 LDA INZ80,X ;READ THE BYTE STA (PG0W0),Y INY DEC PG0W1 BNE $1 XITREC: RTS ;************************************* ;ROUTINE: RDZ80WORD ; SENDTOZ80 ;PURP: SEND A BLOCK OF MEMORY TO THE Z80 ;ENTRY: X = Z80SLOT ; PG0W0 = STARTING ADDRESS ; PG0W1 = NUMBER OF BYTES ;EXIT: NONE ;USED: ALL ;******************************* WNZ80BYTES: LDX Z80SLOT SENDTOZ80: LDY #0 LDA PG0W1+1 BETO CMDLOOP ;ENTRY: X = Z80SLOT ; Z80 SENDING THE ADDRESS ;EXIT: JUMPS TO THE ADDRESS ;USED: ALL ;************************************* EXECUTE: JSR RDZ80WORD STA PG0W0+1 STY PG0W0 JMP (PG0W0) ;******************************* ;ROUTINE:LOW BYTE (THE FIRST BYTE SENT) ;EXIT: Z80 SENT 2 BYTES ;USED: A,F,Y ;************************************* WRZ80WORD: PHA TYA JSR WRZ80BYTE PLA JMP WRZ80BYTE ;************************************* ;ROUTINE: WRZ80BYTE ;PURP: WRITE A BYTQ OKCONDRVR ;BIF EQUAL LDA #1 ;ELSE RAN OUT OF PAGE ZERO MEMORY LDX Z80SLOT JMP WRZ80BYTE ;EXIT NOT ENOUGH PAGE 0 ROOM ;SEND OK MESSAGE THAT CODE FITS OKCONDRVR: LDA #0 LDX Z80SLOT JSR WRZ80BYTE ;READ THE DATA INTO DRVRADR + ODEVNUM CDELEN: .EQU 2 ;OFFSET FROM DRVRADR TO CODE LENGTH OP0LEN: .EQU 4 ;OFFSET FROM DRVRADR TO PAGE ZERO LENGTH ODEVNUM: .EQU 6 ;OFFSET FROM DRVRADR TO DEVICE NUMBER ONUMDEVS: .EQU 8 ;OFFSET FROM DRVRADR TO NUMBER OF DEVICES ODEVVEC: .EQU 10 ;OFFSET FROM DW ADDRESS OF BYTE ; BYTE 2 = HIGH ADDRESS OF BYTE ;EXIT: NONE ;USED: ALL ;************************************ SETPOKE: JSR RDSETPPDATA STA POKEADR+1,X ;SET HIGH BYTE TYA STA POKEADR,X ;AND LOW BYTE RTS SETPEEK: JSR RDSETPPDATA STA DA LOMEM CLC ADC DRVRLEN LDA LOMEM+1 ADC DRVRLEN+1 TAY INY ;BUMP TO NEXT PAGE BOUNDRY TO BE SURE CPY HIMEM+1 BCC CDELENOK LDA #1 ;ELSE RAN OUT OF CODE MEMORY LDX Z80SLOT JMP WRZ80BYTE ;INDICATE THAT CODE LENGTH IS OK CDELENOK: NUMBER OF DEVICES (WORD LOW BYTE ONLY) ; DEVICE VECTOR 0 (WORD) ; DEVICE VECTOR 1 (WORD) ; DEVICE VECTOR 2 (WORD) ; DEVICE VECTOR 3 (WORD) ; DRIVER CODE AND DATA (LENGTH NUMBER OF BYTES) ; CODE RELOCATION BIT MAP ((LENGTHE TO THE Z80 ;ENTRY: X = Z80SLOT ; A = BYTE TO SEND TO Z80 ;EXIT: Z80 SENT 1 BYTE ;USED: A,F,Y ;************************************* W1Z80BYTE: LDX Z80SLOT WRZ80BYTE: TAY $1: LDA OSTATZ80,X BMI $1 ;WAIT UNTIL BIT 7 = 0 TYA STA OUTZ80,CATING JSR RDZ80WORD ;GET LOAD ADDRESS STA DRVRADR+1 STY DRVRADR ORA DRVRADR BEQ $0 ;BIF DRVRADR = 0 (DO RELOCATION) LDA DRVRADR ;SET LOMEM TO DRVRADR STA LOMEM LDA DRVRADR+1 STA LOMEM+1 JMP $1 ;DRVRADR := LOMEM ; WE ARE GOING RVRADR TO VECTORS OIVEC: .EQU 10 ;OFFSET FROM DRVRADR TO INITIALIZE VECTOR OPOLLVEC: .EQU 18 ;OFFSET FROM DRVRADR TO POLLVEC CONDRVR: ;GET LOAD ADDRESSES ; IF IT IS ZERO THEN DYNAMICLY RELOCATE LDA #0 STA RELOCFLG ;ASSUME THAT WE ARE NOT RELOPEEKADR+1,X ;SET HIGH BYTE TYA STA PEEKADR,X ;AND LOW BYTE RTS RDSETPPDATA: JSR RDZ80BYTE ASL A ;MULTIPLY TYPE * 8, FOR INDEX INTO PPCODE ASL A ASL A STA PPNUM ;SAVE TYPE JSR RDZ80WORD ;GET ADDRESS, A,Y LDX PPNUM ;X = INDEX RT LDA #0 LDX Z80SLOT JSR WRZ80BYTE ;GET THE PAGE 0 LENGTH LDX Z80SLOT JSR RDZ80WORD STY DRVRP0LEN ;ONLY THE LOWER BYTE IS VALID ;CHECK THAT THE PAGE 0 FITS LDA LOPG0 CLC ADC DRVRP0LEN CMP HIPG0 BCC OKCONDRVR ;BIF LESS THAN BE + 7) DIV 8 NUMBER OF BYTES) ; PAGE 0 RELOCATION BIT MAP ((LENGTH + 7) DIV 8 NUMBER OF BYTES) ;EXIT: DEVICE PLACED IN MEMORY AND CONNECTED ;USED: ALL ;************************************* OLOADADR: .EQU 0 ;OFFSET FROM DRVRADR TO LOAD ADDRESS OX ;WRITE THE BYTE RTS .IF FASTPP ;************************************** ;ROUTINE: SETPEEK,SETPOKE ;PURP: ALLOW FOR A HIGH SPEED PEEK AND POKE OF THE APPLE MEMORY ;ENTRY: 3 PARAMETERS SENT FROM HOST ; BYTE 0 = 0..3 FOR PEEK NUMBER ; BYTE 1 = LOTO RELOCATE TO LOMEM $0: LDA #0FFH STA RELOCFLG ;INDICATE WE ARE RELOCATING LDA LOMEM STA DRVRADR LDA LOMEM+1 STA DRVRADR+1 ;GET THE CODE LENGTH $1: LDX Z80SLOT JSR RDZ80WORD STA DRVRLEN+1 STY DRVRLEN ;CHECK THAT THE CODE FITS L= Z80SLOT ; Z80 TO SEND DRIVER DATA IN FOLLOWING FORMAT ; LOAD ADDRESS OF DRIVER CODE (WORD 0=RELOCATE IT) ; LENGTH OF DRIVER CODE (WORD) ; LENGTH OF PAGE ZERO NEEDED (WORD LOW BYTE ONLY) ; DEVICE NUMBER 0..31 (WORD LOW BYTE ONLY) ;S ;8 BYTES OF POKE CODE POKE: JSR RDZ80BYTE STA 0FFFFH RTS NOP ;8 BYTES OF PEEK CODE PEEK: LDA 0FFFFH JMP WRZ80BYTE NOP NOP .ENDC ;*************************************** ;ROUTINE: CONDRVR ;PURP: CONECT A DRIVER ;ENTRY: X LDA DRVRADR ;PG0W0 := DRVRADR STA PG0W0 LDA DRVRADR+1 STA PG0W0+1 LDA DRVRLEN ;PG0W1 := LENGTH STA PG0W1 LDA DRVRLEN+1 STA PG0W1+1 LDX Z80SLOT JSR RECFRMZ80 ;READ THE DATA INTO DRVRADR ;RELOCATE IF NECESSARY LDA RELOCFLG BEQ RL),Y NORELOCATION: ;INCREMENT TO NEXT BYTE OF DRIVER INC PG0W0 BNE RELOCLOOP INC PG0W0+1 ;INCREMENT HI BYTE OF DRIVER JMP RELOCLOOP ;CONTINUE XITRELOC: RTS ;************************************** ;ROUTINE: WBOOT ;PURP: WARM BOOT CPM + DRVRP0LEN LDA LOPG0 CLC ADC DRVRP0LEN STA LOPG0 ;INITIALIZE THE DEVICE INITDEV: LDY #OIVEC LDA (PG0W0),Y ;GET LOW BYTE OF INIT VECTOR STA PG0W1 INY LDA (PG0W0),Y ;AND HIGH BYTE STA PG0W1+1 JMP (PG0W1) ;INITIALIZE ;******F DEVICES THIS IS TO BE STA DRVRNUMDEVS LDA DRVRDEVNUM STA DRVRCURDEV ;INIT CURRENT DEVICE $CONLP: ;SET THE DEVICE TABLE TO THE VECTORS $NOTBLK: LDA DRVRCURDEV ASL A ;* 2 ASL A ;* 4 ASL A ;* 8 FOR INDEX INTO DEVICE TABLE TAX ;X =;EXIT WHEN BOTH = 0 ;DECREMENT DRIVER LENGTH COUNTER LDA PG0W1 BNE $1 DEC PG0W1+1 $1: DEC PG0W1 ;GET NEXT BYTE OF BIT MAP IF NECESSARY DEX BNE RLLP1 LDX Z80SLOT ;READ NEXT BYTE OF BIT MAP JSR RDZ80BYTE ;GET CURRENT BITMAP BYTE STAS BNE POLLLP ;CONTINUE UNTIL ALL ARE UPDATED ;UPDATE LOMEM TO NEXT PAGE BOUNDRY FOLLOWING THE CODE ;LOMEM := (LOMEM + DRVRLEN + 0FFH) AND 0FF00H LDA LOMEM ;LOMEM := LOMEM + DRVRLEN CLC ADC DRVRLEN STA LOMEM LDA LOMEM+1 ADC DRVRLEN+1 CP0 ;BIF NO CODE RELOCATION LDA DRVRADR+1 ;RELOCATE USING HIGH BYTE OF DRVRADR JSR RELOCATE ;RELOCATE PAGE ZERO RLCP0: LDA DRVRP0LEN BEQ CONNECT ;BIF NO PAGE ZERO TO RELOCATE LDA LOPG0 ;RELOCATE PAGE ZERO USING LOPG0 AS THE BASE JSR RELOCTHE PROGRAM CORRESPONDING TO A ; 1 BIT IN THE BITMAP GETS THE RELOCATION OFFSET ; ADDED TO IT. ;USED: ALL ;*************************************** RELOCATE: STA RELOCOFFSET LDA DRVRADR STA PG0W0 LDA DRVRADR+1 STA PG0W0+1 ;PG0W0 := ROUTIN********************************* ;ROUTINE: RELOCATE ;PURP: RELOCATE THE SUBROUTINE ;ENTRY: A = RELOCATION OFFSET ; DRVRADR = BEGINNING OF PROGRAM TO RELOCATE ; DRVRLEN = LENGTH OF PROGRAM TO RELOCATE ; Z80 IS SENDING THE BITMAP ;EXIT: EACH BYTE IN INDEX INTO DEVICE TABLE LDY #ODEVVEC ;Y = INDEX INTO DEVICE VECTORS $LP1: LDA (PG0W0),Y ;GET VECTOR STA DEVTBL,X ;STORE IN TABLE INX INY CPY #ODEVVEC+8 BNE $LP1 ;CONTINUE UNTIL THE VECTORS ARE UPDATED INC DRVRCURDEV ;INCREMENT CURRENT DE DRVRCURRBYTE LDX #8 ;8 RELOCATION BITS PER BYTE RLLP1: ROR DRVRCURRBYTE ;GET NEXT BIT BCC NORELOCATION ;BIF BIT = 0 ;ELSE RELOCATE THIS BYTE LDA RELOCOFFSET ;THIS BYTE := THIS BYTE + RELOCOFFSET CLC LDY #0 ADC (PG0W0),Y STA (PG0W0 STA LOMEM+1 LDA #0FFH ;LOMEM := LOMEM + 0FFH CLC ADC LOMEM LDA #0 STA LOMEM ; BE SURE LOW BYTE OF LOMEM IS 0 BCC $1 ;BIF NO CARRY FROM ADDING OF 0FFH INC LOMEM+1 ;ELSE INCREMENT HIGH BYTE OF LOMEM $1: ;UPDATE LOPG0 ; LOPG0 := LOPG0 ATE ;CONNECT THE DRIVER BY COPYING THE 4 VECTORS INTO THE ;DEVICE TABLE CONNECT: LDA DRVRADR STA PG0W0 LDA DRVRADR+1 STA PG0W0+1 LDY #ODEVNUM LDA (PG0W0),Y STA DRVRDEVNUM ;GET DEVICE NUMBER LDY #ONUMDEVS LDA (PG0W0),Y ;GET NUMBER OE ADDRESS LDA DRVRLEN STA PG0W1 LDA DRVRLEN+1 STA PG0W1+1 ;PG0W1 := DRVRLEN (LOOP COUNTER) LDX #1 ;FORCE FIRST BYTE TO BE READ RELOCLOOP: ;EXIT WHEN DRIVER LENGTH = 0 LDA PG0W1 ORA PG0W1+1 ;OR HIGH BYTE WITH LOW BYTE BEQ XITRELOC S COUNTER LDA DRVRDEVNUM ;GET DEVICE NUMBER ASL A ;MULTIPLY BY 2 TAX ; AND USE AS INDEX INTO POLLTBL POLLLP: LDY #OPOLLVEC LDA (PG0W0),Y STA POLLTBL,X ;STORE LOW BYTE INY LDA (PG0W0),Y STA POLLTBL+1,X ;STORE HIGH BYTE DEC DRVRNUMDEVVICE DEC DRVRNUMDEVS ;DECREMENT NUMBER OF DEVICES BNE $CONLP ;CONTINUE UNTIL ALL DEVICES TABLE ENTRYS ARE ; UPDATED ;ADD THE POLLROUTINE VECTOR LDY #ONUMDEVS LDA (PG0W0),Y ;GET NUMBER OF DEVICES THIS IS TO BE STA DRVRNUMDEVS ; AND USE A ;ENTRY: X = Z80 SLOT ;EXIT: CCP AND BDOS SENT TO THE Z80 ;USED: ALL ;************************************** WBOOT: LDA WBLCLADR STA PG0W0 LDA WBLCLADR+1 STA PG0W0+1 LDA WBLEN STA PG0W1 LDA WBLEN+1 STA PG0W1+1 JMP SENDTOZ80 ;**NE: CREAD ;PURP: GOTO THE APPORIATE CHARACTER READ ROUTINE ;ENTRY: CMDBYTE = INDEX INTO THE DEVICE TABLE OF THE ROUTINE TO EXECUTE ; NO PARAMETERS FROM Z80 ;EXIT: A CHARACTER RETURNED TO Z80 ;USED: ALL ;************************************** CREAD************************** ;ROUTINE: BOTHER ;PURP: HANDLE OTHER BLOCK COMMANDS ;ENTRY: CMDBYTE = INDEX INTO THE DEVICE TABLE OF THE ROUTINE TO EXECUTE ; Z80 SENDING THE COMMAND BYTE ;EXIT: JUMP TO THE INIT ROUTINE ;USED: ALL ;*********************** INTO THE DEVICE TABLE OF THE ROUTINE TO EXECUTE ; Z80 SENDING ; SECTOR SIZE, DRIVE, TRACK, AND SECTOR ;EXIT: A ERROR CODE RETURNED TO Z80 ;USED: ALL ;************************************** BREAD: JSR GETSDTS ;GET SECTOR SIZE, DRIVE, TRACK ANDA RTS ADRDRVRPARMS: .WORD DRVRPARMS ;ADDRESS OF DRIVER PARAMETERS ;************************************* ;ROUTINE: CINIT ;PURP: GOTO THE APPORIATE CHARACTER INIT ROUTINE ;ENTRY: CMDBYTE = INDEX INTO THE DEVICE TABLE OF THE ROUTINE TO EXECUTEGETSDTS ;GET SECTOR SIZE, DRIVE, TRACK AND SECTOR ;GET THE DATA FROM THE Z80 LDA ADRDSKBUF STA PG0W0 ;SET PAGE ZERO ADDRESS LDA ADRDSKBUF+1 STA PG0W0+1 LDA CURSSZ STA PG0W1 LDA CURSSZ+1 STA PG0W1+1 LDX Z80SLOT ;GET SLOT JSR RECFR*********************************** ;ROUTINE: BINIT ;PURP: GOTO THE APPORIATE BLOCK INIT ROUTINE ;ENTRY: CMDBYTE = INDEX INTO THE DEVICE TABLE OF THE ROUTINE TO EXECUTE ; NO PARAMETERS FROM Z80 ;EXIT: A ERROR CODE RETURNED TO Z80 ;USED: ALL ;*******Z80 ;ENTRY: Z80 TO SEND SECTOR SIZE, DRIVE, TRACK AND SECTOR ;EXIT: A = 1 TO INDICATE AN ERROR ;USED A,Y ;************************************* GETSDTS: JSR RDZ80WORD ;GET SECTOR SIZE STA CURSSZ+1 STY CURSSZ JSR RDZ80BYTE ;GET DRIVE NUMBER **************** BOTHER: JSR RDZ80BYTE ;READ THE COMMAND BYTE JSR JMPBHDLR ;DO IT LDX Z80SLOT JMP WRZ80BYTE ;SEND ERROR CODE ;************************************** ;ROUTINE: GETSDTS ;PURP: GET THE SECTOR SIZE, DRIVE, TRACK AND SECTOR FROM SECTOR LDA ADRDRVRPARMS+1 ;A,Y = ADDRESS OF PARAMETERS LDY ADRDRVRPARMS JSR JMPBHDLR ;READ THE DATA FROM THE DEVICE HANDLER ;TRANSFER BUFFER TO Z80 PHA ;SAVE STATUS ON STACK LDA ADRDSKBUF STA PG0W0 ;SET PAGE ZERO ADDRESS LDA ADRDSKBU ; NO PARAMETERS FROM Z80 ;EXIT: A ERROR CODE RETURNED TO Z80 ;USED: ALL ;************************************** CINIT: JSR JMPCHDLR ;GOTO HANDLER LDX Z80SLOT JMP WRZ80BYTE ;SEND ERROR CODE ;************************************* ;ROUTIMZ80 ;GET THE DATA ;WRITE THE DATA LDA ADRDRVRPARMS+1 ;A,Y = ADDRESS OF PARAMETERS LDY ADRDRVRPARMS JSR JMPBHDLR ;GOTO THE DEVICE HANDLER AND WRITE IT LDX Z80SLOT ;RESTORE THE SLOT NUMBER TO X JMP WRZ80BYTE ;SEND ERROR FLAG ;******************************************* BINIT: JSR JMPBHDLR ;GOTO INIT ROUTINE LDX Z80SLOT JMP WRZ80BYTE ;SEND THE ERROR CODE ;************************************* ;ROUTINE: BREAD ;PURP: GOTO THE APPORIATE BLOCK READ ROUTINE ;ENTRY: CMDBYTE = INDEX STA CURDSK JSR RDZ80WORD ;GET TRACK NUMBER STA CURTRK+1 STY CURTRK JSR RDZ80WORD ;GET SECTOR LDA #0 STA CURSEC+1 ;FOR NOW UPPER BYTE IS 0 STY CURSEC LDA ADRDSKBUF+1 ;SET CURDMA TO TEMPORARY BUFFER STA CURDMA+1 LDA ADRDSKBUF STA CURDMOCK WRITE ROUTINE ;ENTRY: CMDBYTE = INDEX INTO THE DEVICE TABLE OF THE ROUTINE TO EXECUTE ; Z80 SENDING ; SECTOR SIZE, DRIVE, TRACK, AND SECTOR ;EXIT: A ERROR CODE RETURNED TO Z80 ;USED: ALL ;************************************** BWRITE: JSR F+1 STA PG0W0+1 LDA CURSSZ STA PG0W1 LDA CURSSZ+1 STA PG0W1+1 LDX Z80SLOT JSR SENDTOZ80 ;SEND THE DATA TO THE Z80 PLA JMP WRZ80BYTE ;SEND ERROR FLAG ;************************************* ;ROUTINE: BWRITE ;PURP: GOTO THE APPORIATE BL: JSR JMPCHDLR ;GOTO HANDLER LDX Z80SLOT JMP WRZ80BYTE ;SEND THE CHARACTER ;************************************* ;ROUTINE: CWRITE ;PURP: GOTO THE APPORIATE CHARACTER WRITE ROUTINE ;ENTRY: CMDBYTE = INDEX INTO THE DEVICE TABLE OF THE ROUTINE TOPMBOOT: 0000: 01 .BYTE 1 ;THE FIRST BYTE OF THE FIRST SECTOR IS THE 0001: ; NUMBER OF SECTORS TO READ 0001: EA NOP ;THIS IS WHERE CONTROL IS T0H ;FORM Cn TAX ;X = Cn LDA CMDBYTE ASL A TAY LDA DEVTBL,Y ;PG0W0 = DEVICE ROUTINE ADDRESS STA PG0W0 LDA DEVTBL+1,Y STA PG0W0+1 ORA PG0W0 BEQ BADHDLR1 ;BIF NO HANDLER TYA ASL A AND #0F0H TAY ;Y = n0 PLA ;RESTORE A JMPURP: CHARACTER OTHER COMMANDS ;ENTRY: CMDBYTE = INDEX INTO THE DEVICE TABLE OF THE ROUTINE TO EXECUTE ; Z80 SENDING THE COMMAND BYTE ;EXIT: JUMP TO THE INIT ROUTINE ;USED: ALL ;*************************************** COTHER: JSR RDZ80BYTE ;READ TECTOR .EQU 03DH ;RDSECTOR SECTOR 0000: 0026 = BUFADR .EQU 026H ;RDSECTOR BUFFER ADDRESS 0000: 002B = SLOT16 .EQU 02BH ;SLOT NUMBER * 16 OF CARD 0000: 000F = LASTSEC ;RESTORE A LDA #0FFH ;RETURN AN ERROR IF NO SUCH DEVICE RTS ;************************************* ;ROUTINE: JMPCHDLR ;PURP: GOTO THE APPORIATE CHARACTER HANDLER ;ENTRY: CMDBYTE = INDEX INTO THE DEVICE TABLE OF THE ROUTINE TO EXECUTE ; A = PARA EXECUTE ; Z80 SENDING THE CHARACTER ;EXIT: NO RESULT TO Z80 ;USED: ALL ;************************************** CWRITE: BIT TRANSLOT BMI $1 ;NO TRANSLATION AT ALL LDA CMDBYTE ;CHECK IF THIS IS THE SLOT LSR A LSR A AND #0FH CMP TRANSL (PG0W0) ;GOTO THE ROUTINE .END +1,Y STA PG0W0+1 ORA PG0W0 BEQ BADHDLR1 ;BIF NO HANDLER TYA ASL A AND #0F0H TAY ;Y = n0 PLA ;RESTORE A JMPHE COMMAND BYTE JSR JMPCHDLR ;DO IT LDX Z80SLOT JMP WRZ80BYTE ;SEND ERROR CODE ;************************************* ;ROUTINE: JMPBHDLR ;PURP: GOTO THE APPORIATE HANDLER ;ENTRY: CMDBYTE = INDEX INTO THE DEVICE TABLE OF THE ROUTINE TO EXECUTE .EQU 15 ;LAST SECTOR OF TRACK 0000: 0002 = LASTTRK .EQU 2 ;LAST TRACK TO READ 0000: FCA8 = WAIT .EQU 0FCA8H ;WAIT ROUTINE IN APPLE MONITOR ROM 0000: 0000: CMETER ;EXIT: A = PARAMETER ; X = Cn ; Y = n0 ; WHERE n = DEVICE NUMBER = SLOT NUMBER ;USED: F,X,Y ;************************************** JMPCHDLR: PHA ;SAVE A LDA CMDBYTE LSR A ;MOVE DEVICE NUMBER TO BITS 0..3 LSR A AND #0FH ORA #COT ;IS THIS THE RIGHT SLOT ? BNE $1 JSR RDZ80BYTE ;GET THE CHARACTER JMP (TRANVEC) ;GOTO THE TRANSLATION ROUTINE $1: JSR RDZ80BYTE ;GET THE CHARACTER TO WRITE JMP JMPCHDLR ;DO IT ;************************************** ;ROUTINE: COTHER ;P ABOOTSLOT .EQU GOADR+94 ;ADDRESS OF THE BOOT SLOT 0000: C65C = RDSEC .EQU 0C65CH ;ADDRESS OF THE READ SECTOR ROUTINE 0000: 0041 = TRACK .EQU 041H ;RDSECTOR TRACK 0000: 003D = S0 LDA DEVTBL+1,Y STA PG0W0+1 ORA PG0W0 BEQ BADHDLR ;BRANCH IF NO SUCH DEVICE PLA TAY ;RESTORE Y PLA ;RESTORE A JMP (PG0W0) ;GOTO THE ROUTINE WHICH WILL RETURN TO THE ; CALLER BADHDLR: PLA TAY ;RESTORE Y BADHDLR1: PLA ;EXIT: THE HANDLER JUMP TO ;USED: F ;************************************** JMPBHDLR: PHA ;SAVE A TYA PHA ;SAVE Y LDA CMDBYTE ASL A ;CMDBYTE * 2 = INDEX INTO DEVICE HANDLER TAY LDA DEVTBL,Y ;GET ROUTINE ADDRESS TO PG0W0 STA PG0WRANSFER TO BY 0002: ; RDSEC. THIS WILL BE PATCHED TO A RTS 0002: ;SET SLOT AND PATCH THE READ SECTOR CALL 0002: A62B LDX SLOT16 0004: 8A TXA 0005: 4A STA ABOOTSLOT 0075: 4C00B0 JMP GOADR ;GOTO THE SYSTEM CODE 0078: 0078: 0078: ;SECTOR TRANSLATION TABLE 0078: SECTRAN: 0078: 0002040608 .BYTE 0,2,4,6,8,1: 0A ASL A ;MULTIPLY BY 4 0045: 0A ASL A 0046: 052B ORA SLOT16 ;FORM OFFSET TO THIS TRACKS PHASE OFF 0048: AA TAX 0049: A002 10: 8D0100 STA CPMBOOT+1 ; CHANGE THE NOP TO RTS 0013: 0013: ;READ IN 3 TRACKS STARTING AT TRACK 0 SECTOR 1 TO LOADADR 0013: A900 LDA #LOADADR AND 0FFH ;LOW BYTE 0015: 8526 TRK 005F: A62B LDX SLOT16 ;SET X BACK TO SLOT TIME 16 0061: A900 LDA #0 0063: 8D8800 STA SEC ;BACK TO SECTOR 0 0066: EE8900 INC TRK 0069: AD8900 PATCH: ;PATCH READ SECTOR ADDRESS 0032: 205CC6 JSR RDSEC ;READ THE SECTOR 0035: EE8800 INC SEC 0038: AD8800 LDA SEC 003B: C910 CMP LSR A 0006: 4A LSR A 0007: 4A LSR A 0008: 4A LSR A 0009: 09C0 ORA #0C0H ;FORM CN FOR READ SECTOR 000B: 8D3400 STA PATCH+2 ;P 004F: E8 INX 0050: 8A TXA 0051: 29F7 AND #F7H ;MAKE THE LOWER 3 BITS MODULO 8 0053: AA TAX 0054: BD81C0 LDA 0C081H,X ;TURN ON NEXT PHASLDY #2 ;ADVANCE 2 PHASES TO THE NEXT TRACK 004B: SKLP: 004B: BD80C0 LDA 0C080H,X ;TURN OFF THIS PHASE 004E: E8 INX ;ADVANCE TO THE NEXT PHASE STA BUFADR 0017: A991 LDA #LOADADR U/ 256 ;HIGH BYTE 0019: 8527 STA BUFADR+1 001B: A901 LDA #1 ;SECTOR 1 001D: 8D8800 STA SEC 0020: A900 LDA TRK 006C: C903 CMP #LASTTRK+1 006E: D0B5 BNE RDLP ;BIF NOT DONE YET 0070: A52B LDA SLOT16 ;PASS THE SLOT WE BOOTED OFF OF 0072: 8D5EB0 #LASTSEC+1 003D: D0E6 BNE RDLP ;CONTINUE UNTIL DONE WITH TRACK 003F: 003F: ;INCREMENT TO NEXT TRACK 003F: AD8900 LDA TRK 0042: 2903 AND #3 0044ATCH THE READ SECTOR CALL 000E: 000E: ;CHANGE THE NOP ABOVE TO AN RTS SO THAT THE FRIMWARE RDSEC ROUTINE 000E: ; BECOMES A SUBROUTINE 000E: A960 LDA #060H ;OPCODE FOR RTS 00E 0057: A956 LDA #056H 0059: 20A8FC JSR WAIT ;WAIT FOR ABOUT 20 MILLI-SECONDS 005C: 88 DEY 005D: D0EC BNE SKLP ;CONTINUE UNTIL WE ARE AT THE NEXT ;GET SECTOR 0028: B97800 LDA SECTRAN,Y ; TRANSLATE TO PHYSICAL 002B: 853D STA SECTOR 002D: AD8900 LDA TRK ;GET TRACK 0030: 8541 STA TRACK 0032: LDA #0 ;TRACK 0 0022: 8D8900 STA TRK 0025: Page 2 CPMBOOT 0025: RDLP: 0025: AC8800 LDY SEC 0,12,14 007D: 0A0C0E 0080: 0103050709 .BYTE 1,3,5,7,9,11,13,15 0085: 0B0D0F 0088: 00 SEC: .BYTE 0 ;TEMPORARY SECTOR 0089: 00 TRK: .BYTE 0 ;TEMPORARY TRACK 008A: 008A: CURSORH 000A: 9128 STA (LINEBASE),Y 000C: Page 2 SMALL CHARIO KS Z80 COMPUTER 000C: ;CLEAR THE SCREEN 000C: 4C58FC JMP 0FC58H ;CALL THE H0/82 (WLS) 0000: ; CREATED 0000: ;****************************** 0000: 0000: 0001 = TRUE: .EQU 1 ;VALUE FOR TRUE 0000: 0000 = FALSE: .EQU 0 ;VALUE FOR FALSE ;PURP: INITIALIZE THE CARDS 0001: ;ENTRY: Y = n0 0001: ; X = Cn 0001: ;EXIT: THE CARD IS INITIALIZED 0001: ;USED: ALL 0001: ;************************************ 0001: 0001: .END ABOOTSLO EQ B05E: BUFADR EQ 0026: CPMBOOT PL 0000: GOADR EQ B000: LASTSEC EQ 000F LASTTRK EQ 0002: LOADADR EQ 9100: PATCH PL 0032: RDLP PL 0025: RDSEC EQ C65C SEC PL 0088: SECTOR EQ 003D: SECTRAN PL 0078 .LIST 0000: 0000: 0028 = LINEBASE: .EQU 28H ;BASE OF CURRENT SCREEN LINE 0000: 0024 = CURSORH: .EQU 24H ;CURRENT CURSOR HORZITIONAL POSITION 0000: 0025 = CURSORV: .EQU 25H ;CURREN0000: 0000 = DEBUG: .EQU FALSE ;TRUE FOR DEBUG CODE 0000: 0000: ;ENTRY POINTS 0000: .DEF APLINIT,APLIN,APLOUT,APLOTHER 0000: 0000: .NOLIST 0000: X%@X L+EDP% 6*@Q2"@(#lH.kz RwXmdem@(T/P C){ T? bV#l@Ā+lH$ZEhX@@0  @`P8$ m0Fۀje` P T TL,X*@j@ @ APLINIT: 0001: A9A0 LDA #0A0H ;MAKE CURRENT CHARACTER A SPACE 0003: 8D0000 STA CURCHR 0006: A960 LDA #60H ;MAKE CURSOR A FLASHING SPACE 0008: A424 LDY LS) 0000: ; ADDED INITIALIZATION OF TYPECARD 0000: ; 0000: ; 5/6/82 (WLS) 0000: ; MODIFIED FOR DEVICE HANDLER CONVECTIONS 0000: ; 0000: ; 2/2: SKLP PL 004B: SLOT16 EQ 002B TRACK EQ 0041: TRK PL 0089: WAIT EQ FCA8 T CURSOR VERTICAL POSITION 0000: CURCHR: .BLOCK 1 ;CURRENT CHARACTER AT CURSOR POSITION 0001: 0001: ;************************************ 0001: ;ROUTINE: INITIALIZE ROUTINES 0001: OME AND CLEAR SCREEN ROUTINE IN ROM 000F: 000F: 000F: ;*********************************** 000F: ;ROUTINE: APLIN 000F: ;PURP: GET A CHARCTER FROM A CARD 000F: ;ENTRY: Y = n0 000F: ********** 004B: 004B: 004B: APLOTHER: 004B: C902 CMP #2 004D: B00C BCS CHNOTREADY ;IF DO NOT KNOW THEN RETURN A 0 004F: A8 TAY ;SET FLAGS#"z"+1 0033: B003 BCS $2 ;BIF GREATER THAN LOWER CASE Z 0035: 38 SEC 0036: E920 SBC #20H ;ELSE MAKE LOWER CASE 0038: 0980 $2: ORA #80H ;SET BIT 7 003AA: 001A: ;*********************************** 001A: ;ROUTINE: APLOUT 001A: ;PURP: OUTPUT A CHARCTER TO THE DEVICE 001A: ;ENTRY: A = CHARACTER 001A: ; Y = n0 001A: ; TUS 004B: ;ENTRY: A = STATUS TYPE = 0 = OUTPUT STATUS, 1 = INPUT STATUS 004B: ; Y = n0 004B: ; X = Cn 004B: ; WHERE n = THE SLOT NUMBER 0..7 004B: ;EXIT: IF READY (WITH INPUT ;IF IT IS A CR THEN JUST SET CURSOR 002B: ; POSITION TO 0 SO AUTOMATIC LIND FEEDS AFTER 002B: ; CARRIAGE RETURNS DO NOT OCCUR 002B: F010 BEQ ; X = Cn 000F: ;EXIT: A = CHARACTER 000F: ;USED: A,F,Y,X 000F: ;*********************************** 000F: 000F: APLIN: 000F: AD00C0 LDA 0C000H 0012: 10FB LDY CURSORH 003F: B128 LDA (LINEBASE),Y 0041: 8D0000 STA CURCHR ;SAVE CHARACTER 0044: 297F AND #7FH ;TURN OFF BIT 7 0046: 0940 ORA #40H ;TURN ON BI: 20F0FD JSR 0FDF0H ;OUTPUT CHARACTER Page 3 SMALL CHARIO KS Z80 COMPUTER 003D: 003D: ;MAKE A FLASHING CURSOR (BIT 7 = 0, BIT 6 = 1) 003D: A424 $3: X = Cn 001A: ;EXIT: NONE 001A: ;USED: A,F,Y,X 001A: ;********************************** 001A: 001A: 001A: APLOUT: 001A: 48 PHA ;SAVE CHAROR OK TO OUTPUT) THEN 004B: ; A=0FFH 004B: ; C=1 004B: ; ELSE 004B: ; A=0 004B: ; C=0 004B: ;USED: A,F,Y 004B: ;********************* $3 ;ALWAYS TAKEN 002D: 002D: ;CONVERT LOWER TO UPPER CASE 002D: C961 $1: CMP #"a" 002F: 9007 BCC $2 ;BIF LESS THAN LOWER CASE A 0031: C97B CMP BPL APLIN ;WAIT FOR A CHARACTER TO BECOME AVAILABLE 0014: 8D10C0 STA 0C010H ;CLEAR STROBE 0017: 297F AND #07FH ;CLEAR BIT 7 0019: 60 RTS 001A: 001T 6 0048: 9128 STA (LINEBASE),Y ;MAKES A FLASHING CURSOR 004A: 60 RTS 004B: 004B: ;******************************* 004B: ;ROUTINE: APLOTHER 004B: ;PURP: RETURN THE STALA ;RESTORE CHARACTER 0023: C90D CMP #0DH ;CHECK FOR CARRIAGE RETURN 0025: D006 BNE $1 ;BIF NOT 0027: A900 LDA #0 0029: 8524 STA CURSORHACTER 001B: 001B: ;RESTORE CHARACTER AT CURSOR 001B: AD0000 LDA CURCHR 001E: A424 LDY CURSORH 0020: 9128 STA (LINEBASE),Y 0022: 0022: 68 P 0050: F005 BEQ CHREADY ;IF 0 THEN OUTPUT STATUS SO ALWAYS READY 0052: 0052: APLINSTAT: ; ELSE DO INPUT STATUS 0052: 2C00C0 BIT 0C000H 0055: 1004 BPL URSEC EQ 0003: OCURTRK EQ 0001: OPG0BASE EQ 0080 OSTATCDE EQ 0000: OTHERON EQ 0002: OTHOFFSE EQ 0006: OTHRON EQ 8FB8: OUTOFFSE EQ 0004 PG0B0 EQ 0009: PG0B1 EQ 000A: PG0B2 EQ 000B: PG0BASE EQ 0005: PG0W0 EQ 0005 PG0W1 EQ 0007: POLLRO3F: AILOPG0 EQ B041: AINITBLK EQ B04A: AINITCHR EQ B052 AISYSPG EQ B043: ALASTCMD EQ B05B: ALSTSLT EQ B049: AMONITOR EQ B02A: AOSLCLAD EQ B02F AOSLEN EQ B033: AOSSLVAD EQ B031: AOSSTART EQ B035: AOTHRRES EQ B026: APLIN DF 000F APLINIT DF 0001: V EQ 0086: @1RBDEV EQ 0002 @1RCDEV EQ 0082: @1WBDEV EQ 0004: @1WCDEV EQ 0084: @2APLON EQ 00B6: @2CMDDEF EQ 0003 @2CURPOL EQ 0075: @2HARDDE EQ 0003: @2HARDGX EQ 0003: @2OTHRON EQ 00B8: @2POLLTB EQ 0076 @2TRANSL EQ 0002: @2TRANVE EQ 0000: @2TYPECA E0001: FRSTVHI EQ 0076 FRSTVLO EQ 00B5: GOTOBHDL EQ B00F: GOTOCHDL EQ B012: GOTOINIT EQ B01B: GOTOWB EQ B01E GXYOFFSE EQ 0000: HARDDEF EQ 8F03: HARDGXY EQ 8F03: HARDGXYB EQ 8F54: HARDGXYO EQ 8F53 HIMEM EQ 0012: HIPG0 EQ 0015: IBDEV EQ 8E00 CHNOTREADY 0057: 0057: CHREADY: 0057: A9FF LDA #0FFH 0059: 38 SEC 005A: 60 RTS 005B: 005B: CHNOTREADY: 005B: A900 LDA #0 005D: 18 EN EQ B039: AWBSTART EQ B03B: AWCMDCNT EQ B044: AZ80SLOT EQ B02E: BEGINCP6 EQ B000 BFP0BASE EQ 0086: BLKDEVS EQ 8E00: CHNOTREA PL 005B: CHRDEVS EQ 8E80: CHREADY PL 0057 CLAFCMD EQ 000B: CMDARYPT EQ 0080: CMDDEFS EQ 8F03: CMDLPENT EQ B006: CP65 APLINSTA PL 0052: APLON EQ 8FB6: APLOTHER DF 004B: APLOUT DF 001A APPLEON EQ 0003: AREBOOTV EQ B028: ARESCODE EQ B024: ARESETIF EQ B078: ARWTSPDI EQ B099 ARWTSPSL EQ B098: AVERHI EQ B02D: AVERLOW EQ B02C: AWALCNT EQ B045: AWBLCLAD EQ B037 AWBL[`TĔA1%9%RAPLOTHETU%@U h@ H h}B IHV "(42A2< @=cH<A"P$ %1P R :PTS A1%9%R:Tc@A1=URp T TL,X*@j@ @: ICDEV EQ 8E80: INITOFFS EQ 0000 INOFFSET EQ 0002: ISTATCDE EQ 0001: LINEBASE EQ 0028: LOMEM EQ 0010: LOPG0 EQ 0014 NOTUSED EQ B021: NUMBLKDE EQ 0010: NUMCHRDE EQ 0010: OBDEV EQ 8E06: OCDEV EQ 8E86 OCURDMA EQ 0005: OCURDSK EQ 0000: OCQ 006D: AACMDARY EQ B05C: ABEGSLT EQ B047 ABEGSLTA EQ B048: ABOOTPRM EQ B05F: ABOOTSLO EQ B05E: ADSKBUF EQ B076: ADZ80 EQ B09D AEZ80 EQ B09A: AFRSTCMD EQ B05A: AHSTIDB EQ B046: AIDSKSZ EQ B03D: AIHIMEM EQ B040 AIHIPG0 EQ B042: AILOMEM EQ B0 CLC 005E: 60 RTS 005F: 005F: .END 00AE1 TP 002D: 00AE2 TP 0038: 00AE3 TP 003D: @1BLKDEV EQ 0000: @1CHRDEV EQ 0080 @1IBDEV EQ 0000: @1ICDEV EQ 0080: @1OBDEV EQ 0006: @1OCDE EQ B000 CURCHR PL 0000: CURPOLLN EQ 8F75: CURSORH EQ 0024: CURSORV EQ 0025: DEBUG EQ 0000 DEVTBL EQ 8E00: DL1FCMD EQ 000C: DLAFCMD EQ 000E: EFP0BASE EQ 00FF: ENDEXTRA EQ B0A0 ENDFIXED EQ 8FB9: FALSE EQ 0000: FLUSHCMD EQ 0002: FRMTCMD EQ UT EQ B003: POLLTBL EQ 8F76: PWREDUP EQ 03F4: RBDEV EQ 8E02 RCDEV EQ 8E82: RD1Z80BY EQ B009: RDNZ80BY EQ B015: RETCFB EQ 0012: SCRNBASE EQ 000C SELFB1 EQ 0010: SELFB2 EQ 0011: SNDNAMEC EQ 000F: SNDPRMCM EQ 0000: SOFTDEF EQ 8F55 SOFTEV E5u.^0 h&PPEu.T/PL0@ 7/07 #07 <.+p"L7)B.p/07 #0 6(Dۆ M TUԸAA u.PPEu.^`4fR6 OB +p+p P2 !@4+p܁q  `*( @.p WR1Z80BY EQ B00C WRNZ80BY EQ B018  `@:!A P*!@ p+i/#^@5m%Fd*50)xyѯ@6 9RF@nTXY5(L@Pf ,@@D @P2   , j*4T݅P["AKՠ I %')Mh J )@/PJ@~/6Q 03F2: SOFTGXY EQ 8F55: SOFTGXYB EQ 8F6A: SOFTGXYO EQ 8F69: SOFTLDIN EQ 8F6C SOFTLEAD EQ 8F6B: SYSP1 EQ 0082: SYSP2 EQ 0084: SZBLKDEV EQ 0080: SZCHRDEV EQ 0080 SZCMDDEF EQ 006A: SZDEVTBL EQ 0100: SZHARDDE EQ 0052: SZPOLLTB EQ 0040: SZSOFTCM EQ 00A2ā,@2(( +j`2,@1![]UmwB< V(!]K$ L 6 P*!@p rʖ \L  \L  h h  #p`3+k7+k70@+p2-P2(( LJ٠${@ fà<P)T,@9`Wvga@XQ|[@JIbN셈:wGAܥ d RMh TP$N`(6(Q@ XPvB n Vp([enBոh QTp(!.R&0!e4j\ h8@H\VE&V0S!@p+i@P L t5DDHHh fRDZ80BYV `uu%%hM1=RTD5K%  ph<\". K@%p pl\8.K% qn o@ @ j aɔuF'ѕ 6 X(3 pf @" ?4(("+)(0blR* hP2 hPBL b ! !r hj@AA ^ѕ A|ѠAyРd +p<k`XS!sJxר&P,CxԸ@R5 }P y`CAڥ ^ +!hDA_@ ]QԸ[ReH ^X P^@j0"R@ elGRHAAALCzp d S:_-uׂۀ[ Ch5VAFOЂ+* /Pl|<mZHٵl`*((@!@2L@RT.mP `P12@ͲBW6 &Q&P``:~: = \P1 `J P`pP1 EQ 0010 SELFB2 EQ 0011: SNDNAMEC EQ 000F: SNDPRMCM EQ 0000: SOFTDEF EQ 8F55: SOFTEV EQ 03F2 SOFTGXY EQ 8F55: SOFTGXYB EQ 8F6A: SOFTGXYO EQ 8F69: SOFTLDIN EQ 8F6C: SOFTLEAD EQ 8F6B SYSP1 EQ 0082: SYSP2 EQ 0084: SZBLKDEV EQ 0080: SZCHRDEV EQ 0080: SZCMDDEF EQ 006A SZDEVTBL EQ 0100: SZHARDDE EQ 0052: SZPOLLTB EQ 0040: SZSOFTCM EQ 0014: SZSOFTDE EQ 0018 SZTYPECA EQ 0008: TACLR EQ 0013: TAOFF EQ 0014: TAON EQ 0015: TRANSLOT EQ 8F02 TRANVEC EQ 8F00: TRUE EQ FFFF: TYPECARD EQ 8F6D: ULAFCMD EQ 000D: VIDEOBAS EQ 000E WAP16 DF 0016: WBDEV EQ 8E04: WCDEV EQ 8E84: WDTHDSP EQ 0004: WR1Z80BY EQ B00C WRITE EQ 0002: WRNZ80BY EQ B018