home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
No Fragments Archive 10: Diskmags
/
nf_archive_10.iso
/
MAGS
/
DNTPAPER
/
DNT_04.MSA
/
ARCHIVES.DNT
/
SOURCES.ZIP
/
MONOEMUL
/
MONO_EMU.S
< prev
Wrap
Text File
|
1992-12-11
|
11KB
|
257 lines
OUTPUT mono_emu.prg
; The Auto Mono Emulator. V5.00 By Mick West. November 20th 1988.
; Routine to make the ST think it is in mono mode. Needs TOS in ROM
; Makes the system think that there is a mono screen, but actually
; be updating a medium real screen from this under Vblank interrupt
; The XBIOS calls; Physbase,Setscreen and Getrez are revectored.
; Put in an Auto Folder
; Works with any TOS in the entire world - hopefully
MOVE.L 4(A7),A0
MOVE.L #$8400,D6 ; 32K for the screen
ADD.L $C(A0),D6 ; plus the usual space
ADD.L $14(A0),D6
ADD.L $1C(A0),D6
MOVE.L D6,-(SP) ; save length of program for later
MOVE.W #4,-(SP)
TRAP #14 ; Get screen Resolution
ADDQ.L #2,SP
CMP.W #2,D0 ; If not high then carry on
BNE NOTHIGH
MOVE.L (SP)+,D6 ; else tidy up the stack
MOVE.W #0,-(SP) ; return ok to,GEM
TRAP #1 ; Then exit back to desktop
NOTHIGH:
CLR.L -(SP)
MOVE.W #32,-(SP)
TRAP #1 ; Enter supervisor mode
ADDQ.L #6,SP
MOVE.L D0,SAVESTACK ; Save the supervisor stack
MOVE.L #MESSAGE,-(SP) ; Address of start of message
MOVE.W #9,-(SP) ; Print startup message
TRAP #1
ADDQ.L #6,SP
INLOOP:
MOVE.L #INPUT,-(SP)
MOVE.W #9,-(SP) ; Print input message
TRAP #1
ADDQ.L #6,SP
MOVE.B #3,MESSAGE ; Input length = 3
MOVE.L #MESSAGE,-(SP)
MOVE.W #10,-(SP)
TRAP #1 ; Input number
ADDQ.L #6,SP
MOVE.W #40,D0 ; Default = 40
TST.B MESSAGE+1
BEQ DEFAULT ; If len=0
CMP.B #1,MESSAGE+1 ; len of 1 not allowed
BEQ INLOOP
CLR.W D0
MOVE.B MESSAGE+2,D0 ; first digit
SUB.W #48,D0
BLE INLOOP ; Too low
CMP.W #9,D0
BGT INLOOP ; Too High (>100)
MULU #10,D0
CLR.W D1
MOVE.B MESSAGE+3,D1 ; second digit
SUB.W #48,D1
BLT INLOOP ; Too low
CMP.W #9,D1
BGT INLOOP ; Too high
ADD.W D1,D0
CMP.W #80,D0
BGT INLOOP ; Check less than 80
DEFAULT:
MOVE.W D0,SCANPOKE+2
SUB.L A5,A5
MOVE.L $044E(A5),MED ; Set MED
MOVE.L $B8,XBIOSPOKE+2 ; Get the old XBIOS address and
MOVE.L $70,VBLANKPOKE+2 ; VBLANK and insert into new versions
MOVE.L #0,MONOPOS ; Set offset to top of screen
SCANPOKE:
MOVE.W #40,MONOLINES ; Fourty lines per Vblank is default
MOVE.W #0,MONOCOUNT ; Counter is set to zero
LEA XEND,A2 ; A2 = pos of generated code
LEA GEN,A1 ; A1 = pos of instructions to copy
MOVE.W #39,D0 ; Generate the code
GENMOVE1:
MOVE.L (A1),(A2)+ ; Copys 40 of - MOVE.W (A0)+,(A1)+
DBF D0,GENMOVE1 ; and MOVE.W (A2)+,(A1)+
ADDQ.L #4,A1
MOVE.W (A1),(A2)+ ; Move the RTS
MOVE.L A2,D0 ; A2 = start of free memory
ADD.L #512,D0 ; Force it to a 512 byte boundry
AND.L #$FFFFFE00,D0
MOVE.L D0,$044E(A5) ; And that is the monochrome screen
MOVE.L D0,MONO ; Set MONO
MOVE.W #$0002,-(SP) ; Hardware and Software to Mono
MOVE.L #-1,-(SP)
MOVE.L #-1,-(SP)
MOVE.W #5,-(SP)
TRAP #14 ; Set high resolution
ADD.L #12,SP
MOVE.L $70,A0 ; Save the old VBLANK
MOVE.L #SIMPLE_VBLANK,$70 ; And set up mine
MOVE.W #1,RASTER_FLAG ; Set raster flag to 'not occured yet'
WAIT_RASTER
TST.W RASTER_FLAG ; If still not occured
BNE WAIT_RASTER ; then loop until a vbl does occur
MOVE.B #1,$FF8260 ; Back to medium hardware after VBL
MOVE.L A0,$70
MOVE.L #XBIOS,$B8 ; Set up the new XBIOS vector
MOVE.L #VBLANK,$70 ; And the new VBLANK vector
MOVE.L SAVESTACK,-(SP) ; Restore the Supervisor stack
MOVE.W #32,-(SP) ; And go back to User mode
TRAP #1
ADDQ.L #6,SP
MOVE.L (SP)+,D0 ; Tidy stack
CLR.W -(SP) ; Exit ok for GEM
MOVE.L D0,-(SP) ; Length of program + data space
MOVE.W #$31,-(SP) ; terminate and stay resident (TSR)
TRAP #1 ; Finished this AUTO program
; This is the new XBIOS routine
XBIOS:
MOVEM.L A1/A2,-(SP) ; Save A1 and A2
MOVE.L SP,A2 ; A2 = the stack
ADD.L #8,A2 ; offset over A1 and A2
BTST #5,(A2) ; Test if called from user mode
BNE NOTUSER ; Skip if it is
MOVE.L USP,A2 ; Otherwise get A2 = User stack
SUB.L #6,A2 ; Offset it as if it were the SSP
NOTUSER:
MOVE.W $6(A2),D0 ; Get XBIOS instruction code
CMP.W #2,D0 ; If it is _PHYSBASE
BEQ PHYSBASE ; then jump to new PHYSBASE routine
CMP.W #4,D0 ; If it is _GETREZ
BEQ GETREZ ; then jump to new GETREZ routine
CMP.W #5,D0 ; If it is NOT _SETSCREEN
BNE NORM_XBIOS ; Then continue with the normal XBIOS
MOVE.W #-1,16(A2) ; Else alter rez.W to -1 (No change)
MOVE.L 12(A2),D0 ; Get the ploc.L parameter
CMP.L #-1,D0 ; If it is -1
BEQ NORM_XBIOS ; then continue with normal XBIOS
MOVE.L D0,MONO ; Otherwise, new value goes to MONO
MOVE.L #-1,12(A2) ; Set ploc.L to -1 (no change)
BRA NORM_XBIOS ; then norm BIOS deals with lloc.L
PHYSBASE:
MOVE.L MONO,D0 ; Get address of mono screen
MOVEM.L (SP)+,A1/A2 ; Tidy stack
RTE ; Return mono screen location
GETREZ:
MOVE.W #2,D0 ; Pretend we are in mono resolution
MOVEM.L (SP)+,A1/A2 ; Tidy the stack
RTE ; Return code for mono resolution
NORM_XBIOS:
MOVEM.L (SP)+,A1/A2 ; Tidy the stack up
XBIOSPOKE:
JMP $0.L ; And jump into the normal XBIOS
; This is the new VBLANK routine
VBLANK:
MOVEM.L D0-D7/A0-A6,-(SP) ; Save all registers
MOVE.W #$333,$FF8242 ; Set up colours, grey for thin lines
MOVE.W #$333,$FF8244 ; (1 vert mono pixel = 1 grey med pix)
BTST #0,$FF8240 ; Check inverted
BEQ INVERT ; Jump if so
MOVE.W #$777,$FF8240 ; White background (normal)
MOVE.W #$000,$FF8246 ; Black ink
BRA NOINVERT
INVERT:
MOVE.W #$000,$FF8240 ; Black background (inverted)
MOVE.W #$777,$FF8246 ; White ink
NOINVERT:
CLR.L D0
MOVE.B $FF8201,D0 ; Video base high
LSL.L #8,D0 ; times 256
MOVE.B $FF8203,D0 ; Plus video base low
LSL.L #8,D0 ; All times 256
MOVE.L D0,A3 ; Is the address of the Real screen
MOVE.L MONO,A0 ; A0 = virtual mono screen
MOVE.L MED,A1 ; A1 = real medium screen
CMP.L A1,A3 ; Check if the real screen has moved
BEQ MEDOK ; Skip this if not
MOVE.L A3,A0 ; Get the new real screen address
MOVE.L A0,MONO ; Set MONO From this
MOVE.L A1,D0 ; And put the real screen back
LSR.L #8,D0 ; to its origional position
MOVE.B D0,$FF8203
LSR.L #8,D0
MOVE.B D0,$FF8201
MEDOK:
MOVE.L A0,A2 ; A2 = mono start
ADD.L #80,A2 ; plus 80, on to next line
MOVE.L MONOPOS,D2 ; Get position in the screen RAM
ADD.L D2,A0 ; Offset position in mono screen
ADD.L D2,A2 ; And the other mono position
ADD.L D2,A1 ; Offset pos in real medium screen
MOVE.W #20,D1 ; default 20 lines / Vblank
TST.B $43E ; Test flock system variable
BNE COPYMOVE ; Set speed to 20 if using disk drive
MOVE.W MONOLINES,D1 ; Otherwise get preset speed
COPYMOVE:
BSR XEND ; combine and move two mono lines
ADD.L #80,A0 ; both need moving down another line
ADD.L #80,A2 ; in the mono screen
ADD.L #160,MONOPOS ; move down one medium/two mono lines
ADD.W #1,MONOCOUNT ; count medium lines dome
CMP.W #200,MONOCOUNT ; Done 200 medium/ 400 mono ?
BNE NOT200 ; if not then skip
MOVE.L #0,MONOPOS ; otherwise reset ram offset
SUB.L #32000,A0 ; MONO position back to top of screen
SUB.L #32000,A1 ; and the same for MEDIUM
SUB.L #32000,A2 ; and the other MONO position
MOVE.W #0,MONOCOUNT ; reset the counter
NOT200:
DBF D1,COPYMOVE ; loop round MONOLINES times
VBLEXIT:
MOVEM.L (SP)+,D0-D7/A0-A6 ; Restore all registers
VBLANKPOKE:
JMP $0.L ; Jump to normal VBLANK routine
; This is a simple Vblank routine that just clears a flag
SIMPLE_VBLANK
CLR.W RASTER_FLAG ; Indicate a Vertical blank has occured
RTE
; The following bits of code are not called but are used to calculate
; a large chunk of code to combine two mono lines into one medium one.
GEN:
MOVE.W (A0)+,(A1)+ ; Move one Mono line to one Medium
MOVE.W (A2)+,(A1)+ ; line on both colour planes times 40
RTS
EVEN
SAVESTACK: DC.L 0
MONO: DC.L 0 ; Base address of mono screen
MED: DC.L 0 ; Base address of medium screen
MONOPOS: DC.L 0 ; Offset in both screens in bytes
MONOLINES: DC.L 0 ; Pairs of mono lines to do per VBLANK
MONOCOUNT: DC.L 0 ; Count of pairs done so far
RASTER_FLAG: DC.W 0 ; Flag cleared every raster (tempory)
XEND: nop ; Position of calculated code
MESSAGE:
DC.B 27,'E','The Mono Emulator - Mick West 1988',13,10
DC.B 'V5.00. Should be in AUTO Folder',13,10
DC.B 'Will run with any TOS',13,10,13,10
DC.B 'This is Shareware',13,10
DC.B 'Send Money and Problems to:',13,10
DC.B 'Mick West',13,10
DC.B '27 Lynton Drive,',13,10
DC.B 'Shipley,',13,10
DC.B 'BD18 3DJ',13,10
DC.B 'ENGLAND',13,10,13,10
DC.B 'Feel free to give away copies of this',13,10
DC.B 'But please copy the whole folder',13,10,13,10,0
INPUT:
DC.B 13,10
DC.B 'Enter speed (10 to 80, Return = 40) ',0