; CHAPTER 2: Investigation of Modulae boot loader. I've read the source they provided, but this may differ somewhat ; Uses $C50D (without deriving it properly!), may also use IWM 3.5" drive registers at second stage ; Let's look! ; 5/1/2016 conclusions: boot0 loader uses smartport ; boot1 uses low-level IWM registers ; modulae disk block $00 @ $00/0800 (first-stage loader) ; 0800: 01 - db 01 ; it's always 01 0801: 78 - SEI 0802: 38 - SEC 0803: FB - XCE ; e=1 0804: 8D 00 C0 - STA $C000 ; 80store off 0807: 8D 0C C0 - STA $C00C ; set 40 columns 080A: EE F4 03 - INC $03F4 ; corrupt $3F4: reset will reboot 080D: 20 89 FE - JSR $FE89 ; IN #0 (keyboard/screen) 0810: 20 93 FE - JSR $FE93 ; PR #0 (keyboard/screen) 0813: 20 2F FB - JSR $FB2F ; set text mode 0816: 20 58 FB - JSR $FC58 ; clear text screen 0819: 38 - SEC 081A: 20 1F FE - JSR $FE1F ; check machine ID 081D: 90 4C - BCC $086B ; carry clear == IIGS 081F: A9 00 - LDA #$00 0821: A0 00 - LDY #$00 0823: 20 4C 08 - JSR $084C ; call subroutine for non-iigs machine ; not-iigs message here 0826: - str 'MODULAE required an Apple IIGS.' 0845: 00 - db 00 0846: 9C 00 08 - STZ $0800 0849: 4C 00 E0 - JMP $E000 ; BASIC language entry point ; subroutine called if not iigs 084C: 84 24 - STY $24 ; $24 = 00 084E: 20 5B FB - JSR $FB5B ; vtab 0851: 68 - PLA 0852: 85 00 - STA $00 ; $00 - high byte of return address frm stack 0854: 68 - PLA 0855: 85 01 - STA $01 ; $01 - low byte of return address frm stack 0857: E6 00 - INC $00 ; increment return address 0859: A2 00 - LDX #$00 085B: A1 00 - LDA ($00,X) ; load stuff after return address 085D: F0 05 - BEQ $0864 ; break if terminating zero 085F: 20 ED FD - JSR $FDED ; print out a letter 0862: 80 F3 - BRA $0857 ; continue printing loop 0864: A5 01 - LDA $01 0866: 48 - PHA 0867: A5 00 - LDA $00 0869: 48 - PHA 086A: 60 - RTS ; effectively jump to $(0000) = return address after end of message ; where we land if we are on a IIGS 086B: AD 2E C0 - LDA $C02E 086E: C9 F8 - CMP #$F8 0870: 90 F9 - BCC $086B ; VBL wait loop 0872: A9 41 - LDA #$41 0874: 8D 29 C0 - STA $C029 ; VGC text mode 0877: A9 80 - LDA #$80 0879: 0C 36 C0 - TSB $C036 ; TODO CYA register 087C: 0C 2D C0 - TSB $C03D ; Ensonic DOC register 087F: 9C 34 C0 - STZ $C034 ; black-out border color 0882: 9C 22 C0 - STZ $C022 ; black-out text and background 0885: 9C 23 C0 - STZ $C023 ; TODO turn off VGC interrupts? 0888: 9C 41 C0 - STZ $C041 ; TODO turn off VBL interrupts? 088B: 9C 32 C0 - STZ $C032 ; VGC interrupt clear 088E: AF C0 00 E1 - LDAL $E100CA 0892: 29 0F - AND #$0F 0894: 8D 3C C0 - STA $C03C ; set DOC volume from control panel 0897: A2 A0 - LDX #$A0 0899: 8A - TXA 089A: 8D 3E C0 - STA $C03E ; DOC register #$A0 (channel control) 089D: A9 03 - LDA #$03 089F: 8D 3D C0 - STA $C03D ; DOC data: #$03 (one shot/halt) 08A2: E8 - INX 08A3: E0 C0 - CPX #$C0 08A5: D0 F2 - BNE $0899 ; set DOC control registers $A0 through $C0 (control1 through control32) 08A7: A9 E1 - LDA #$E1 08A9: 8D 3E C0 - STA $C03E ; DOC register #$E1 (??) 08AC: A9 3E - LDA #$ 08AE: 8D 3D C0 - STA $C03D ; DOC register data: always $3D 08B1: 18 - CLC 08B2: FB - XCE 08B3: C2 30 - REP #$30 ; cookin with gas 0B85: A9 FF 01 - LDA #$01FF 08B8: 1B - TCS ; nail the stack? 08B9: A9 00 00 - LDA #$0000 08BC: 8F FE 15 E1 - STAL $E115FE ; TODO kill tools? 08C0: 5B - TCD 08C1: 38 - SEC 08C2: FB - XCE ; e=1 08C3: 20 F9 08 - JSR $08F9 ; read disk block 1 at $0A00-$0C00 08C6: 20 76 0B - JSR $0B76 ; check if modifier key pressed, if so, go to text and print loader screen 08C9: A9 94 - LDA #$94 08CB: 8D DA 09 - STA $09DA ; new disk read buffer: $9400 08CE: 8D B3 09 - STA $09B3 ; also store it at $09B3 for later routine 08D1: A9 07 - LDA #$07 08D3: 3D DB 09 - STA $09DB ; new disk read block #7 08D6: 20 F9 08 - JSR $08F9 ; read disk block 7 at $9400-$9600 08D9: EE DB 09 - INC $09DB ; increment disk read block 08DC: EE DA 09 - INC $09DA 08DF: EE DA 09 - INC $09DA ; inc disk read buffer by two pages because $200 per sector 08E2: AD DB 09 - LDA $09DB 08E5: C9 0D - CMP #$0D 08E7: 90 ED - BCC $9DB ; blocks 7,8,9,A,B,C at $9400-$A000 08E9: 18 - CLC 08EA: FB - XCE 08EB: C2 30 - REP #$30 08ED: AE B2 09 - LDX $09B2 ; x = $9400 08F0: A9 00 00 - LDA #$0000 ; a = $0000 08F3: 20 00 0A - JSR $0A00 ; call Decruncher 08F6: 6C B2 09 - JMP ($09B2) ; jump to next stage @ $9400 ; DEBUG ALT: ; 08F6: 00 00 (BRK) ; smartport entry1 08F9: 20 0D C5 - JSR $C50D ; smartport entry; NOTE NOT SUPERDRIVE-COMPATIBLE (but CFFA3K compatible) 08FC: 01 - db 01 ; read block command 08FD: D7 09 - dw $09D7 ; params at $09D7 08FF: B0 01 - BCS $0902 ; branch if error 0901: 60 - RTS 0902: C9 2E - CMP #$2E 0904: F0 F3 - BEQ $08F9 ; try again if error was $2E 0906: 20 0D C5 - JSR $C50D 0909: 04 - db 04 ; smartport cmd 4 (control) 090A: D1 09 - dw $09D1 ; params at $09D1 ; disk error here 090C: 18 - CLC 090D: FB - XCE 090E: C2 30 - REP #$30 ; cookin with gas 0910: A2 00 00 - LDX #$0000 ; fill screen with spaces 0913: A9 A0 A0 - LDA #$A0A0 0916: 9D 00 04 - STA $0400,X 0919: 9F 00 04 01 - STAL $010400,X 091D: E8 - INX 091E: E8 - INX 091F: E0 00 04 - CPX #$0400 0922: D0 EF - BNE $0913 0924: 38 - SEC 0925: FB - XCE 0926: 8D 0F C0 - STA $C00F ; alt char set on 0929: 8D 0D C0 - STA $C00D ; 80 columns on 092C: AF DA 02 E1 - LDAL $E102DA ; TODO get control panel text/background colors? 0930: 0A - ASL 0931: 0A - ASL 0932: 0A - ASL 0933: 0A - ASL ; divide by 16 / move upper half of byte to lower half and fill with zeroes 0934: 0F DB 02 E1 - ORAL $E102DB 0938: 8D 22 C0 - STA $C022 ; restore text/background colors? 093B: AF DC 02 E1 - LDAL $E201DC ; TODO get control panel border color? 093F: 8D 34 C0 - STA $C034 ; restore border color? 0942: A9 01 - LDA #$01 0944: 8D 29 C0 - STA $C029 ; VGC text mode 0947: A0 00 - LDY #$00 ; text printing loop (80-column rolling apple) 0949: B9 B4 09 - LDA $09B4,Y 094C: F0 0B - BEQ $0959 094E: 8B - PHB 094F: 20 A5 09 - JSR $09A5 ; get offset into 80-col text screen 0952: 9D 0C 07 - STA $070C,X ; write text to 80-column screen 0955: AB - PLB 0956: C8 - INY 0957: 80 F0 - BRA $0949 0959: 20 3A FF - JSR $FF3A ; ring the bell 095C: A0 00 - LDY #$00 095E: F0 08 - BEQ $0968 0960: 20 A5 09 - JSR $09A5 ; get offset into 80-col text screen 0963: A9 DF - LDA #$DF 0965: 9D A8 05 - STA $05A8,X 0968: C8 - INY 0969: 20 A5 09 - JSR $09A5 ; get offset into 80-col text screen 096C: A9 41 - LDA #$41 096E: 9D A8 05 - STA $05A8,X 0971: 20 9A 09 - JSR $099A ; wait for a VBL 0974: C0 4D - CPY #$4D 0976: 90 E6 - BCC $095E 0978: 88 - DEY 0979: C8 - INY 097A: 20 A5 09 - JSR $09A5 ; get offset into 80-col text screen 097D: A9 4C - LDA #$4C 097F: 9D A8 05 - STA $05A8,X 0982: 88 - DEY 0983: 20 A5 09 - JSR $09A5 ; get offset into 80-col text screen 0986: A9 40 - LDA #$40 0988: 9D A8 05 - STA $05A8,X 098B: 20 9A 09 - JSR $099A ; wait for a VBL 098E: 88 - DEY 098F: D0 E8 - BNE $0979 0991: C8 - INY 0992: 80 CA - BRA $095E 0994: 8D 22 C0 - STA $C022 ; text/background color 0997: 20 9A 09 - JSR $099A ; wait for a VBL 099A: AD 19 C0 - LDA $C019 099D: 30 FB - BMI $099A ; VBL wait part 1 099F: AD 19 C0 - LDA $C019 09A2: 10 FB - BPL $099F ; VBL wait part 2 09A4: 60 - RTS ; subroutine to set X to offset into 80-column text screen 09A5: 48 - PHA 09A6: 98 - TYA 09A7: 4A - LSR 09A8: AA - TAX 09A9: A9 00 - LDA #$00 09AB: B0 01 - BCS $09AE 09AD: 1A - INC 09AE: 48 - PHA 09AF: AB - PLB 09B0: 68 - PLA 09B1: 60 - RTS 09B2: 00 - DB 00 09B3: C5 - DB C5 ; gets changed to $94 by $08CE 09B4: - STR ' [ MODULAE Loading Error ! [' 09D0: - DB 00 ; smartport eject params 09D1: 03 - DB 03 ; parameter count = 3 09D2: 01 - DB 01 ; unit number 1 09D3: 00 00 - DW 0000 ; control list parameter: 0000 09D5: 04 00 - DB 04,00 ; eject ; smartport block read params 09D7: 03 - DB 03 ; parameter count = 3 09D8: 01 - DB 01 ; unit number 1 09D9: 00 0A - DW $0A00 ; read buffer = $0A00 09DB: 01 00 00 - DB 01,00,00 ; block number 1 ; all zeroes after this ; modulae disk block $01 @ $00/0A00 ; ; Decruncher ACS - From TSI Cruncher ; MultiBank - AutoDecompactable by itself ; v1.0 - 29/JUL/90 ; on first call... ; x = $9400 (address in bank) ; a = $0000 (bank number) ; $00 = Ptr_Decompact = start of data area ; $04 = Ptr_Crunch ; $08 = Ptr_Len ; $0A = Ptr_Dist ; $0E = Buf_Lu ; $0F = Buf_Copie ; $10 = Current_Range ; Decruncher 0A00: 08 - PHP 0A01: C2 30 - REP #$30 0A03: 86 00 - STX $00 ; Ptr_Decompact = $9400 0A05: 8E 68 0B - STX $0B68 ; Patch_End = $0B68/$0B69 = $9400 0A03: 85 02 - STA $02 ; Ptr_Decompact+2 = $0000 0A0A: E2 30 - SEP #$30 0A0C: 8D 6F 0B - STA $0B6F ; Patch_End2 = $0B6F = $00? 0A0F: C2 30 - REP #$20 0A11: A9 80 00 - LDA #$0080 0A14: 0C 36 C0 - TSB $C036 ; TODO CYA register 0A17: A0 02 00 - LDY #$0002 0A1A: A7 00 - LDA [$00] ; A = [Ptr_Decompact] = value at $9400 ($0B12) 0A1C: 18 - CLC 0A1D: 65 00 - ADC $00 ; add Ptr_Decompact = $9400 to value at $9400 = $9F12 0A1F: 85 04 - STA $04 ; Ptr_Crunch = $04 = $9F12 0A21: A0 02 00 - LDY #$0002 0A24: B7 00 - LDA [$00], Y ; A = [Ptr_Decompact] = value at $9402 to start ($0000) 0A26: 65 02 - ADC $02 ; add $00 0A28: 85 06 - STA $06 ; $06 = $0000 0A2A: A7 04 - LDA [$04] ; A = value at $9F12 = $FB18 (CLC,XCE) 0A2C: 07 00 - STA [$00] ; $9400 = CLC,XCE 0A2E: B7 04 - LDA [$04],Y ; A = $9F12+2 = $30E2 (SEP #$30) 0A30: 97 00 - STA [$00],Y ; $9402 = SEP #$30 0A32: C8 - INY 0A33: C8 - INY ; y = 4 0A34: B7 04 - LDA [$04],Y ; A = $9F12+4 = $1201 0A36: E2 20 - SEP #$20 0A38: 8D 56 0A - STA $0A56 ; $0A56 = $01 0A3B: EB - XBA 0A3C: 8D 28 0B - STA $0B28 ; $0B28 = $12 0A41: C8 - INY 0A42: C8 - INY ; y = 6 0A43: B7 04 - LDA [$04],Y ; A = $9F12+6 = $12 0A45: 18 - CLC 0A46: 65 01 - ADC $01 ; A = $12 + $94 = $A6 0A48: 85 01 - STA $01 ; $01 = $A6, $00/01 = $94A6 0A4A: E2 30 - SEP #$30 0A4C: 20 51 0A - JSR $0A51 ; TODO what 0A4F: 28 - PLP 0A50: 60 - RTS ; Go_Decompact 0A51: 64 10 - STZ $10 ; Current_Range = $10 = 0 0A53: 64 09 - STZ $09 ; Ptr_Len+1 = $09 = 0 0A55: A9 00 - LDA #$00 ; NOTE this $00 gets changed by $0A38 to $01, A = 1 0A57: 85 08 - STA $08 ; $08 = 01 ; prg1 0A59: 20 36 0B - JSR $0B36 ; JSR rout1 0A5C: 20 52 0B - JSR $0B52 ; JSR rout2 0A5F: D0 08 - BNE $0A69 0A61: A9 01 - LDA #$01 0A63: 85 09 - STA $09 ; Ptr_Len+1 - if the byte is nul, recopy an entire page 0A65: A9 00 - LDA #$00 0A67: 80 EE - BRA $A57 ; more1 0A69: 85 0E - STA $0E ; Buf_Lu 0A6B: 29 3F - AND #$3F 0A6D: 85 0A - STA $0A ; Ptr_Dist 0A6F: 85 0F - STA $0F ; Buf_Copie 0A71: 64 0B - STZ $0B ; Ptr_Dist+1 0A73: A5 0E - LDA $0E ; Buf_Lu - if bit 7 is set, go to more2 0A75: 30 34 - BMI $0AAB ; more2 0A77: 06 0E - ASL $0E ; Buf_Lu - if bit 6 is set, go to more3 0A79: 30 26 - BMI $0AA1 ; more3 0A7B: A9 00 - LDA #$00 ; if bit 7 is 0 and bit 6 is 0 0A7D: 85 0F - STA $0F ; Buf_Copie 0A7F: A9 02 - LDA #$02 ; prg2 0A81: 85 08 - STA $08 ; prg3 0A83: C2 20 - REP #$20 0A85: 18 - CLC ; where Ptr_Dist is = to offset + destination 0A86: A5 0A - LDA $0A ; Ptr_Dist 0A88: 65 00 - ADC $00 ; Ptr_Decompact 0A8A: 85 0A - STA $0A ; Ptr_Dist 0A8C: A5 02 - LDA $02 ; Ptr_Decompact+2 0A8E: 69 00 00 - ADC #$0000 0A91: 85 0C - STA $0C ; Ptr_Dist+2 0A93: E2 20 - SEP #$20 0A95: 20 E8 0A - JSR $0AE8 ; rout3 0A98: A5 0F - LDA $0F 0A9A: 85 08 - STA $08 0A9C: F0 BE - BEQ $0A5C 0A9E: 4C 59 0A - JMP $0A59 ; prg1 ; more3 0AA1: 20 52 0B - JSR $0B52 ; rout2 0AA4: 85 0A - STA $0A ; Ptr_Dist 0AA6: A9 03 - LDA #$03 0AA8: 4C 81 0A - JMP $0A81 ; prg2 ; more2 0AAB: 06 0E - ASL $0E 0AAD: 30 29 - BMI $0AD8 0AAF: A9 04 - LDA #$04 0AB1: 85 08 - STA $08 0AB3: A5 0F - LDA $0F 0AB5: C9 3F - CMP #$3F 0AB7: D0 05 - BNE $0ABE 0AB9: 20 52 0B - JSR $0B52 0ABC: 85 0F - STA $0F 0ABE: 20 52 0B - JSR $0B52 0AC1: 85 0A - STA $0A 0AC3: 38 - SEC 0AC4: A5 0A - LDA $0A 0AC6: E5 10 - SBC $10 0AC8: F0 02 - BEQ $0ACC 0ACA: B0 07 - BCS $0AD3 0ACC: A5 0A - LDA $0A 0ACE: 85 0B - STA $0B 0AD0: 20 52 0B - JSR $0B52 0AD3: 85 0A - STA $0A 0AD5: 4C 83 0A - JMP $0A83 0AD8: A5 0F - LDA $0F 0ADA: C9 05 - CMP #$05 0ADC: B0 05 - BCS $0AE3 0ADE: 85 09 - STA $09 0AE0: 20 52 0B - JSR $0B52 0AE3: 85 08 - STA $08 0AE5: 4C B9 0A - JMP $0AB9 ; decrement counters at $00, $0a/$0b 0AE8: 38 - SEC 0AE9: A5 00 - LDA $00 ; A = $9400 0AEB: E5 08 - SBC $08 ; $08 = $01 0AED: 85 00 - STA $00 ; $00 = $93FF 0AEF: B0 03 - BCS $0AF4 0AF1: 20 25 0B - JSR $0B25 0AF4: 38 - SEC 0AF5: A5 0A - LDA $0A ; $0A = 00? 0AF7: E5 08 - SBC $08 ; a = $FF 0AF9: 85 0A - STA $0A ; $0a = 1F 0AFB: B0 08 - BCS $0B05 0AFD: A5 0B - LDA $0B ; a = $0b 0AFF: D0 02 - BNE $0B03 0B01: C6 0C - DEC $0C ; dec $0c if $0b overflowed 0B03: C6 0B - DEC $0B ; dec $0b again 0B05: A4 08 - LDY $08 ; y = $01 0B07: 98 - TYA ; a = $01 0B08: 05 09 - ORA $09 0B0A: D0 01 - BNE $0B0D 0B0C: 60 - RTS 0B0D: 98 - TYA 0B0E: D0 0D - BNE $0B1D 0B10: C6 09 - DEC $09 0B12: A5 0B - LDA $0B 0B14: D0 02 - BNE $0B18 0B16: C6 0C - DEC $0C 0B18: C6 0B - DEC $0B 0B1A: 20 25 0B - JSR $0B25 0B1D: 88 - DEY 0B1E: B7 0A - LDA [$0A],Y 0B20: 97 00 - STA [$00],Y 0B22: 4C 07 0B - JMP $0B07 0B25: A5 10 - LDA $10 0B27: C9 00 - CMP #$00 ; NOTE this $00 gets changed by $0A3C to $12 0B29: B0 02 - BCS $0B2D ; >= $12? 0B2B: E6 10 - INC $10 ; if not, increment 0B2D: A5 01 - LDA $01 0B2F: D0 02 - BNE $0B33 ; $01 not $00? 0B31: C6 02 - DEC $02 0B33: C6 01 - DEC $01 0B35: 60 - RTS 0B36: C2 20 - REP #$20 0B38: A5 04 - LDA $04 ; A = $12 0B3A: 85 0A - STA $0A ; $0A = $12 0B3C: A5 05 - LDA $05 ; A = $9F 0B3E: 85 0B - STA $0B ; $0B = $9F, $0A = $9F12 0B40: E2 20 - SEP #$20 0B42: 20 E8 0A - JSR $0AE8 0B45: C2 20 - REP #$20 0B47: A5 0A - LDA $0A 0B49: 85 04 - STA $04 0B4B: A5 0B - LDA $0B 0B4D: 85 08 - STA $05 0B4F: E2 20 - SEP #$20 0B51: 60 - RTS 0B52: A5 04 - LDA $04 0B54: D0 08 - BNE $0B5E 0B56: A5 05 - LDA $05 0B58: D0 02 - BNE $0B5C 0B5A: C6 06 - DEC $06 0B5C: C6 05 - DEC $05 0B5E: C6 04 - DEC $04 0B60: B7 04 - LDA [$04],Y 0B62: 48 - PHA 0B63: C2 20 - REP #$20 0B65: A5 04 - LDA $04 0B67: C9 00 00 - CMP #$0000 ; Patch_End NOTE this $0000 gets changed by $0A05 0B6A: E2 20 - SEP #$20 0B6C: A5 06 - LDA $06 0B6E: E9 00 - SBC #$00 ; Patch_End2 NOTE this $00 gets changed by $0A0C 0B70: 68 - PLA 0B71: B0 02 - BCS $0B75 0B73: 68 - PLA 0B74: 68 - PLA 0B75: 60 - RTS ; end of ACS Decruncher ; check for modifier keypress, show text loader if so 0B76: AD 25 C0 - LDA $C025 ; read keyboard modifier keys 0B79: 29 C3 - AND #$C3 0B7B: C9 01 - CMP #$01 0B7D: D0 54 - BNE $0BD3 0B7F: 38 - SEC 0B80: FB - XCE 0B81: 08 - PHP 0B82: E2 30 - SEP #$30 0B84: 20 00 C3 - JSR $C300 ; PR #3 (80-column text) 0B87: 20 58 FC - JSR $FC58 ; clear text screen 0B8A: A9 0D - LDA #$0D 0B8C: A0 1D - LDY #$1D 0B8E: 20 4C 08 - JSR $084C ; print message after return address and crash to rolling apple 0B91: - STR 'FTA SpeedyBoot v2.0' 0BA4: 00 - DB 00 0BA5: - STR '). L.MODULAE v1.02' 0BB9: 00 - DB 00 0BBA: - STR ')' 0BBB: 00 - DB 00 0BBC: 8D - DB 8D 0BBD: 00 - DB 00 ; TODO what is this? maybe nothing interesting 0BBE: C0 20 - CPY #$20 0BC0: 94 09 - STY $09,X 0BC2: A9 50 20 - LDA #$2050 0BC5: 94 09 - STY $09,X 0BC7: A9 A0 20 - LDA #$20A0 0BCA: 94 09 - STY $09,X 0BCC: A9 F0 20 - LDA #$20F0 0BCF: 94 09 - STY $09,X 0BD1: 28 - PLP 0BD2: FB - XCE 0BD3: 60 - RTS ; all zeroes after this till $C00 ; modulae disk block #07 @ $9400 ; 9400: 12 0B - DB 12,0B ; later changed to CLC, XCE 9402: 00 00 - DB 00,00 ; later changed to SEP #$30 9404: 78 - SEI 9405: 9C F4 03 - STZ $03F4 ; corrupt $3F4: reset will reboot 9408: A9 37 09 - LDA #$0937 940B: 89 A9 30 - BIT #$30A9 940E: 8D 35 C0 - STA $C035 ; shadow register 9411: 57 05 - EOR [$05],Y ; modulae disk block #08 @ $9600 ; modulae disk block #09 @ $9800 ; modulae disk block #0A @ $9A00 ; modulae disk block #0B @ $9C00 ; modulae disk block #0C @ $9E00 9F00: A4 88 88 10 - DB A4,88,88,10 9F12: 18 - CLC 9F13: FB - XCE 9F14: E2 30 - SEP #$30 9F16: 01 12 - DB 01,12 9F18: 12 00 - DB 12,00 ; decrunched $9400 disassembly: ; with help from xmas demo src (one of the GIFT.SDK disks, volume DEMO, file LOADER2.S) ; CHK1 = $5C ; read routine checksum ; CHK2 = $5D ; CHK3 = $5E ; QUART = $66 ; storage for fourth nibble ; PNT0 = $06 ; Loading address ; PNT1 = $18 ; Loading address-1 ; PNT2 = $1C ; Loading address+254 ; PNT3 = $F0 ; Loading address+510 9400: 18 - CLC 9401: FB - XCE 9402: E2 30 - SEP #$30 9404: 78 - SEI 9405: 9C F4 03 - STZ $03F4 ; corrupt $3F4: reset will reboot 9408: A9 80 0C - LDA #$80 940A: 0C 36 C0 - TSB $C036 940D: A9 30 - LDA #30 940F: 8D 35 C0 - STA $C035 9412: C2 30 - REP #$30 9414: A2 00 00 - LDX #$0000 ; load 3.5" disk I/O vectors, store them in different vectors? ; NOTE $E10F6F is the SetHook/GetHook table for 3.5" disk I/O 9417: BF 73 0F E1 - LDA E10F6F+4,X 941B: 9F 6F 0F E1 - STA E10F6F,X 941F: BF 75 0F E1 - LDA E10F6F+6,X 9423: 9F 71 0F E1 - STA E10F6F+2,X 9427: 8A - TXA 9428: 18 - CLC 9429: 69 08 00 - ADC #$0008 942C: AA - TAX 942D: E0 40 00 - CPX #0040 9430: D0 E5 - BNE $9417 ; check for 1MB of RAM ; store zeroes at $0000 in banks $00 through $10 9432: E2 30 - SEP #$30 9434: 8B - PHB 9435: A9 00 48 - LDA #00 9437: 48 - PHA 9438: AB - PLB 9439: 8D 00 00 - STA $0000 943C: 1A C9 10 - INC 943D: C9 10 - CMP #$10 943F: D0 F6 - BNE $9437 ; check that $0000 is still zeroed in banks $00 through $10 9441: A9 00 - LDA #00 9443: 48 - PHA 9444: AB - PLB 9445: CD 00 00 - CMP $0000 9448: D0 07 - BNE $9451 944A: 1A - INC 944B: C9 10 - CMP #$10 944D: D0 F4 - BNE $9443 944F: 80 05 - BRA $9456 ; not enough memory error 9451: A9 00 - LDA #00 9453: 4C D1 9C - JMP $9CD1 ; eject disk etc ; continue with the show ; some $E10000 preparation here outside of SHR area ; looks like we zero-out a lot of tool locator vectors to CLC, RTL (wow, someone really hates tools) 9456: AB - PLB 9457: C2 30 - REP #$30 9459: A2 00 00 - LDX #0000 945C: A9 18 6B - LDA #$6B18 945F: 9F 00 00 E1 - STA $E10000,X 9463: E8 - INX 9464: E8 - INX 9465: E8 - INX 9466: E8 - INX 9467: E0 10 10 - CPX #$0010 946A: F0 F7 - BEQ $9463 946C: E0 B4 00 - CPX #$00B4 946F: D0 EB - BNE $945C 9471: A9 38 6B - LDA #$6B38 9474: 8F 6C 00 E1 - STA $E1006C ; change bell vector? ; clear SHR screen 9478: A2 00 00 - LDX #0000 947B: 8A - TXA 947C: 9F 00 20 E1 - STA $E12000,X 9480: E8 - INX 9481: E8 - INX 9482: 10 F8 - BPL $947C ; this will branch till X = $8000 which is size of SHR screen after all, clearing $7FFE bytes 9484: 4C D6 9A - JMP $9AD6 ; jump to stage 2 loader ; as with XMAS DEMO, we have tables to help us with de-nibblization of 6-and-2 encoding ; DEBDATA 9487: D5 AA AD - HEX ADAAD5 ; beginning of track data area mark ; FINDATA 948A: AA DE - HEX AADE ; end of track data area mark ; ; DS IN0+$96-* ;Modifier $94.. si SEGMENT depasse.. ; ;OCTET 9496: - HEX 00010000020300040506000000000000 ; Translation table - HEX 0708000000090A0B0C0D00000E0F1011 - HEX 1213B81415161718191AC0C1C2C3C4C5 ; for 6-bit nibbles - HEX C6C7C8C9CA1BCC1C1D1ED0D1D21FD4D5 - HEX 2021D822232425262728E0E1E2E3E429 - HEX 2A2BE82C2D2E2F303132000033343536 - HEX 3738F8393A3B3C3D3E3F ;OCTET2 - HEX 00000000000000000000000000000000 ; Fast decoding tables - HEX 40404040404040404040404040404040 - HEX 80808080808080808080808080808080 - HEX C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0 ;OCTET3 - HEX 000000004040404080808080C0C0C0C0 ; standard - HEX 000000004040404080808080C0C0C0C0 - HEX 000000004040404080808080C0C0C0C0 - HEX 000000004040404080808080C0C0C0C0 ;OCTET4 - HEX 004080C0004080C0004080C0004080C0 - HEX 004080C0004080C0004080C0004080C0 - HEX 004080C0004080C0004080C0004080C0 - HEX 004080C0004080C0004080C0004080C0 ; 1=m 0=x ; this is the IWM low-level 3.5" disk I/O that isn't CFFA3000 compatible ; see http://www.mac.linux-m68k.org/devel/iwm.php ; see also bouncin ferno etc sources? ; see also POCorGTFO 0x10 which deals with 5.25" low-level IO which is very very similar ; guessing the 9400,x and 9500,x offsets are de-nibblization things ; NOTE this is almost unchanged from XMAS DEMO LOADER2.S so I'm borrowing comments from there 95C0: 38 - SEC ; bad data field 95C1: 60 - RTS 95C2: 64 5E - STZ $5E ; CHK3 95C4: 64 5D - STZ $5D ; CHK2 95C6: 64 5C - STZ $5C ; CHK1 95C8: A0 19 - LDY #$19 ; "Locate the data byte signal" 95CA: A2 02 - LDX #$02 ; "Locate the byte beginning pointer" 95CC: 88 - DEY 95CD: F0 F1 - BEQ $95C0 ; branch if error 95CF: AD EC C0 - LDA $C0EC ; DATA 95D2: 10 FB - BPL $95CF ; wait until iwm ready 95D4: DD 87 94 - CMP $9487,X 95D7: D0 F1 - BNE $95CA 95D9: CA - DEX 95DA: 10 F0 - BPL $95CC ; at this point we've read D5 AA AD (beginning of track data) ; NOTE D5 AA 95 is address field preamble ; it is followed by track#, sector#, sides, format, checksum, then DE AA ; then there is the track data field ; it starts with D5 AA AD ; it is followed by track#, 699 data bytes (6-and-2 encoded), 4 checksum bytes, then DE AA ; NOTE there are lots of these, in LOADER2.S, they are MAC'd as 'NIBBLE'.. it reads one 6-and-2 encoded byte from disk ; ie loop reading DATA register until high bit is set (ie a nibble is ready for us to read) ; get the next byte: block number 95DC: AE EC C0 - LDX $C0EC 95DF: 10 FB - BPL $95DC ; wait until iwm ready ; verify that we got the correct block number 95E1: BD 00 94 - LDA $9400,X ; translate nibble from OCTET 6-bit translation table, in LOADER2.S this is MAC'd as 'EVAL' 95E4: CF 33 0F E1 - CMP $E10F33 ; NUMBL, we're holding the block number here 95E8: D0 D6 - BNE $95C0 ; if it doesn't match, we error out ; checksum of the first 12 octets? 95EA: A0 F3 - LDY #$F3 95EC: 4C 2A 96 - JMP $962A 95EF: AE EC C0 - LDX $C0EC 95F2: 10 FB - BPL $95EF ; wait until iwm ready 95F4: BD 00 94 - LDA $9400,X 95F7: A6 66 - LDX $66 95F9: 1D 00 95 - ORA $9500,X 95FC: 45 5C - EOR $5C 95FE: 65 5E - ADC $5E 9600: 85 5E - STA $5E 9602: C8 - INY 9603: AE EC C0 - LDX $C0EC 9606: 10 FB - BPL $9603 ; wait until iwm ready 9608: BD 00 94 - LDA $9400,X 960B: A6 66 - LDX $66 960D: 1D 40 95 - ORA $9540,X 9610: 45 5E - EOR $5E 9612: 65 5D - ADC $5D 9614: 85 5D - STA $5D 9616: C8 - INY 9617: AE EC C0 - LDX $C0EC 961A: 10 FB - BPL $9617 ; wait until iwm ready 961C: BD 00 94 - LDA $9400,X 961F: A6 66 - LDX $66 9621: 1D 80 95 - ORA $9580,X 9624: 45 5D - EOR $5D 9626: 65 5C - ADC $5C 9628: 85 5C - STA $5C ; read and store the 4th nibble 962A: AE EC C0 - LDX $C0EC 962D: 10 FB - BPL $962A ; wait until iwm ready 962F: BD 00 94 - LDA $9400,X ; translate it 9632: 85 66 - STA $66 ; store it in QUART 9634: 06 5C - ASL $5C ; multiply with CHK1 9636: 90 02 - BCC $963A ; no need to inc CHK1? 9638: E6 5C - INC $5C 963A: C8 - INY 963B: D0 B2 - BNE $95EF ; loop for 12 octets ; read and decode the first 255 octets of the block 963D: C8 - INY 963E: AE EC C0 - LDX $C0EC 9641: 10 FB - BPL $963E ; wait until iwm ready 9643: BD 00 94 - LDA $9400,X ; translate it 9646: A6 66 - LDX $66 ; QUART 9648: 1D 00 95 - ORA $9500,X ; decode with OCTET2 table 964B: 45 5C - EOR $5C ; EOR with CHK1 964D: 97 18 - STA [$18],Y ; store at address pointed to by PNT1 964F: 65 5E - ADC $5E ; add CHK3 9651: 85 5E - STA $5E ; save CHK3 9653: C8 - INY 9654: AE EC C0 - LDX $C0EC 9657: 10 FB - BPL $9654 ; wait until iwm ready 9659: BD 00 94 - LDA $9400,X ; translate it 965C: A6 66 - LDX $66 ; QUART 965E: 1D 40 95 - ORA $9540,X ; decode with OCTET3 table 9661: 45 5E - EOR $5E ; EOR with CHK3 9663: 97 18 - STA [$18],Y ; store at address pointed to by PNT1 9665: 65 5D - ADC $5D ; add CHK2 9667: 85 5D - STA $5D ; save CHK2 9669: C8 - INY 966A: AE EC C0 - LDX $C0EC 966D: 10 FB - BPL $966A ; wait until iwm ready 966F: BD 00 94 - LDA $9400,X ; translate it 9672: A6 66 - LDX $66 ; QUART 9674: 1D 80 95 - ORA $9580,X ; decode with OCTET4 table 9677: 45 5D - EOR $5D ; EOR with CHK2 9679: 97 18 - STA [$18],Y ; store at address pointed to by PNT1 967B: 65 5C - ADC $5C ; add CHK1 967D: 85 5C - STA $5C ; save CHK1 967F: AE EC C0 - LDX $C0EC 9682: 10 FB - BPL $967F ; wait until iwm ready 9684: BD 00 94 - LDA $9400,X ; translate it 9687: 85 66 - STA $66 ; QUART 9689: 06 5C - ASL $5C ; multiply with CHK1 968B: 90 02 - BCC $968F ; no need to inc CHK1? 968D: E6 5C - INC $5C 968F: C8 - INY 9690: D0 AC - BNE $963E ; loop for 255 octets ; read and decode octets 256 through 510 9692: C8 - INY 9693: AE EC C0 - LDX $C0EC 9696: 10 FB - BPL $9693 ; wait until iwm ready 9698: BD 00 94 - LDA $9400,X ; translate it 969B: A6 66 - LDX $66 ; QUART 969D: 1D 00 95 - ORA 9500,X ; decode with OCTET2 table 96A0: 45 5C - ORA $5C ; EOR with CHK1 96A2: 97 1C - STA [$1C],Y ; store at address pointed to by PNT2 (PNT1 + 254) 96A4: 65 5E - ADC $5E ; add CHK3 96A6: 85 5E - STA $5E ; save CHK3 96A8: C8 - INY 96A9: AE EC C0 - LDX $C0EC 96AC: 10 FB - BPL $96A9 ; wait until iwm ready 96AE: BD 00 94 - LDA $9400,X ; translate it 96B1: A6 66 - LDX $66 ; QUART 96B3: 1D 40 95 - ORA $9540,X ; decode with OCTET3 table 96B6: 45 5E - EOR $5E ; EOR with CHK3 96B8: 97 1C - STA [$1C],Y ; store at [PNT2] 96BA: 65 5D - ADC $5D ; add CHK2 96BC: 85 5D - STA $5D ; save CHK2 96BE: C8 - INY 96BF: AE EC C0 - LDX $C0EC 96C2: 10 FB - BPL $96BF ; wait until iwm ready 96C4: BD 00 94 - LDA 9400,X ; translate it 96C7: A6 66 - LDX $66 ; QUART 96C9: 1D 80 95 - ORA $9580,X ; decode with OCTET4 table 96CC: 45 5D - EOR $5D ; EOR with CHK2 96CE: 97 1C - STA [$1C],Y ; store at [PNT2] 96D0: 65 5C - ADC $5C ; add CHK1 96D2: 85 5C - STA $5C ; save CHK1 96D4: AE EC C0 - LDX $C0EC 96D7: 10 FB - BPL $96D4 ; wait until iwm ready 96D9: BD 00 94 - LDA $9400,X ; translate it 96DC: 85 66 - STA $66 ; QUART 96DE: 06 5C - ASL $5C ; multiply with CHK1 96E0: 90 02 - BCC $96E4 ; branch if we don't have to increment 96E2: E6 5C - INC $5C 96E4: C8 - INY 96E5: D0 AC - BNE $9693 ; loop for octets 256 - 510 ; get octets 511 and 512 96E7: AE EC C0 - LDX $C0EC 96EA: 10 FB - BPL $96E7 ; wait until iwm ready 96EC: BD 00 94 - LDX $9400,X ; translate it 96EF: A6 66 - LDX $66 ; QUART 96F1: 1D 00 95 - ORA $9500,X ; decode with OCTET2 table 96F4: 45 5C - EOR $5C ; EOR with CHK1 96F6: 97 F0 - STA [$F0],Y ; store at [PNT3] (PNT1+510) 96F8: 65 5E - ADC $5E ; add CHK3 96FA: 85 5E - STA $5E ; store CHK3 96FC: C8 - INY 96FD: AE EC C0 - LDX $C0EC 9700: 10 FB - BPL $96FD ; wait until iwm ready 9702: BD 00 94 - LDA $9400,X ; translate it 9705: A6 66 - LDX $66 ; QUART 9707: 1D 40 95 - ORA $9540,X ; decode with OCTET3 table 970A: 45 5E - EOR $5E ; EOR with CHK3 970C: 97 F0 - STA [$F0],Y ; store at [PNT3] 970E: 65 5D - ADC $5D ; add CHK2 9710: 85 5D - STA $5D ; save CHK2 ; verify block checksum 9712: AE EC C0 - LDX $C0EC 9715: 10 FB - BPL $9712 ; wait until iwm ready 9717: BD 00 94 - LDA $9400,X ; translate it 971A: AA - TAX 971B: BD 80 95 - LDA $9580,X ; decode with OCTET4 table 971E: 85 66 - STA $66 ; store at QUART 9720: BD 40 95 - LDA $9540,X ; decode with OCTET3 table 9723: 85 67 - STA $67 ; store at QUART+1 9725: BD 00 95 - LDA $9500,X ; decode with OCTET3 table 9728: A2 02 - LDX #$AC 972A: AC EC C0 - LDY $C0EC 972D: 10 FB - BPL $972A ; wait until iwm ready 972F: 29 C0 - AND #$C0 9731: 19 00 94 - ORA $9400,Y ; translate it 9734: D5 5C - CMP $5C,X ; compare checksum 9736: D0 16 - BNE $974E ; branch out if error 9738: B5 65 - LDA $65,X ; QUART-1 973A: CA - DEX 973B: 10 ED - BPL $972A ; get the end of track data mark: AA DE 973D: A2 02 - LDX #02 973F: AD EC C0 - LDA $C0EC 9742: 10 FB - BPL $97EF ; wait until iwm ready 9744: DD 89 94 - CMP $9489,X ; FINDATA-1 9747: D0 05 - BNE $974E 9749: CA - DEX 974A: D0 F3 - BNE $973F 974C: 18 - CLC 974D: 60 - RTS ; error return 974E: 38 - SEC 974F: 60 - RTS ; ENTER ; Entry point ; this is called with data bank $E1 ; with 3.5" drive already selected 9750: C2 30 - REP #$30 9752: AE 28 0F - LDX $0F28 ; $E10F28 9755: BD EA C0 - LDA $C0EA,X 9758: AD E9 C0 - LDA $C0E9 975B: 64 FF - STZ $FF ; TEST 975D: 64 AF - STZ $AF ; DRIVEOK ; track by track analysis to find position 975F: C2 20 - REP #$20 9761: 64 F6 - STZ $F6 ; PISTEUR (tracker) 9763: 64 49 - STZ $F9 ; POINTEUR 9765: A9 30 00 - LDA #$0030 9768: 85 FC - STA $FC ; PAS 976A: A6 FC - LDX $F6 976C: E2 20 - SEP #$20 976E: BF 05 A5 00 - LDA $00A505,X ; PISTES table 9772: F0 11 - BEQ $9785 ; not one we want? then branch out 9774: A5 F6 - LDA $F6 9776: 4A - LSR 9777: 8D 29 0F - STA $0F29 ; actual physical track 977A: A9 00 6A - LDA #$6A00 977D: 8D 2B 0F - STA $0F2B ; side number? 9780: 20 99 98 - JSR $9899 ; PISTE 9783: B0 66 - BCS $97EB ; performs a few things (notably "AND NOW, FTA PRESENTS..") while blocks are being loaded 9785: A5 AF - LDA $AF 9787: 30 40 - BMI $97C9 9789: E6 AF - INC $AF 978B: A5 AF - LDA $AF 978D: C9 06 D0 - CMP #$06 978F: D0 05 - BNE $9796 9791: 20 8C 9D - JSR $9D8C 9794: 80 33 - BRA $97C9 9796: C9 07 - CMP #07 9798: D0 08 - BNE $97A8 979A: 9C 22 C0 - STZ $C022 979D: 20 40 A0 - JSR $A040 97A0: 80 27 - BRA $97C9 97A2: C9 07 - CMP #$07 97A4: 90 23 - BCC $97C9 97A6: AD CA 00 - LDA $00CA 97A9: A9 0F - AND #$0F 97AB: 8D 3C C0 - STA $C03C 97AE: A9 A0 - LDA #$A0 97B0: 8D 3E C0 - STA $C03E 97B3: AD 3D C0 - LDA $C03D 97B6: AD 3D C0 - LDA $C03D 97B9: 89 01 - BIT #$01 97BB: F0 0C - BEQ $97C9 97BD: A2 00 - LDX #00 97BF: 20 36 A1 - JSR $A136 97C2: 20 00 65 - JSR $5800 97C5: A9 FF - LDA #$FF 97C7: 85 AF - STA $AF 97C9: C2 30 - REP #$20 97CB: A5 F9 - LDA $F9 ; POINTEUR 97CD: 18 - CLC 97CE: 65 FC - ADC $FC ; PAS 97D0: 85 F9 - STA $F9 97D2: E6 F6 - INC $FC 97D4: A5 F6 - LDA $F6 ; PISTEUR 97D6: 29 1F 00 - AND #$001F 97D9: D0 8F - BNE $976A 97DB: E6 FF - INC $FF ; TEST 97DD: A5 FC - LDA $FC ; PAS 97DF: 38 - SEC 97E0: E9 04 00 - SBC #$0004 97E3: 85 FC - STA $FC ; PAS 97E5: C9 1C 00 - CMP #$001C ; finished with 160 tracks? 97E8: D0 80 - BNE $976A 97EA: 18 - CLC ; RETOURAGA - return in ROM to an RTS 97EB: E2 30 - SEP #$30 97ED: 5C E1 02 FF - JMP $FF02D1 ; $021D written by $9804 ; entry from $9AD8 ; PREINIT - find a $60 (RTS) to return in ROM 97F1: 08 - PHP 97F2: C2 30 - REP #$30 97F4: E2 20 - SEP #$20 97F6: A2 00 00 - LDX #0000 97F9: BF 00 00 FF - LDA $FF0000,X 97FD: C9 60 - CMP #$60 97FF: F0 03 - BEQ $9804 9801: E8 - INX 9802: 80 F5 - BRA $97F9 9804: 8E EE 97 - STX $97EE ; X should be $021D, where first $60 is in bnk $FF ; $97EE = $021D ; VRTS+1 ; create a table to operation on blocks, at a cost of 6560 bytes 9807: A2 00 00 - LDX #0000 980A: 64 51 - STZ $51 ; UT4 980C: A9 0C - LDA #$0C 980E: 85 4E - STA $4E ; UT1 9810: A9 20 - LDA #$20 9812: 85 4F - STA $4F ; UT2 9814: A5 4E - LDA $4E 9816: 85 50 - STA $50 ; UT3 9818: A9 FF - LDA #$FF 981A: 9D A7 A5 - STA $A5A7,X ; buffer+2,X 981D: A5 51 - LDA $51 981F: 9D A8 A5 - STA $A5A8,X ; buffer+3,X 9822: E8 - INX 9823: E8 - INX 9824: E8 - INX 9825: E8 - INX 9826: C6 50 - DEC $50 9828: D0 EE - BNE $9818 982A: E6 51 - INC $51 982C: C6 4F - DEC $4F 982E: D0 E4 - BNE $9814 9830: C6 4E - DEC $4E 9832: A5 4E - LDA $4E 9834: C9 07 - CMP #$07 9836: D0 D8 - BNE $9810 ; zero-out the table of tracks 9838: A2 A0 00 - LDA #$00A0 983B: 93 05 A5 - STZ $A505,X 983E: CA - DEX 983F: 10 FA - BPL $983B 9841: 28 - PLP 9842: 60 - RTS ; smartport firmware changing 9843: 8D 78 98 - STA $9878 ; DEVICE variable 9846: C2 30 - REP #$30 9848: A9 00 00 - LDA #0000 984B: 8F 91 0F E1 - STA $E10F91 ; divert this vector 984F: A9 50 97 - LDA #$9750 9852: 8F 90 0F E1 - STA $E10F90 ; so disk reads go to our new ENTER vector 9856: 38 - SEC 9857: FB - XCE 9858: E2 30 - SEP #30 985A: 20 0D C5 - JSR $C50D 985D: 03 - db 03 ; command: format 985F: 77 98 - dw $9877 ; DATA2 9860: 08 - PHP 9861: 18 - CLC 9862: FB - XCE 9863: C2 30 - REP #$30 9865: AF 93 0F E1 - LDA $E10F8F+4 ; restore this vector 9869: 8F 8F 0F E1 - STA $E10F8F 986D: AF 95 0F E1 - LDA $E10F91+4 9871: 8F 91 0F E1 - STA $E10F91 9875: 28 - PLP 9876: 60 - RTS ; DATA2 9877: 01 - db 01 ; command ; DEVICE 9878: 01 - db 01 ; device number - db C8,00 ; no effect - db 00,00,00 ; ... ; add blocks/addresses to the list of things to load 987E: 0A - ASL 987F: 0A - ASL 9880: 48 - PHA 9881: 8A - TXA 9882: FA - PLX 9883: 9D A5 A5 - STA $A5A5,X 9886: 98 - TYA 9887: E2 20 - SEP #$20 9889: 9D A7 A5 - STA $A5A7,X 988C: BD A8 A5 - LDA $A5A8,X 988F: AA - TAX 9890: 1A - INC 9891: E2 30 - SEP #$30 9893: 9D 05 A5 - STA $A505,X 9896: C2 30 - REP #$30 9898: 60 - RTS ; ... 992B: 60 - RTS ; a lot of this section in LOADER.S appears to be disassembled smartport ROM ; set iwm for reading 992C: 2C EC 60 - BIT $C0EC 992F: 70 FB - BVS $992C ; wait for iwm 9931: AD EE C0 - LDA $C0EE 9934: AD EC C0 - LDA $C0EC ; set iwm for reading 9937: 18 - CLC 9938: 60 - RTS ... ; iwm stuff? 999E: 20 B2 99 - JSR $99B2 ; get drive status and control bits 99A1: 2C ED C0 - BIT $C0ED ; Q6+1 99A4: AD EE C0 - LDA $C0EE ; Q7 99A7: 60 - RTS ; iwm stuff? 99A8: 20 B2 99 - JSR $99B2 ; get drive status and control bits 99AB: 2C E7 C0 - BIT $C0E7 ; LSTRB+1 99AE: 2C E6 C0 - BIT $C0E6 ; LSTRB 99B1: 60 - RTS ; straight from IWM docs: get status and control bits for drive.. seek to track? 99B2: 2C E0 C0 - BIT $C0E0 ; CA0 set switches to known state 99B5: 2C E3 C0 - BIT $C0E3 ; CA1+1 99B8: 2C E6 C0 - BIT $C0E6 ; LSTRB 99BB: 2C E4 C0 - BIT $C0E4 ; CA2 99BE: 4A - LSR 99BF: 90 03 - BCC $99C4 99C1: 2C E5 C0 - BIT $C0E5 ; if bit 0 on, turn on CA2 99C4: 4A - LSR 99C5: 48 - PHA 99C6: AD 31 C0 - LDA $C031 ; DISKREG 99C9: 29 7F 90 - AND #7F ; if bit 1 off, turn off SEL 99CB: 90 02 - BCC 99CF 99CD: 09 80 - ORA #$80 ; else turn on SEL 99CF: 8D 31 C0 - STA $C031 ; DISKREG 99D2: 68 - PLA 99D3: 4A - LSR 99D4: 90 03 - BCC $99D9 99D6: 2C E1 0C - BIT $C0E1 ; CA0+1 - if bit 2 on, turn on CA0 99D9: 4A - LSR 99DA: B0 03 - BCS $99DF 99DC: 2C E2 C0 - BIT $C0E2 ; if bit 3 off, turn off CA1 99DF: 60 - RTS .. 9A49: A9 0B - LDA #0B ;9A4A: 0B - PHD 9A4B: 20 93 99 - JSR $999E ; start reading? 9A4E: 2C EE C0 - BIT $C0EE ; Q7 9A51: 30 FB - BMI $9A4E ; wait for iwm 9A53: 60 - RTS 9A54: A9 01 - LDA #$01 9A56: 2C 2B 0F - BIT $0F2B 9A59: 10 01 - BPL $9A5D 9A5B: A9 03 - LDA #$03 9A5D: 20 9E 99 - JSR $999E ; start reading? 9A60: AD EC C0 - LDA $C0EC 9A63: AD EC C0 - LDA $C0EC 9A66: 60 - RTS 9A67: 20 49 9A - JSR $9A49 9A6A: 20 54 9A - JSR $9A54 9A6D: A9 07 - LDA #$07 9A6F: 85 68 - STA $68 9A71: A0 9E - LDY #$9E 9A73: A2 02 - LDX #$02 9A75: 88 - DEY 0A76: D0 04 - BNE $9A7C 9A78: C6 68 - DEC $68 9A7A: 30 4B - BMI $9AC7 9A7C: AD EC C0 - LDA $C0EC 9A7F: 10 FB - BPL $9A7C ; wait for iwm 9A81: DD 69 0F - CMP $0F69,X 9484: D0 ED - BNE $9A73 9486: CA - DEX 9A87: 10 EC - BPL $9A75 9A89: A0 04 - LDY #$04 9A8B: 64 5B - STZ $5B 9A8D: AE EC C0 - LDX $C0EC 9A90: 10 FB - BPL $9A8D 9A92: BF 00 94 00 - LDA $009400,X 9A96: 99 30 0F - STA $0F30,Y 9A99: 45 5B - EOR $5B 9A9B: 85 5B - STA $5B 9A9D: 88 - DEY 9A9E: 10 ED - BPL $9A8D 9AA0: A8 - TAY 9AA1: D0 24 - BNE $9AC7 9AA3: AD EC C0 - LDA $C0EC 9AA6: 10 FB - BPL $9AA3 ; wait for iwm 9AA8: CD 63 0F - CMP $0F63 9AAB: D0 1A - BNE $9AC7 9AAD: AD EC C0 - LDA $C0EC 9AB0: 10 FB - BPL $9AAD 9AB2: CD 62 0F - CMP $0F62 9AB5: D0 10 - BNE $9AC7 9AB7: AE 28 0F - LDX $0F28 9ABA: AD 31 0F - LDA $0F31 9ABD: 0A - ASL 9ABE: 0A - ASL 9ABF: 0A - ASL 9AC0: 7E 24 0F - RAR $0F24,X 9AC3: A9 00 - LDA #$00 9AC5: 18 - CLC 9AC6: 60 - RTS 9AC7: A9 20 - LDA #$20 9AC9: 0C 44 0F - TSB $0F44 9ACC: 38 - SEC 9ACD: 60 - RTS ; end of apparently-disassembled-smartport-ROM bits ; FIRST_BLOCK (word) 9ACE: 00 00 - db 00,00 ; NB_BLOCK (word) 9AD0: 00 00 - db 00,00 ; ADRESSES (long) 9AD2: 00 00 - db 00,00 9AD4: 00 00 - db 00,00 ; Loader 9AD6: C2 30 - REP #$30 9AD8: 20 F1 97 - JSR $97F1 ; call PREINIT 9ADB: A9 AD 9B - LDA #9BAD ; SEGMENT2 9ADE: 20 6F 9C - JSR $9C6F ; Load_Segment 9AE1: 38 - SEC 9AE2: FB - XCE 9AE3: 20 0D C5 - JSR $C50D 9AE6: 04 - DB 04 9AE7: 90 A0 - DW $A090 ; disk eject params at $A090 9AE9: 18 - CLC 9AEA: FB - XCE 9AEB: C2 30 - REP #$30 9AED: A2 00 00 - LDX #0000 ; address in bank 9AF0: A9 0B 00 - LDA #$000B ; bank # 9AF3: 20 00 0A - JSR $0A00 ; call Decruncher 9AF6: A2 00 10 - LDX #$1000 9AF9: A9 00 00 - LDA #$0000 9AFC: 20 00 0A - JSR $0A00 ; call Decruncher 9AFF: A2 00 04 - LDX #$0400 9B02: A9 0A 00 - LDA #$000A 9B05: 20 00 0A - JSR $0A00 ; call Decruncher 9B08: 20 00 10 - JSR $1000 ; TODO what 9B0B: C2 30 - REP #$30 9B0D: A2 06 00 - LDX #$0006 9B10: 20 36 A1 - JSR $A136 ; TODO what 9B13: AF 35 C0 E1 - LDA $E1C035 9B17: 48 - PHA 9B18: 22 00 00 0B - JSL 0B0000 9B1C: 68 - PLA 9B1D: 09 10 80 - ORA #8010 9B20: 8F 35 C0 E1 - STA $E1C035 ; ... ; SEGMENT2 ; table of blocks to load at addresses 9BAD: 10 00 - DA $10 ; starting block 00 10 00 00 - ADRL $001000 ; address to load 74 00 00 00 - ADRL $000074 ; #blocks to load 00 80 0E 00 - ADRL $0E8000 04 00 00 00 - ADRL $000004 00 00 02 00 - ADRL $020000 34 00 00 00 - ADRL $000034 00 C0 06 00 - ADRL $06C000 1A 00 00 00 - ADRL $00001A 00 F8 02 00 - ADRL $02F800 06 00 00 00 - ADRL $000006 00 38 08 00 - ADRL $083800 12 00 00 00 - ADRL $000012 00 80 06 00 - ADRL $068000 20 00 00 00 - ADRL $000020 00 A0 02 00 - ADRL $02A000 0A 00 00 00 - ADRL $00000A 00 B0 02 00 - ADRL $02B000 10 00 00 00 - ADRL $000010 00 C0 02 00 - ADRL $02C000 0C 00 00 00 - ADRL $00000C 00 00 05 00 - ADRL $050000 36 00 00 00 - ADRL $000036 00 00 07 00 - ADRL $070000 0A 01 00 00 - ADRL $00010A 00 00 03 00 - ADRL $030000 B8 00 00 00 - ADRL $0000B8 00 50 08 00 - ADRL $085000 26 00 00 00 - ADRL $000026 00 00 0C 00 - ADRL $0C0000 04 02 00 00 - ADRL $000204 00 10 0E 00 - ADRL $0E1000 50 00 00 00 - ADRL $000050 00 A0 01 00 - ADRL $01A000 1A 00 00 00 - ADRL $00001A 00 80 08 00 - ADRL $088000 72 00 00 00 - ADRL $000072 00 10 00 00 - ADRL $001000 36 00 00 00 - ADRL $000036 00 00 09 00 - ADRL $090000 04 01 00 00 - ADRL $000104 00 04 0A 00 - ADRL $0A0400 0A 00 00 00 - ADRL $00000A 00 00 0F 00 - ADRL $0F0000 32 00 00 00 - ADRL $000032 00 00 0B 00 - ADRL $0B0000 0E 00 00 00 - ADRL $00000E ; break 00 00 00 00 - ADRL $000000 00 00 00 00 - ADRL $000000 ; Load_Segment ; A = $9BAD 9C6F: 85 00 - STA $00 ; $00 = $9BAD 9C71: B2 00 - LDA ($00) ; A = $0010 9C73: 8D CE 9A - STA $9ACE ; $9ACE = $0010 9C76: E6 00 - INC $00 9C78: E6 00 - INC $00 ; $00 = $9BAF 9C7A: A0 00 00 - LDY #0000 9C7D: 5A - PHY 9C7E: B1 00 - LDA ($00),Y ; Y=0, A=$1000 9C80: 8D D2 9A - STA $9AD2 ; $9AD2 = $1000 9C83: C8 - INY 9C84: C8 - INY 9C85: B1 00 - LDA ($00),Y ; Y=2, A=$0000 9C87: 8D D4 9A - STA $9AD4 ; $9AD4 = $0000 9C8A: C8 - INY 9C8B: C8 - INY 9C8C: B1 00 - LDA ($00),Y ; Y=4, A=$0074 9C8E: F0 2A - BEQ $9CBA ; done yet? 9C90: 4A - LSR 9C91: 8D D0 9A - STA $9AD0 ; $9AD0 = $0074/2 9C94: AD CE 9A - LDA $9ACE ; A = $0010 9C97: AE D2 9A - LDX $9AD2 ; X = $1000 9C9A: AC D4 9A - LDY $9AD4 ; Y = $0000 9C9D: 20 7E 98 - JSR $987E ; add to table of blocks to load at addresses 9CA0: AD D3 9A - LDA $9AD3 ; LDA $9AD3 9CA3: 18 - CLC 9CA4: 69 02 00 - ADC #$0002 9CA7: 8D D3 9A - STA $9AD3 9CAA: EE CE 9A - INC $9ACE 9CAD: CE D0 9A - DEC $9AD0 9CB0: D0 E2 - BNE $9C94 9CB2: 68 - PLA 9CB3: 18 - CLC 9CB4: 69 08 00 - ADC #$0008 9CB7: A8 - TAY 9CB8: 80 C3 - BRA $9C7D 9CBA: 68 - PLA 9CBB: A9 01 00 - LDA #$0001 9CBE: 20 43 98 - JSR $9843 ; call smartport 9CC1: E2 30 - SEP #$30 9CC3: 90 05 - BCC $9CCA 9CC5: A9 02 - LDA #$02 9CC7: 4C D1 9C - JMP $9CD1 ; branch if error 9CCA: 18 - CLC 9CCB: FB - XCE 9CCC: C2 30 - REP #$30 9CCE: 60 - RTS 9CCF: 00 00 - DB 00,00 ; something bad here: eject disk and show error 9CD1: 38 - SEC 9CD2: FB - XCE 9CD3: 4B - PHK 9CD4: AB - PLB 9CD5: 8D CF 9C - STA $9CCF 9CD8: 20 0D C5 - JSR $C50D 9CDB: 04 - DB 04 ; command: control 9CDC: 90 A0 - DW $A090 ; params at $A090 9CDE: 18 - CLC 9CDF: FB - XCE 9CE0: C2 30 - REP #$30 ; clear text screen to spaces 9CE2: A2 00 00 - LDX #0000 9CE5: A9 A0 A0 - LDA #A0A0 9CE8: 9D 00 04 - STA 0400,X 9CEB: 9F 00 04 01 - STA 010400,X 9CEF: E8 - INX 9CF0: E8 - INX 9CF1: E0 00 04 - CPX #0400 9CF4: D0 EF - BNE $9CE5 9CF6: 38 - SEC 9CF7: FB - XCE 9CF8: E2 30 - SEP #$30 9CFA: 8D 0F C0 - STA $C00F 9CFD: 8D 0D C0 - STA $C00D 9D00: AF DA 02 E1 - LDA $E102DA 9D04: 0A - ASL 9D05: 0A - ASL 9D06: 0A - ASL 9D07: 0A - ASL 9D08: 0F DB 02 E1 - ORA $E102DB 9D0C: 8D 22 C0 - STA $C022 ; restore text/background color 9D0F: AF DC 02 E1 - LDA $E102DC 9D13: 8D 34 C0 - STA $C034 .. ; set direct page to $C000 for DOC and IWM access via DP registers 9D8C: 08 - PHP 9D8D: 8B - PHB 9D8E: 0B - PHD 9D8F: 4B - PHK 9D90: AB - PLB 9D91: F4 00 C0 - PEA $C000 9D94: 2B - PLD ; direct page is $00/$C000 ! 9D95: C2 10 - REP #$10 9D97: E2 20 - SEP #$20 9D99: AF C0 00 E1 - LDA $E100CA 9D9D: 29 0F 09 - AND #$090F 9D9F: 60 - RTS ; this looks like DOC register inits with dp = $C000 9DA1: 85 3C - STA $3C 9DA3: 64 3E - STZ $3E 9DA5: 64 3F - STZ $3F ... ; $A090 smartport params (eject) A090: 03 - DB 03 A091: 01 - DB 01 A092: 00 00 - DW $0000 A094: 04 00 - DW $0004