Little Helper Tool

Started by LokalHorst, June 08, 2010, 09:36 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LokalHorst

This is only possible within C128 CP/M -> switch to a different CPU (in this specific case starting the build-in ML-Monitor)

As Commodore left out a lot of documentation, software regarding CP/M, I once started to explore this mode myself with the help of the following little program.
It can be used to transfer files from normal CBM disks to CP/M in combination with save.com (reduces TPA by 800h bytes) or the more advanced ddtz.com (uses 2200h bytes). You can load files to the TPA (bank1) from 10400 to 1e200 (save.com) or 1c800 (if ddtz.com is loaded).
You can move Z80 bios code to bank1 to examinate with ddtz etc. and with the monitor x command you're back in CP/M (get a CP/M mem map to know what is used)

The attachment contains utils to assemble/debug the following source code plus a working binary (tedmon.com):
Code (tedmon.mac) Select

.RADIX 16 ;all # in hex
.Z80
ASEG
ORG 0100
;
BDOS   EQU    00005
;
  JP   START
;
BIOJMP:            ;BIOS CALL VIA JMP-TABLE  A = BIOS FN * 3
  PUSH HL
  LD   HL,(00001)
  LD   L,A
  EX   (SP),HL
  RET
;
FN30:
  JP   0F05A       ;XBIOS SUBFUNCTION CALL    A = SUB FN
;
CHARSET:           ;temp. copied to the end of the cpu switch routine
  PUSH BC          ;RESTORES 80COL CP/M CHARSET
  PUSH DE         
  CALL 005BD
  POP  DE
  POP  BC
  RET
;
START:
  LD   HL,(00001)      ;adjust XBIOS jmp addr.
  LD   L,5A
  LD   (FN30 + 1),HL
BUGFIX:                ;bugfix for version 85 bios
  LD   DE,0262B        ;bank0 addr.
  XOR  A               ;0=byte read fn to reg C
  CALL FN30
  LD   A,0C3           ;wrong opcode Z80 JMP instead of 8502 JMP($xxxx)
  XOR  C               ;compare
  JR   NZ,NOBUG        ;skip if not equal
  LD   C,06C           ;else load correct value to C
  INC  A               ;1=byte write fn from reg C
  CALL FN30
NOBUG:                 ;disable irq
  DI
  LD   BC,0D01A        ;temp save vic irq reg
  IN   A,(C)
  PUSH AF
  LD   BC,00001        ;B=dest. bank  C=src. bank
  LD   A,057           ;bios XMOVE
  CALL BIOJMP          ;set banks for the next move call
  LD   BC,00080        ;# byte count
  LD   DE,00180        ;src. addr.
  LD   HL,02A80        ;dest. addr.
  LD   (0FD05),HL      ;start addr. for the USR-Jump function
  LD   A,04B           ;bios MOVE
  CALL BIOJMP          ;copy the 8502 code block to bank0
  LD   BC,START - CHARSET
  LD   DE,0FFEE
  LD   HL,CHARSET
  LDIR                 ;temp copy charset reload call to the switch rout.
  LD   L,009           ;Bios8502 subfunction 9=USR-Jump via ($fd05)
  LD   A,004           ;XBIOS subfunction 4=call bios8502
  CALL FN30            ;execute custom 8502 code
  LD   A,0C9           ;restore default opcode (Z80 RET) in switch rout.
  LD   (0FFEE),A
  LD   BC,0D01A        ;restore vic irq reg
  POP  AF
  OUT  (C),A
  DEC  C
  OUT  (C),A           ;clear irq req. reg
  EI                   ;enable irq
  LD   E,01A           ;clr screen
  LD   C,002
  CALL BDOS
  JP   00000           ;return to CP/M
;
DS 80 - ($ AND 07F) ;align to record boundary
;
; the following code is transfered to bank0 at $2a80 before execution
;
DB  0A9,000      ;$2A80: LDA #$00   enable roms (bank15)
DB  08D,000,0FF  ;       STA $FF00
DB  0A9,004      ;       LDA #$04   set 1k common ram at $0000-$03ff
DB  08D,006,0D5  ;       STA $D506
DB  0A9,0C6      ;       LDA #$C6   new irq addr. ($2ac6)
DB  0A2,02A      ;       LDX #$2A
DB  08D,014,003  ;       STA $0314
DB  08E,015,003  ;       STX $0315
DB  0A9,0D2      ;       LDA #$D2   return addr. for monitor 'x' cmd ($2ad2)
DB  08D,000,00A  ;       STA $0A00
DB  08E,001,00A  ;       STX $0A01
DB  0A9,07F      ;       LDA #$7F   disable timer irq
DB  08D,00D,0DC  ;       STA $DC0D
DB  0AD,00D,0DC  ;       LDA $DC0D
DB  020,0B6,077  ;       JSR $77B6  fast mode on
DB  08D,012,0D0  ;       STA $D012  enable raster irq
DB  08D,01A,0D0  ;       STA $D01A
DB  0CE,019,0D0  ;       STA $D019
DB  024,0D7      ;       BIT $D7    80col active ?
DB  030,003      ;       BMI $2AB7  skip if yes
DB  020,05F,0FF  ;       JSR $FF5F  switch 40->80col
DB  020,062,0FF  ;$2AB7: JSR $FF62  load default vdc charset
DB  0AD,015,024  ;       LDA $2415  80col attribute (CP/M)
DB  085,0F1      ;       STA $F1
DB  020,042,0C1  ;       JSR $C142  editor init
DB  04C,000,0B0  ;       JMP $B000  start monitor
DB  000
;
DB  020,012,0C0  ;$2AC6: JSR $C012  keyboard scan
DB  020,03D,0F6  ;       JSR $F63D  run/stop key check
DB  0CE,019,0D0  ;       DEC $D019  clr raster irq
DB  04C,033,0FF  ;       JMP $FF33  end irq
;
DB  0A5,0D5      ;$2AD2: LDA $D5    wait until no key pressed
DB  049,058      ;       EOR #$58
DB  0D0,0FA      ;       BNE $2AD2
DB  078          ;       SEI
DB  08D,030,0D0  ;       STA $D030  slow mode
DB  08D,01A,0D0  ;       STA $D01A  disable raster irq
DB  085,09D      ;       STA $9D
DB  020,021,0CB  ;       JSR $CB21  cursor off
DB  0A9,00A      ;       LDA #$0A   set 4k common ram at $e000-$ffff
DB  08D,006,0D5  ;       STA $D506
DB  0AD,018,003  ;       LDA $0318  restore irq vector
DB  0AE,019,003  ;       LDX $0319
DB  08D,014,003  ;       STA $0314
DB  08E,015,003  ;       STX $0315
DB  08D,001,0FF  ;       STA $FF01  bank0 no rom
DB  0AD,0DE,0FF  ;       LDA $FFDE  hi byte of bios 8502 entry
DB  048          ;       PHA
DB  0A9,005      ;       LDA #$05   lo offset-1
DB  048          ;       PHA
DB  060          ;       RTS        return to bios
;
END


..LH