English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 09 May 2017, 07:14   #1
LuigiThirty
Registered User
 
Join Date: Dec 2016
Location: USA
Posts: 101
Amiga 'Jumpstart' example?

I found an old Stackoverflow post about writing a 68K operating system as an educational exercise. Someone suggested using the Amiga hardware as a base since it's pretty easy to work with and well-documented since everyone twiddles the hardware directly to do anything cool anyway. It seems like a fun little project.

It can be easily done by writing a replacement ROM and loading it into WinUAE as the boot ROM. Unfortunately the example code in the link on that page (which blinks the power LED and plays with the screen colors) seems to have disappeared. Long shot, but did anyone here save a copy of it?
LuigiThirty is offline  
Old 09 May 2017, 18:45   #2
paraj
Registered User
 
paraj's Avatar
 
Join Date: Feb 2017
Location: Denmark
Posts: 1,099
I don't have the original code, but the following should do the same:
Code:
; Assemble with vasm -phxass -x -Fbin -o rom.bin rom.s
; Supply rom.bin to Winuae with e.g. -s kickstart_rom_file="%CD%\rom.bin"

        org $fc0000             ; System ROM image location

custom=$dff000
bplcon0=$100
color00=$180
ciaa=$bfe001
pra=$000
ddra=$200

        ; The ROM is mapped at $000000 on startup shadowing RAM
rom_start:
        dc.l    0               ; Initial SP
        dc.l    rom_code        ; Initial PC
rom_code:
        move.l  #custom, a0     ; a0 = custom
        move.l  #ciaa, a1       ; a1 = ciaa
        move.b  #3, ddra(a1)    ; Set port A direction to output for /LED and OVL
        move.b  #0, pra(a1)     ; Disable OVL (Memory from $0 onwards available)
        move.w  #1<<9, bplcon0(a0) ; BPU=0, COLOR=1
.l:
        bchg.b  #1, pra(a1)     ; Blink LED
        move.w  d0, color00(a0) ; Change background color
        addq.w  #1, d0
        moveq   #-1, d1
.delay: dbf     d1, .delay
        bra.s   .l
EDIT: Since most people would probably want to do their code in C in this case here's anexample of how that could be done using vasm/vbcc/vlink (NOTE: I'm going for minimalism so there's some bad style):

Code:
; init.s
        XREF _kmain

        section init,code

ciaa=$bfe001
pra=$000
ddra=$200

        ; The ROM is located at $fc0000 but is mapped at $000000 afer reset shadowing RAM
rom_start:
        dc.l    $10000          ; Initial SP
        dc.l    rom_code        ; Initial PC
rom_code:
        move.b  #3, ciaa+ddra   ; Set port A direction to output for /LED and OVL
        move.b  #0, ciaa+pra    ; Disable OVL (Memory from $0 onwards available)
        jmp     _kmain
Code:
/* boot.c */
typedef unsigned char  UBYTE;
typedef unsigned short UWORD;
typedef unsigned long  ULONG;

#define COLORS ((volatile UWORD*)0xdff180)
#define VPOS ((*((volatile ULONG*)0xdff004) >> 8) & 0x1ff)
#define CIAAPRA *((volatile UBYTE*)0xbfe001)

void kmain(void) {
    for (unsigned short c=0;;++c) {
        // Blink LED every 16th frame
        if ((c&15)==0) CIAAPRA ^= 2;
        // Change background color
        COLORS[0] = c;
        // Wait for VBLANK
        while (VPOS != 10)
            ;
        while (VPOS == 10)
            ;
    }
}
Code:
/* rom.ld */
SECTIONS {
    . = 0xfc0000; /* System ROM image location */
    .everything: {
        *(init)
        *(CODE)
        *(DATA)
        *(BSS)
    }
}
Compile, assemble & link:
Code:
vbccm68k.exe -c99 -warn=-1 -dontwarn=168 -dontwarn=81 -maxerrors=0 -speed -O=1023 -o=boot.s boot.c
vasmm68k_mot_win32.exe -phxass -x -Fhunk -o init.o init.s
vasmm68k_mot_win32.exe -phxass -x -Fhunk -o boot.o boot.s
vlink.exe -Trom.ld -brawbin1 -o rom.bin init.o boot.o
Note: Placing DATA/BSS in ROM is a bad idea so it'll need some work before running larger code samples

Last edited by paraj; 09 May 2017 at 21:20.
paraj is offline  
Old 09 May 2017, 21:35   #3
Leo24
Registered User
 
Join Date: May 2017
Location: Sao Paulo
Posts: 17
Hi guys. Additionally, if you plan to use interrupt routines, make sure that the binary image is exact 256K or 512K and the last 7 words in "ROM" are "0019 001a 001b 001c 001d 001e 001f":
At offsets $3fff0 - $3ffff for a 256K ROM.
At offsets $7fff0 - $7ffff for a 512K ROM.

Otherwise exception handling will not work as expected.
Not sure how to define that in the linker script.
Leo24 is offline  
Old 10 May 2017, 00:54   #4
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by Leo24 View Post
Hi guys. Additionally, if you plan to use interrupt routines, make sure that the binary image is exact 256K or 512K and the last 7 words in "ROM" are "0019 001a 001b 001c 001d 001e 001f":
At offsets $3fff0 - $3ffff for a 256K ROM.
At offsets $7fff0 - $7ffff for a 512K ROM.

Otherwise exception handling will not work as expected.
Not sure how to define that in the linker script.
Yes, and you have to setup Autovectors address value, set SR, enable IRQs reg. and all

For the casual reader: the last 7 words in 68k mem address space was an indices in exception table, counting from $0.
Normallly vector number $19->location $64 was Autovector Interrupt Level 1, $1A Autovector Interrupt Level 2
and so on to Level 7 (NMI IRQ, $1F).
So explained the 'strange' value in ROM.
(I'm not sure about Spurious Interrupt Vector ($18), some kickstarts seems to set it, but i don't think Amiga can generate spurious interrupt..)

You can potentially change this values, but all you know about Amiga [interrupts management] does not work anymore

Bye,
ross

Last edited by ross; 10 May 2017 at 01:22. Reason: []
ross is offline  
Old 12 May 2017, 23:31   #5
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by Leo24 View Post
Not sure how to define that in the linker script.
Just add this:
Code:
        . = 0xfffff0;
        .vecs: {
                *(vectors)
        }
It will also make sure that the ROM is always 256K (or 512K big). In "rawbin1" mode vlink will fill the gap with zeros.

For "vectors" just take something like this:
Code:
        section vectors,data
        dc.w    $18,$19,$1a,$1b,$1c,$1d,$1e,$1f
Quote:
Originally Posted by paraj View Post
Code:
vasmm68k_mot_win32.exe -phxass -x -Fhunk -o init.o init.s
vasmm68k_mot_win32.exe -phxass -x -Fhunk -o boot.o boot.s
vlink.exe -Trom.ld -brawbin1 -o rom.bin init.o boot.o
When generating raw binary output, the object file format is irrelevant. So you can use anything you want. I prefer "vobj" in these cases, which is the vasm/vlink internal, native format.

Quote:
Note: Placing DATA/BSS in ROM is a bad idea so it'll need some work before running larger code samples
When you leave the DATA and BSS sections out of the script the linker will at least warn you about those occurences, which you want to fix.

A more sophisticated approach is to define memory regions. Put the data and BSS into RAM and the code and constants into ROM. Like this:
Code:
MEMORY {
        RAM: org=0, len=0x80000
        ROM: org=0xfc0000, len=0x3fff0
        VEC: org=0xfffff0, len=16
}

SECTIONS {
        .rom: {
                *(CODE)
        } >ROM
        .data: {
                *(DATA)
        } >RAM AT>ROM
        .vecs: {
                *(vectors)
        } >VEC
        .bss (NOLOAD): {
                *(BSS)
        } >RAM
}
References to the DATA section are relocated to RAM, but "AT>ROM" places the initialized data into a ROM location, where code could copy it into RAM on startup.


Quote:
Originally Posted by ross View Post
For the casual reader: the last 7 words in 68k mem address space was an indices in exception table, counting from $0.
Normallly vector number $19->location $64 was Autovector Interrupt Level 1, $1A Autovector Interrupt Level 2
and so on to Level 7 (NMI IRQ, $1F).
That's quite interesting. I know about these vectors in the Amiga ROM, but I never really understood how they are used. There is no code in the ROM which uses them, AFAIK. Anybody knows more?
phx is offline  
Old 12 May 2017, 23:47   #6
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by phx View Post
Just add this:
Code:
        . = 0xfffff0;
        .vecs: {
                *(vectors)
        }
Code:
        section vectors,data
        dc.w    $18,$19,$1a,$1b,$1c,$1d,$1e,$1f

etc. etc.
Ok, with this you fill even the 'spurious interrupt' index.
Quote:
That's quite interesting. I know about these vectors in the Amiga ROM, but I never really understood how they are used. There is no code in the ROM which uses them, AFAIK. Anybody knows more?
It's a 68k/68k10 hardware property. More info on an old Motorola Manual (paper) that i have somewhere... I went to memory...

Cheers,
ross
ross is offline  
Old 13 May 2017, 00:23   #7
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Interesting!

Spurious Interrupt.
During the interrupt acknowledge cycle, if no device responds by asserting DTACK or AVEC, VPA, BERR should be asserted to terminate the vector acquisition. The processor separates the processing of this error from bus error by forming a short format exception stack and fetching the spurious interrupt vector instead of the bus error vector. The processor then proceeds with the usual exception processing.

So in a really compromised machine (with no device that acknowledge interrupts) a spurious can be generated!
Maybe usefull for some DiagROM code
ross is offline  
Old 13 May 2017, 02:44   #8
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Ok, a compendium for the sequence of events during an interrupt (some info from Exec_Interrupts, some from Motorola Manual, some from my deduction).
Long post.

When a hardware device decides to cause an interrupt sends a signal to the interrupt control portions of the 4703 (Paula) custom chip.
The 4703 interrupt control logic notices this new signal and performs two primary operations.
First, it records that the interrupt has been requested by setting a flag bit in the INTREQ register.
Second, it examines the INTENA register to determine whether the corresponding interrupt and the interrupt master are enabled.
If both are enabled, the 4703 generates an interrupt request by placing the priority level of the request onto the three 68000 interrupt control input lines (IPL0, IPL1, IPL2).
These three signals correspond to seven interrupt priority levels in the 68000.
If the priority of the new interrupt is greater than the current processor priority the processor acknowledges the interrupt and initiates processing.
Interrupt level 7 is edge-triggered. On the other hand, the interrupt levels 1 to 6 are level sensitive.
But as soon as the status register (SR) is saved the processor updats its interrupt mask to the same level.
Value in SR disables all interrupts below or equal to I2/1/0.
Once the 68000 has decided to ACK an interrup request, it pushes PC and SR to stack, enter supervisor mode, inhibit tracing, updates the priority mask bits and also the address lines A3-A1 with the interrupt level.
Then assert AS to inform the external device that A3-A1 has the IRQ level and sets FC2/1/0 to 111 to run an IACK cycle for 8bit vector number acquisition.
The 68000 multiplies the 8bit vector by 4 to determine the pointer to locations containing the starting address of the service routine.
External logic can respond to interrupt acknowledge in one of the following ways: by requesting automatic vectoring or by placing a vector number on the data bus (nonautovector) or by indicating that no device is responding (spurious interrupt).
[If the hardware asserts VPA to terminate the IACK bus cycle, the 68000 directs itself automatically to the proper interrupt vector corrisponding to the current interrupt level.]
In nonautovector situation, the interrupting device uses external hardware to place a vector number on data lines D0-D7, and then performs a DTACK handshake to terminate the IACK bus cycle.
The user vector number allowed are $40 to $FF, but Motorola has not implemented a protection on the first entries so that user-interrupt vectors may overlap at the discretion of the system designer.
In Amiga seems that (clever!) designers used A3-A1 (with others Ax lines tied to 1) to address [FFFFF(16)]A3A2A1[1(2)] (so the odd address) in ROM and select in data line D7-D0 the vector number.
So Amiga is a nonautovector machine using autovector indices making possible all the 4703 IRQ subpriority.
Exec must now further decode the interrupt by examining the INTREQ and INTENA 4703 chip registers.
Once the active interrupt has been determined, Exec indexes into an ExecBase array to fetch the interrupt's handler entry point and handler data pointer addresses.
Exec now turns control over to the interrupt handler by calling it as if it were a subroutine.
This handler may deal with the interrupt directly or may propagate control further by invoking interrupt server chain processing.

Some hardware expert can confirm?

Cheers,
ross
ross is offline  
Old 13 May 2017, 12:19   #9
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,505
Yes, thats correct, Amiga uses non-autovector mode. ("In nonautovector situation" part)
Toni Wilen is offline  
Old 13 May 2017, 15:25   #10
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Thanks Toni.

So You can fill
$FFFFF0
with:
Code:
dc.w    $4118,$5219,$4F1A,$531B,$201C,$361D,$381E,$6B1F
          A     R     O     S           6     8     k
ross is offline  
Old 13 May 2017, 16:16   #11
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,505
Yeah, even bytes are unused
Toni Wilen is offline  
Old 13 May 2017, 16:37   #12
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
mmh, about all this ROM indices, there is something missing in AROS code:

AROS/arch/m68k-amiga/boot/romcheck.c

near line 152:
Code:
               p = (uint8_t*)rom + len - 16;
               for (i = 0; i < 7; i++) {
                       p[i * 2 + 1] = i + 0x18;
                       p[i * 2 + 0] = 0;
               }
need to be:
Code:
               for (i = 0; i <= 7; i++) {
No problem at all in real 68k Amiga with no L7 IRQ HW, but just in case..

Bye!
ross
ross is offline  
Old 13 May 2017, 18:10   #13
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by ross View Post
Ok, a compendium for the sequence of events during an interrupt (some info from Exec_Interrupts, some from Motorola Manual, some from my deduction).
First class information! Thanks, ross!

I always wondered why the Amiga didn't just use autovector-mode, as it doesn't use any interrupt vectors outside the autovector range (in contrast to the Atari ST, for example).
phx is offline  
Old 13 May 2017, 18:37   #14
Leo24
Registered User
 
Join Date: May 2017
Location: Sao Paulo
Posts: 17
I just read the chapters about "interrupt acknowledge cycles" in all M680x0 User´s Manuals and it seems that only the 68000, 68010, 68020 and 68030 set the interrupt level in A1-A3 and drive A0, A4-A31 address lines high. The 68040 and 68060 drive all address lines high.
I wonder how an 040 or 060 equipped Amiga can still work. It would always read the vector number $1f from $ffffffff. Maybe turbo cards make use of autovector mode. Does anyone know some details?
Leo24 is offline  
Old 13 May 2017, 20:52   #15
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by phx View Post
I always wondered why the Amiga didn't just use autovector-mode, as it doesn't use any interrupt vectors outside the autovector range (in contrast to the Atari ST, for example).
The Amiga fake-autovector can cause misconception but is smart: avoid all the E-cycle slowness of real autovector (and only memory cycle slowness).
ross is offline  
Old 13 May 2017, 21:13   #16
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,505
It is also very cheap, no extra hardware needed
Toni Wilen is offline  
Old 13 May 2017, 21:37   #17
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by Leo24 View Post
I just read the chapters about "interrupt acknowledge cycles" in all M680x0 User´s Manuals and it seems that only the 68000, 68010, 68020 and 68030 set the interrupt level in A1-A3 and drive A0, A4-A31 address lines high. The 68040 and 68060 drive all address lines high.
I wonder how an 040 or 060 equipped Amiga can still work.
You're right.
In AROS source even only 68000 and 68010 are marked for ROM 'indices' use.
But something interesting in 060 manual:
Transfer Cycle Modifier (TM2–TM0). These three-state outputs provide supplemental information for each transfer cycle type.
For interrupt acknowledge transfers, the TMx signals carry the interrupt level being acknowledged.
So a 1:1 map of A3-A1..
Quote:
It would always read the vector number $1f from $ffffffff.
I don't think so, require ROM mirroring, and with only a single indices...

Quote:
Maybe turbo cards make use of autovector mode. Does anyone know some details?
Waiting Toni for the response

Last edited by ross; 13 May 2017 at 21:51. Reason: better quoting...
ross is offline  
Old 13 May 2017, 22:21   #18
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,505
I haven't really examined what 68020+ do but I have always assumed it is 68000/010 only feature.

I just did quick test with ACA500plus and 68060, 68030 and 68020 A1200 accelerators + custom flashed KS 3.1 ROM image with last 16 bytes erased. It still worked fine. (Except in 68000 mode)
Toni Wilen is offline  
Old 14 May 2017, 20:28   #19
michaelz
Registered User
 
Join Date: Jan 2017
Location: Den Haag / Netherlands
Posts: 193
Is there someone who has a full working copy of this and willing to share (through github)? I find this quite interesting (especially the version with c in it).
michaelz is offline  
Old 14 May 2017, 21:00   #20
paraj
Registered User
 
paraj's Avatar
 
Join Date: Feb 2017
Location: Denmark
Posts: 1,099
Quote:
Originally Posted by michaelz View Post
Is there someone who has a full working copy of this and willing to share (through github)? I find this quite interesting (especially the version with c in it).
I can clean up my quick-and-dirty code and include the suggestions from the interesting discussion upthread if you want. What compiler/assembler/etc. are you using?
paraj is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 11:16.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.50106 seconds with 12 queries